Ejemplo n.º 1
0
        public void AddAllDynamicRequestEvents()
        {
            List <Stop> excludedStops = new List <Stop>();

            excludedStops.Add(Context.Depot);
            for (int hour = (int)TimeSpan.FromSeconds(Params.SimulationTimeWindow[0]).TotalHours; hour < (int)TimeSpan.FromSeconds(Params.SimulationTimeWindow[1]).TotalHours; hour++)
            {
                var hourInSeconds = TimeSpan.FromHours(hour).TotalSeconds;
                for (int i = 0; i < Params.NumberDynamicRequestsPerHour; i++)
                {
                    var maxHourTime          = (int)hourInSeconds + (60 * 60) - 1;
                    var requestTime          = RandomNumberGenerator.Random.Next((int)hourInSeconds, (int)maxHourTime);
                    var pickupTimeWindow     = new int[] { requestTime, maxHourTime };
                    var customer             = CustomerFactory.Instance().CreateRandomCustomer(Context.Stops, excludedStops, requestTime, pickupTimeWindow, true, Params.VehicleSpeed); //Generates a random dynamic customer
                    var customerRequestEvent = EventGenerator.Instance().GenerateCustomerRequestEvent(requestTime, customer);                                                           //Generates a pickup and delivery customer request (dynamic)
                    AddEvent(customerRequestEvent);
                }
            }
        }
Ejemplo n.º 2
0
        public override void Handle(Event evt)
        {
            if (evt.Category == 0 && evt is VehicleStopEvent arriveEvent)
            {
                Log(evt);
                evt.AlreadyHandled = true;
                var arrivalTime = evt.Time;

                //Handle arrival evt
                if (arriveEvent.Vehicle.TripIterator.Current != null && arriveEvent.Vehicle.CurrentStop == arriveEvent.Stop)
                {
                    arriveEvent.Vehicle.IsIdle = true;
                    if (arriveEvent.Vehicle.TripIterator.Current.StopsIterator.CurrentIndex == 0) //check if the trip has started
                    {
                        arriveEvent.Vehicle.TripIterator.Current.Start(arrivalTime);
                        _consoleLogger.Log(arriveEvent.Vehicle.ToString() + arriveEvent.Vehicle.TripIterator.Current + " STARTED at " +
                                           TimeSpan.FromSeconds(arrivalTime) + ".");
                    }

                    _consoleLogger.Log(arriveEvent.Vehicle.ToString() + "ARRIVED at " + arriveEvent.Stop + " at " + TimeSpan.FromSeconds(arrivalTime) + ".");
                    arriveEvent.Vehicle.VisitedStops.Add(arriveEvent.Stop);                                                        //adds the current stop to the visited stops
                    arriveEvent.Vehicle.StopsTimeWindows.Add(new long[] { arrivalTime, arrivalTime });                             //adds the current time window

                    if (arriveEvent.Vehicle.TripIterator.Current.StopsIterator.IsDone && arriveEvent.Vehicle.Customers.Count == 0) //this means that the trip is complete
                    {
                        arriveEvent.Vehicle.TripIterator.Current.Finish(arrivalTime);                                              //Finishes the trip
                        _consoleLogger.Log(arriveEvent.Vehicle.ToString() + arriveEvent.Vehicle.TripIterator.Current + " FINISHED at " +
                                           TimeSpan.FromSeconds(arrivalTime) + ", Duration:" +
                                           Math.Round(TimeSpan.FromSeconds(arriveEvent.Vehicle.TripIterator.Current.RouteDuration)
                                                      .TotalMinutes) + " minutes.");

                        arriveEvent.Vehicle.TripIterator.MoveNext();
                        if (arriveEvent.Vehicle.TripIterator.Current == null)
                        {
                            arriveEvent.Vehicle.TripIterator.Reset();
                            arriveEvent.Vehicle.TripIterator.MoveNext();
                        }
                    }
                }
                //end of arrival event handle

                //INSERTION (APPEND) OF CUSTOMER ENTER VEHICLE AND LEAVE VEHICLE EVENTS AND GENERATION OF THE DEPART EVENT FROM THE CURRENT STOP---------------------------------------
                var customerLeaveVehicleEvents = EventGenerator.Instance().GenerateCustomerLeaveVehicleEvents(arriveEvent.Vehicle, arriveEvent.Stop, arrivalTime); //Generates customer leave vehicle event
                var lastInsertedLeaveTime      = 0;
                var lastInsertedEnterTime      = 0;
                lastInsertedLeaveTime = customerLeaveVehicleEvents.Count > 0 ? customerLeaveVehicleEvents[customerLeaveVehicleEvents.Count - 1].Time : arrivalTime;

                List <Event> customersEnterVehicleEvents = null;
                if (arriveEvent.Vehicle.TripIterator.Current != null && arriveEvent.Vehicle.TripIterator.Current.HasStarted)
                {
                    int expectedDemand = 0;
                    try
                    {
                        expectedDemand = !arriveEvent.Vehicle.FlexibleRouting ? Simulation.Context.DemandsDataObject.GetDemand(arriveEvent.Stop.Id, arriveEvent.Vehicle.TripIterator.Current.Route.Id, TimeSpan.FromSeconds(arriveEvent.Time).Hours) : 0;
                    }
                    catch (Exception)
                    {
                        expectedDemand = 0;
                    }

                    customersEnterVehicleEvents = EventGenerator.Instance().GenerateCustomersEnterVehicleEvents(arriveEvent.Vehicle, arriveEvent.Stop, lastInsertedLeaveTime, expectedDemand);
                    if (customersEnterVehicleEvents.Count > 0)
                    {
                        lastInsertedEnterTime = customersEnterVehicleEvents[customersEnterVehicleEvents.Count - 1].Time;
                    }
                }

                Simulation.AddEvent(customersEnterVehicleEvents);
                Simulation.AddEvent(customerLeaveVehicleEvents);


                var maxInsertedTime = Math.Max(lastInsertedEnterTime, lastInsertedLeaveTime);;  //gets the highest value of the last insertion in order to maintain precedence constraints for the depart evt, meaning that the stop depart only happens after every customer has already entered and left the vehicle on that stop location

                //INSERTION OF CUSTOMER ENTER VEHICLE FOR THE FLEXIBLE REQUESTS!


                if (arriveEvent.Vehicle.TripIterator.Current != null && arriveEvent.Vehicle.FlexibleRouting)
                {
                    var currentVehicleTrip            = arriveEvent.Vehicle.TripIterator.Current;
                    var customersToEnterAtCurrentStop = currentVehicleTrip.ExpectedCustomers.FindAll(c => c.PickupDelivery[0] == arriveEvent.Stop && !c.IsInVehicle); //gets all the customers that have the current stop as the pickup stop

                    if (customersToEnterAtCurrentStop.Count > 0)                                                                                                      //check if there is customers to enter at current stop
                    {
                        foreach (var customer in customersToEnterAtCurrentStop)                                                                                       //iterates over every customer that has the actual stop as the pickup stop, in order to make them enter the vehicle
                        {
                            if (currentVehicleTrip.ScheduledTimeWindows[currentVehicleTrip.StopsIterator.CurrentIndex][1] >= customer.DesiredTimeWindow[0])           //if current stop expected depart time is greater or equal than the customer arrival time adds the customer
                            {
                                var enterTime = maxInsertedTime > customer.DesiredTimeWindow[0] ? maxInsertedTime + 1 : customer.DesiredTimeWindow[0] + 1;            //case maxinserted time is greather than desired time window the maxinserted time +1 will be the new enterTime of the customer, othersie it is the customer's desiredtimewindow
                                var customerEnterVehicleEvt =
                                    EventGenerator.Instance().GenerateCustomerEnterVehicleEvent(arriveEvent.Vehicle, (int)enterTime, customer);                       //generates the enter event
                                Simulation.AddEvent(customerEnterVehicleEvt);                                                                                         //adds to the event list
                                maxInsertedTime = (int)enterTime;                                                                                                     //updates the maxInsertedTime
                            }
                        }
                    }
                }


                // END OF INSERTION OF CUSTOMER ENTER VEHICLE FOR THE FLEXIBLE REQUESTS

                //VEHICLE DEPART STOP EVENT

                if (arriveEvent.Vehicle.TripIterator.Current?.ScheduledTimeWindows != null)
                {
                    var currentStopIndex = arriveEvent.Vehicle.TripIterator.Current.StopsIterator.CurrentIndex;
                    var newDepartTime    = arriveEvent.Vehicle.TripIterator.Current.ScheduledTimeWindows[currentStopIndex][1]; //gets the expected latest depart time
                    maxInsertedTime = newDepartTime != 0 ? (int)Math.Max(maxInsertedTime, newDepartTime) : maxInsertedTime;    //if new depart time != 0,new maxInsertedTime will be the max between maxInsertedtime and the newDepartTime, else the value stays the same.
                                                                                                                               //If maxInsertedTime is still max value between the previous maxInsertedTime and newDepartTime, this means that there has been a delay in the flexible trip (compared to the model generated by the solver)
                }

                var nextDepartEvent = EventGenerator.Instance().GenerateVehicleDepartEvent(arriveEvent.Vehicle, maxInsertedTime + 2);
                Simulation.AddEvent(nextDepartEvent);
            }
            else
            {
                Successor?.Handle(evt);
            }
        }
Ejemplo n.º 3
0
        public override void Handle(Event evt)
        {
            if (evt.Category == 1 && evt is VehicleStopEvent departEvent)
            {
                Log(evt);
                evt.AlreadyHandled = true;
                var departTime = departEvent.Time; //the time the vehicle departed on the previous depart event
                //DEPART EVENT HANDLE
                if (departEvent.Vehicle.TripIterator.Current != null && departEvent.Vehicle.CurrentStop == departEvent.Stop)
                {
                    _consoleLogger.Log(departEvent.Vehicle.ToString() + "DEPARTED from " + departEvent.Stop + " at " + TimeSpan.FromSeconds(departTime) + ".");
                    var tuple            = Tuple.Create(departEvent.Vehicle.CurrentStop, departEvent.Vehicle.NextStop);
                    var currentStopIndex = departEvent.Vehicle.TripIterator.Current.StopsIterator.CurrentIndex;
                    departEvent.Vehicle.StopsTimeWindows[currentStopIndex][1] = departTime;
                    Simulation.Context.ArcDistanceDictionary.TryGetValue(tuple, out var distance);

                    //vehicle start transversing to next stop
                    if (departEvent.Vehicle.TripIterator.Current?.StopsIterator != null && !departEvent.Vehicle.TripIterator.Current.StopsIterator.IsDone)
                    {
                        departEvent.Vehicle.IsIdle = false;
                        var t = TimeSpan.FromSeconds(departTime);
                        departEvent.Vehicle.TripIterator.Current.TotalDistanceTraveled += distance;
                        departEvent.Vehicle.TotalDistanceTraveled += distance;
                        _consoleLogger.Log(departEvent.Vehicle.ToString() + "started traveling to " +
                                           departEvent.Vehicle.NextStop + " (Distance: " + Math.Round(distance) + " meters) at " + t + ".");
                    }
                    //end of vehicle transverse to next stop
                }
                //END OF DEPART EVENT HANDLE

                //INSERTION (APPEND) OF VEHICLE NEXT STOP ARRIVE EVENT
                if (departEvent.Vehicle.TripIterator?.Current != null)
                {
                    var currentStop = departEvent.Vehicle.CurrentStop;
                    if (departEvent.Vehicle.NextStop != null)
                    {
                        var nextStop  = departEvent.Vehicle.NextStop;
                        var stopTuple = Tuple.Create(currentStop, nextStop);
                        Simulation.Context.ArcDistanceDictionary.TryGetValue(stopTuple, out var distance);

                        if (distance == 0)
                        {
                            distance = Calculator.CalculateHaversineDistance(currentStop.Latitude,
                                                                             currentStop.Longitude, nextStop.Latitude, nextStop.Longitude);
                        }

                        var travelTime = Calculator.DistanceToTravelTime(departEvent.Vehicle.Speed,
                                                                         distance);                                                       //Gets the time it takes to travel from the currentStop to the nextStop
                        var nextArrivalTime = Convert.ToInt32(departTime + travelTime);                                                   //computes the arrival time for the next arrive event
                        departEvent.Vehicle.TripIterator.Current.StopsIterator
                        .Next();                                                                                                          //Moves the iterator to the next stop
                        var nextArriveEvent = EventGenerator.Instance().GenerateVehicleArriveEvent(departEvent.Vehicle, nextArrivalTime); //generates the arrive event
                        Simulation.AddEvent(nextArriveEvent);
                        //DEBUG!
                        if (departEvent.Vehicle.FlexibleRouting)
                        {
                            var scheduledArrivalTime =
                                departEvent.Vehicle.TripIterator.Current.ScheduledTimeWindows[
                                    departEvent.Vehicle.TripIterator.Current.StopsIterator.CurrentIndex][0];

                            //_consoleLogger.Log("Event arrival time:" + nextArrivalTime +", Scheduled arrival time:" + scheduledArrivalTime);
                        }
                    }

                    //END DEBUG
                }
            }
            //END OF INSERTION OF VEHICLE NEXT STOP ARRIVE EVENT--------------------------------------
            else
            {
                Successor?.Handle(evt);
            }
        }
 protected AbstractSimulation()
 {
     Events         = new List <Event>();
     EventGenerator = EventGenerator.Instance();
     Id             = Interlocked.Increment(ref nextId);
 }