コード例 #1
0
        public void InitializeFlexibleSimulation(bool allowDropNodes)
        {
            var dataModel = DataModelFactory.Instance().CreateInitialSimulationDataModel(allowDropNodes, this);

            if (dataModel != null)
            {
                RoutingSolver routingSolver = new RoutingSolver(dataModel, false);
                var           printableList = dataModel.GetSettingsPrintableList();
                foreach (var tobePrinted in printableList)
                {
                    Console.WriteLine(tobePrinted);
                }
                //dataModel.PrintDataStructures();
                Assignment timeWindowSolution            = null;
                RoutingSearchParameters searchParameters =
                    operations_research_constraint_solver.DefaultRoutingSearchParameters();
                searchParameters.FirstSolutionStrategy =
                    FirstSolutionStrategy.Types.Value.ParallelCheapestInsertion;
                searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.TabuSearch;
                searchParameters.TimeLimit = new Duration {
                    Seconds = 20
                };
                timeWindowSolution = routingSolver.TryGetSolution(searchParameters);


                RoutingSolutionObject routingSolutionObject = null;
                if (timeWindowSolution != null)
                {
                    routingSolver.PrintSolution(timeWindowSolution);

                    routingSolutionObject = routingSolver.GetSolutionObject(timeWindowSolution);
                    for (int j = 0; j < routingSolutionObject.VehicleNumber; j++) //Initializes the flexible trips
                    {
                        var solutionVehicle          = routingSolutionObject.IndexToVehicle(j);
                        var solutionVehicleStops     = routingSolutionObject.GetVehicleStops(solutionVehicle);
                        var solutionTimeWindows      = routingSolutionObject.GetVehicleTimeWindows(solutionVehicle);
                        var solutionVehicleCustomers = routingSolutionObject.GetVehicleCustomers(solutionVehicle);
                        InitializeVehicleFlexibleRoute(solutionVehicle, solutionVehicleStops, solutionVehicleCustomers, solutionTimeWindows);
                    }
                }
            }
            Simulate();
        }
コード例 #2
0
        public void Test(RoutingDataModel dataModel, bool dropNodes) //tests the algorithm using different maxUpperBound values until it finds the earliest feasible maxupperbound value, then saves its metrics
        {
            Console.WriteLine(this.ToString() + " testing algorithm: " + Name + " (Search time: " + SearchTimeLimitInSeconds + " seconds)");
            DataModel = dataModel;
            Solver    = new RoutingSolver(dataModel, dropNodes);
            var watch    = Stopwatch.StartNew();
            var solution = GetSolution();

            _hasBeenTested = true;
            watch.Stop();
            var elapsedSeconds = watch.ElapsedMilliseconds * 0.001;

            SolutionIsFeasible = solution != null;
            if (SolutionIsFeasible) //solution != null (means earliest feasible solution was found)
            {
                //Saves the important metrics for the earliest feasible solution
                MaxUpperBoundInMinutes   = (int)TimeSpan.FromSeconds(Solver.MaximumDeliveryDelayTime).TotalMinutes;
                ComputationTimeInSeconds = elapsedSeconds;
                Solution = solution;
                Solver.PrintSolution(solution);
            }
        }
コード例 #3
0
        public override void Handle(Event evt)
        {  //INSERTION OF EVENTS FOR THE NEWLY GENERATED ROUTE ( after a dynamic request has been accepted)
            if (evt.Category == 4 && evt is CustomerRequestEvent customerRequestEvent)
            {
                Log(evt);
                evt.AlreadyHandled = true;
                _consoleLogger.Log("New Customer (dynamic) request:" + customerRequestEvent.Customer + " - " + customerRequestEvent.Customer.PickupDelivery[0] + " -> " + customerRequestEvent.Customer.PickupDelivery[1] + ", TimeWindows: {" + customerRequestEvent.Customer.DesiredTimeWindow[0] + "," + customerRequestEvent.Customer.DesiredTimeWindow[1] + "} at " + TimeSpan.FromSeconds(evt.Time).ToString());
                //Check if request can be served, if so the
                Simulation.Stats.TotalDynamicRequests++;
                var newCustomer = customerRequestEvent.Customer;
                RoutingSolutionObject solutionObject = null;
                if (Simulation.Context.VehicleFleet.FindAll(v => v.FlexibleRouting).Count > 0 && newCustomer != null)
                {
                    var dataModel = DataModelFactory.Instance().CreateCurrentSimulationDataModel(Simulation, newCustomer, evt.Time);
                    var solver    = new RoutingSolver(dataModel, false);
                    RoutingSearchParameters searchParameters =
                        operations_research_constraint_solver.DefaultRoutingSearchParameters();
                    searchParameters.FirstSolutionStrategy =
                        FirstSolutionStrategy.Types.Value.ParallelCheapestInsertion;
                    searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.TabuSearch;
                    searchParameters.TimeLimit = new Duration {
                        Seconds = 5
                    };                                                        //change
                    _consoleLogger.Log("Generating new Routing Solution...");
                    var solution = solver.TryGetSolution(searchParameters);
                    if (solution != null)
                    {
                        //solver.PrintSolution(solution);
                        Simulation.Stats.TotalServedDynamicRequests++;
                        _consoleLogger.Log(newCustomer.ToString() + " request was inserted into a vehicle route at " + TimeSpan.FromSeconds(customerRequestEvent.Time).ToString());

                        solutionObject = solver.GetSolutionObject(solution);
                    }
                    else
                    {
                        _consoleLogger.Log(newCustomer.ToString() + " will not be able to be served by any of the available vehicles at " + TimeSpan.FromSeconds(customerRequestEvent.Time).ToString());
                    }
                }

                if (!Simulation.Context.DynamicCustomers.Contains(newCustomer))
                {
                    Simulation.Context.DynamicCustomers.Add(newCustomer);
                }

                if (solutionObject != null)
                {
                    //solutionObject.MetricsContainer.PrintMetrics();
                    var vehicleFlexibleRouting = Simulation.Context.VehicleFleet.FindAll(v => v.FlexibleRouting);
                    foreach (var vehicle in vehicleFlexibleRouting)
                    {
                        var solutionRoute       = solutionObject.GetVehicleStops(vehicle);
                        var solutionTimeWindows = solutionObject.GetVehicleTimeWindows(vehicle);
                        var solutionCustomers   = solutionObject.GetVehicleCustomers(vehicle);
                        if (solutionRoute.Count >= 2 && solutionRoute[0] != solutionRoute[1])//check if current vehicle route is valid
                        {
                            if (vehicle.VisitedStops.Count > 1 && vehicle.CurrentStop == Simulation.Context.Depot)
                            {
                                _consoleLogger.Log("Vehicle " + vehicle.Id + " already performed a route and is currently idle at depot.");//debug
                            }
                            if (vehicle.TripIterator?.Current != null)
                            {
                                var           currentStopIndex   = vehicle.TripIterator.Current.StopsIterator.CurrentIndex;
                                var           customers          = solutionObject.GetVehicleCustomers(vehicle); //contains all customers (already inside and not yet in vehicle)
                                List <Stop>   visitedStops       = new List <Stop>(vehicle.VisitedStops);
                                List <long[]> visitedTimeWindows = new List <long[]>(vehicle.StopsTimeWindows);


                                if (currentStopIndex < vehicle.VisitedStops.Count)
                                {
                                    visitedStops.RemoveAt(currentStopIndex);       //remove current stop from the visitedStops list
                                    visitedTimeWindows.RemoveAt(currentStopIndex); //remove current timeWindow from the visitedTimeWindows list
                                }

                                //inserts the already visited stops at the beginning of the solutionRoute list
                                for (int e = visitedStops.Count - 1; e >= 0; e--)
                                {
                                    solutionRoute.Insert(0, visitedStops[e]);
                                    solutionTimeWindows.Insert(0, visitedTimeWindows[e]);
                                }

                                vehicle.TripIterator.Current.AssignStops(solutionRoute, solutionTimeWindows, currentStopIndex);
                                vehicle.TripIterator.Current.ExpectedCustomers = customers.FindAll(c => !c.IsInVehicle);                                                                                                                                                                                  //the expected customers for the current vehicle are the ones that are not in that vehicle

                                var vehicleEvents = Simulation.Events.FindAll(e => (e is VehicleStopEvent vse && vse.Vehicle == vehicle && e.Time >= evt.Time) || (e is CustomerVehicleEvent cve && cve.Vehicle == vehicle && e.Time >= evt.Time)).OrderBy(e => e.Time).ThenBy(e => e.Category).ToList(); //gets all next vehicle depart or arrive events
                                if (vehicleEvents.Count > 0)
                                {
                                    foreach (var vEvent in vehicleEvents)
                                    {
                                        if (vEvent is VehicleStopEvent vehicleStopArriveEvent && vEvent.Category == 0
                                            ) //vehicle arrive stop event
                                        {
                                            //_consoleLogger.Log(vehicleStopArriveEvent.GetTraceMessage());
                                        }

                                        if (vEvent is VehicleStopEvent vehicleStopDepartEvent && vEvent.Category == 1
                                            ) //vehicle depart stop event
                                        {
                                            var departTime = vEvent.Time;

                                            if (vehicleStopDepartEvent.Stop == vehicle.CurrentStop)
                                            {
                                                departTime =
                                                    (int)vehicle.TripIterator.Current.ScheduledTimeWindows[
                                                        vehicle.TripIterator.Current.StopsIterator.CurrentIndex][1] +
                                                    2; //recalculates new event depart time;


                                                vEvent.Time = departTime;
                                            }

                                            var allEnterLeaveEventsForCurrentVehicle = Simulation.Events
                                                                                       .FindAll(e =>
                                                                                                e.Time >= evt.Time &&
                                                                                                (e is CustomerVehicleEvent cve && cve.Vehicle == vehicle))
                                                                                       .OrderBy(e => e.Time).ThenBy(e => e.Category).ToList();

                                            foreach (var enterOrLeaveEvt in allEnterLeaveEventsForCurrentVehicle)
                                            {
                                                if (enterOrLeaveEvt.Time > departTime
                                                    ) //if the event time is greater than the depart time removes those events, otherwise maintain the enter and leave events for current stop
                                                {
                                                    Simulation.Events.Remove(enterOrLeaveEvt);
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    //if vehicle events is 0 it means the vehicle has no more generated events for it, need to generate a new depart event for the vehicle
                                    vehicle.TripIterator.Current.IsDone = false; //current trip is no longer completed
                                    var currentDepartureTime = (int)solutionTimeWindows[currentStopIndex][1];
                                    if (currentDepartureTime == evt.Time)        //if departure time is the same time as the event being handled adds 1 to its time
                                    {
                                        currentDepartureTime++;
                                    }
                                    var departEvt = Simulation.EventGenerator.GenerateVehicleDepartEvent(vehicle, currentDepartureTime);
                                    Simulation.Events.Add(departEvt);
                                }
                            }
                            else
                            {
                                //trip assignment for vehicles that are have not yet performed a route
                                Simulation.InitializeVehicleFlexibleRoute(vehicle, solutionRoute, solutionCustomers, solutionTimeWindows);
                            }
                        }
                    }
                }
            }
            else
            {
                Successor?.Handle(evt);
            }
        }