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); } } }
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); } }
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); }