Exemple #1
0
        public void StartSimulation()
        {
            try
            {
                for (int RoundCount = 1; RoundCount <= 20; RoundCount++)
                {
                    TotalDistanceOfUserWalk      = 0;
                    TotalDistanceOfBikeRides     = 0;;
                    AvailableBikesInTruck        = 0;
                    TotoalNumberOfbikesForPickup = 0;
                    EventID    = 1;
                    GlobalTime = 0;

                    ReadData(RoundCount);

                    List <FutureEvent> FutureEventList = new List <FutureEvent>();
                    int MissRequestCount = 0;
                    int HitRequestCount  = 0;
                    int RebalancingCount = 0;
                    // For each cell in the list creat events and add new events to the FutureEventList
                    //Read stations data from XML file
                    System.Data.DataTable dtStationCells = new System.Data.DataTable();
                    dtStationCells.ReadXmlSchema(StationLocating.strRootResaultPath + "stationsSchema.xml");
                    dtStationCells.ReadXml(StationLocating.strRootResaultPath + "stations.xml");

                    double total1 = 0;

                    foreach (System.Data.DataRow dr in dtStationCells.Rows)
                    {
                        double neareststationDistance;
                        int    neareststationindex = FindNearestStation(Convert.ToDouble(dr["Latitude"]), Convert.ToDouble(dr["Longitude"]), out neareststationDistance);
                        StationList[neareststationindex].Weight      += Convert.ToDouble(dr["Weight"]) * neareststationDistance;
                        StationList[neareststationindex].totalWeight += Convert.ToDouble(dr["Weight"]);
                        StationList[neareststationindex].RequestCount++;
                    }

                    foreach (System.Data.DataRow dr in dtStationCells.Rows)
                    {
                        double neareststationDistance;
                        int    neareststationindex = FindNearestStation(Convert.ToDouble(dr["Latitude"]), Convert.ToDouble(dr["Longitude"]), out neareststationDistance);
                        StationList[neareststationindex].Weight      += Convert.ToDouble(dr["Weight"]) * neareststationDistance;
                        StationList[neareststationindex].totalWeight += Convert.ToDouble(dr["Weight"]);
                        StationList[neareststationindex].RequestCount++;
                    }

                    foreach (var item in StationList)
                    {
                        item.Weight = item.Weight / item.totalWeight;
                        Console.WriteLine(string.Format("Station Index : {0}  Weight : {1}  Request : {2}", item.Index, item.Weight, item.RequestCount));
                        item.RequestCount = 0;
                    }

                    Console.WriteLine("--------------------------------------------------*");

                    PrintStationStatus();

                    foreach (System.Data.DataRow dr in dtStationCells.Rows)
                    {
                        Troschuetz.Random.Distributions.Discrete.PoissonDistribution rnd = new Troschuetz.Random.Distributions.Discrete.PoissonDistribution();
                        rnd.Lambda = 100 - Convert.ToDouble(dr["Weight"]);
                        int t = 0;
                        while (t < 1440) // OneDay = 1440 minute
                        {
                            t += rnd.Next() * 5;
                            FutureEventList.Add(new FutureEvent(EventID++, t, EventType.CustomerRequest, Convert.ToDouble(dr["Latitude"]), Convert.ToDouble(dr["Longitude"])));
                        }
                    }



                    //for (int GlobalTime = 0; GlobalTime < 1440; GlobalTime++)
                    //{
                    //    foreach (var item in FutureEventList.Where(e => e.StartTime == GlobalTime).OrderBy(e => e.EventId).ToList())
                    //    {
                    //        Console.WriteLine(string.Format("ID: {0} Start: {1} Lat:{2} Long:{3}", item.EventId, item.StartTime, item.Latitud, item.Longitud));
                    //    }
                    //}


                    for (int GlobalTime = 0; GlobalTime < 1440; GlobalTime++)
                    {
                        List <FutureEvent> events = FutureEventList.Where(e => e.StartTime == GlobalTime).OrderBy(e => e.EventId).ToList();
                        //List<FutureEvent> events =  FutureEventList.OrderBy(e => new { e.StartTime, e.EventId }).ToList();

                        foreach (FutureEvent fe in events)
                        {
                            Random rndNextStation = new Random();

                            #region CustomerRequest Event

                            if (fe.EventType == EventType.CustomerRequest)
                            {
                                double NearestStationDistance = 0;// (km)
                                int    NearestStationIndex    = FindNearestStation(fe.Latitud, fe.Longitud, out NearestStationDistance);

                                if (NearestStationIndex == -1)
                                {
                                    MissRequestCount++;
                                }
                                else
                                {
                                    FutureEvent ne = new FutureEvent();
                                    ne.StationIndex = NearestStationIndex;
                                    ne.StartTime    = fe.StartTime + Convert.ToInt32(Math.Round((NearestStationDistance / WalkSpeed) * 60, 0)); // t = s / v -> time = distance  / speed , Average speed of walking for age of 20-50 is 3.6 km/h
                                    ne.EventType    = EventType.BikeRentStart;
                                    FutureEventList.Add(ne);
                                }
                            }

                            #endregion

                            #region BikeRentStart Event

                            else if (fe.EventType == EventType.BikeRentStart)
                            {
                                // If there is no Available Bike then Add Miss Count And go to next event
                                if (StationList[fe.StationIndex].AvailebleBikes <= 0)
                                {
                                    MissRequestCount++;
                                    PrintStationStatus();
                                    continue;
                                }

                                HitRequestCount++;

                                StationList[fe.StationIndex].AvailebleBikes -= 1;
                                StationList[fe.StationIndex].RequestCount++;
                                Console.WriteLine("1 Bike Pickedup from station " + fe.StationIndex);


                                //Find Next Station based on Movement Probility Matrix
                                double NextStationProbibility = rndNextStation.Next(0, 100) / 100.0;
                                int    NextStationIndex       = -1;
                                double tempTotalProbility     = 0;
                                for (int j = 0; j < MovementProbilityMatrix.Width; j++)
                                {
                                    //x >= 1 && x <= 100
                                    if (NextStationProbibility >= tempTotalProbility && NextStationProbibility < tempTotalProbility + MovementProbilityMatrix[fe.StationIndex, j])
                                    {
                                        NextStationIndex = j;
                                        break;
                                    }
                                    else
                                    {
                                        tempTotalProbility += MovementProbilityMatrix[fe.StationIndex, j];
                                    }
                                }

                                MovementCountMatrix[fe.StationIndex, NextStationIndex] += 1;
                                FutureEvent ne = new FutureEvent();
                                ne.EventType = EventType.BikeRentFinish;

                                ne.StationIndex = NextStationIndex;
                                double DistanceToNextStation = StationList[fe.StationIndex].GetDistanceFromPosition(StationList[NextStationIndex].Latitude, StationList[NextStationIndex].Longitude);
                                TotalDistanceOfBikeRides += DistanceToNextStation;
                                ne.StartTime              = fe.StartTime + Convert.ToInt32(Math.Round((DistanceToNextStation / BikeSpeed) * 60, 0)); // t = s / v -> time = distance / speed , Average speed of bikes is 15 km/h

                                FutureEventList.Add(ne);

                                if (StationList[fe.StationIndex].AvailebleBikes <= 0)
                                {
                                    FutureEvent re = new FutureEvent();
                                    re.EventType    = EventType.Rebalancing;
                                    re.StationIndex = fe.StationIndex;
                                    re.StartTime    = fe.StartTime + 1;
                                    FutureEventList.Add(re);
                                }
                            }

                            #endregion

                            #region BikeRentFinish Event

                            else if (fe.EventType == EventType.BikeRentFinish)
                            {
                                StationList[fe.StationIndex].AvailebleBikes += 1;
                                Console.WriteLine("1 Bike withdraw in station " + fe.StationIndex);

                                if (StationList[fe.StationIndex].AvailebleBikes >= StationList[fe.StationIndex].Capasity)
                                {
                                    FutureEvent re = new FutureEvent();
                                    re.EventType    = EventType.Rebalancing;
                                    re.StationIndex = fe.StationIndex;
                                    re.StartTime    = fe.StartTime + 1;
                                    FutureEventList.Add(re);
                                }
                            }

                            #endregion

                            #region Rebalancing Event

                            else if (fe.EventType == EventType.Rebalancing)
                            {
                                //?? Reblancing To which stations should be done? one station or multiple station ?
                                //e.StartTime = DateTime.Now;  // #### distance and duration to next station Should be determined in here
                                //e.Distance = 0;  // #### distance and duration to next station Should be determined in here

                                RebalancingCount++;

                                foreach (var item in StationList) //Pickup Extra Bikes from each station
                                {
                                    if (item.AvailebleBikes > item.NumberOfBikes)
                                    {
                                        int NumberOfbikesForPickup = item.AvailebleBikes - item.NumberOfBikes;
                                        Console.WriteLine(NumberOfbikesForPickup.ToString() + " Bike Pickedup from station " + item.Index.ToString() + " for rebalancing" + " AvailebleBikes:" + item.AvailebleBikes + " NumberOfBikes: " + item.NumberOfBikes);
                                        TotoalNumberOfbikesForPickup += NumberOfbikesForPickup;
                                        AvailableBikesInTruck        += NumberOfbikesForPickup;
                                        item.AvailebleBikes           = item.NumberOfBikes;
                                    }
                                }

                                foreach (var item in StationList.OrderByDescending(s => s.NumberOfBikes - s.AvailebleBikes)) // withdraw bilke in each station which is needed
                                {
                                    if (AvailableBikesInTruck > 0)
                                    {
                                        if (item.AvailebleBikes < item.NumberOfBikes)
                                        {
                                            if (AvailableBikesInTruck >= item.NumberOfBikes - item.AvailebleBikes)
                                            {
                                                AvailableBikesInTruck -= item.NumberOfBikes - item.AvailebleBikes;
                                                Console.WriteLine((item.NumberOfBikes - item.AvailebleBikes).ToString() + " Bike withdraw in station " + item.Index.ToString() + " for rebalancing" + " AvailebleBikes:" + item.AvailebleBikes + " NumberOfBikes: " + item.NumberOfBikes);
                                                item.AvailebleBikes = item.NumberOfBikes;
                                            }
                                            else
                                            {
                                                Console.WriteLine(AvailableBikesInTruck.ToString() + " Bike withdraw in station " + item.Index.ToString() + " for rebalancing" + " AvailebleBikes:" + item.AvailebleBikes + " NumberOfBikes: " + item.NumberOfBikes);

                                                item.AvailebleBikes    = AvailableBikesInTruck;
                                                AvailableBikesInTruck -= AvailableBikesInTruck;
                                            }
                                        }
                                    }
                                }
                            }

                            #endregion
                        }
                    }

                    foreach (var item in StationList)
                    {
                        Console.WriteLine(string.Format("Station Index : {0}  Weight : {1}  Request : {2}", item.Index, item.Weight, item.RequestCount));
                    }

                    #region Export Resault

                    xlResaultDataSheet.Cells[1, 10] = "TotalDistanceOfUserWalk";
                    xlResaultDataSheet.Cells[1, 11] = "TotalDistanceOfBikeRides";
                    xlResaultDataSheet.Cells[1, 12] = "MissRequestCount";
                    xlResaultDataSheet.Cells[1, 13] = "HitRequestCount";
                    xlResaultDataSheet.Cells[1, 14] = "NumberOfBikesMoved";
                    xlResaultDataSheet.Cells[1, 15] = "RebalancingCount";

                    xlResaultDataSheet.Cells[RoundCount + 1, 10] = TotalDistanceOfUserWalk;
                    xlResaultDataSheet.Cells[RoundCount + 1, 11] = TotalDistanceOfBikeRides;
                    xlResaultDataSheet.Cells[RoundCount + 1, 12] = MissRequestCount;
                    xlResaultDataSheet.Cells[RoundCount + 1, 13] = HitRequestCount;
                    xlResaultDataSheet.Cells[RoundCount + 1, 14] = TotoalNumberOfbikesForPickup;
                    xlResaultDataSheet.Cells[RoundCount + 1, 15] = RebalancingCount;

                    xlStationsDataSheet.Cells[10, 1] = "SimulationRequestCount";

                    foreach (var item in StationList)
                    {
                        xlStationsDataSheet.Cells[10, item.Index + 2] = item.RequestCount;
                    }

                    Console.WriteLine("MovementProbilityMatrix : ------------------------------- " + RoundCount.ToString());
                    MovementProbilityMatrix.PrintMatrix();
                    Console.WriteLine("MovementCountMatrix : ------------------------------- " + RoundCount.ToString());
                    MovementCountMatrix.PrintMatrix();

                    MovementCountMatrix.FillMatrixWithEqalTotal();
                    #endregion
                }

                xlWorkBook.SaveAs(StationLocating.strRootResaultPath + "StationsData3.xls");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }