public void PrintToConsole( Day day, RoutingModel routing, RoutingIndexManager manager, Assignment solution) { Console.WriteLine("Day " + day.DayNum); if (day.Locations.Count != 0) { // Display dropped nodes. string droppedNodes = "Dropped nodes:"; for (int index = 0; index < routing.Size(); ++index) { if (routing.IsStart(index) || routing.IsEnd(index)) { continue; } if (solution.Value(routing.NextVar(index)) == index) { droppedNodes += " " + manager.IndexToNode(index); } } Console.WriteLine("{0}", droppedNodes); // Inspect solution. for (int i = 0; i < day.Vehicles.Count; i++) { Console.WriteLine("Route for Vehicle {0}:", i); long routeDuration = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { Console.Write("{0} -> ", manager.IndexToNode((int)index)); var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDuration += routing.GetArcCostForVehicle(previousIndex, index, 0); } Console.WriteLine("{0}", manager.IndexToNode((int)index)); Console.WriteLine("Duration of the route: {0}mins", routeDuration); } Console.WriteLine("Minimum duration of the routes: {0}mins", day.MinDur); Console.WriteLine("Maximum duration of the routes: {0}mins", day.MaxDur); } else { Console.WriteLine("This day is holiday."); } }
private IList <Dropped> GetDroppedLocations(FileInput input, RoutingIndexManager manager, RoutingModel routing, Assignment solution) { IDictionary <int, string> locationsNames = input.Locations.ToDictionary(k => k.Id - 1, v => v.Name); List <Dropped> droppedLocations = new List <Dropped>(); for (int index = 0; index < routing.Size(); ++index) { if (routing.IsStart(index) || routing.IsEnd(index)) { continue; } if (solution.Value(routing.NextVar(index)) == index) { int node = manager.IndexToNode(index); droppedLocations.Add(new Dropped { LocationName = locationsNames[node] }); } } return(droppedLocations); }
//IntVar x; //IntVar y;//Reduntant public void SolveVrpProblem(Day day, ConfigParams cfg, VrpProblem vrpProblem, IDataOutput dataOutput, int[] VCMinMax) { this.day = day; this.cfg = cfg; //Google Distance Matrix API (Duration matrix) // Create Routing Index Manager manager = new RoutingIndexManager( day.TimeMatrix.GetLength(0), day.Vehicles.Count, day.Depot); // Create Routing Model. routing = new RoutingModel(manager); // Create and register a transit callback. int transitCallbackIndex = routing.RegisterTransitCallback( (long fromIndex, long toIndex) => { // Convert from routing variable Index to distance matrix NodeIndex. var fromNode = manager.IndexToNode(fromIndex); var toNode = manager.IndexToNode(toIndex); return(day.TimeMatrix[fromNode, toNode]); } ); // Define cost of each arc. routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex); // Add Distance constraint. if (day.TimeWindowsActive != true) { routing.AddDimension(transitCallbackIndex, 0, 700000, true, // start cumul to zero "Distance"); RoutingDimension distanceDimension = routing.GetMutableDimension("Distance"); distanceDimension.SetGlobalSpanCostCoefficient(100); } else { routing.AddDimension( transitCallbackIndex, // transit callback 1000, // allow waiting time 600, // vehicle maximum capacities false, // start cumul to zero "Time"); TimeWindowInit(day, routing, manager);//Set Time Window Constraints } if (day.MaxVisitsActive != 0) { int demandCallbackIndex = routing.RegisterUnaryTransitCallback( (long fromIndex) => { // Convert from routing variable Index to demand NodeIndex. var fromNode = manager.IndexToNode(fromIndex); return(day.Demands[fromNode]); } ); routing.AddDimensionWithVehicleCapacity( demandCallbackIndex, 0, // null capacity slack day.VehicleCapacities, // vehicle maximum capacities true, // start cumul to zero "Capacity"); } // Allow to drop nodes. for (int i = 1; i < day.TimeMatrix.GetLength(0); ++i) { routing.AddDisjunction( new long[] { manager.NodeToIndex(i) }, day.Locations.ElementAt(i).Penalty); } // Setting first solution heuristic. RoutingSearchParameters searchParameters = operations_research_constraint_solver.DefaultRoutingSearchParameters(); searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathMostConstrainedArc; //metaheuristic searchParameters.LocalSearchMetaheuristic = LocalSearchMetaheuristic.Types.Value.GuidedLocalSearch; searchParameters.TimeLimit = new Duration { Seconds = cfg.SolutionDuration }; searchParameters.LogSearch = true; solver = routing.solver(); //TODO //Some location must be on same route. //solver.Add(routing.VehicleVar(manager.NodeToIndex(2)) == routing.VehicleVar(manager.NodeToIndex(5))); //One node takes precedence over the another. //routing.AddPickupAndDelivery(manager.NodeToIndex(2), manager.NodeToIndex(5)); //Constraint variable //x = solver.MakeIntVar(day.Vehicles.Count, day.Vehicles.Count, "x"); //Number of vehicle restriction - old version //solver.Add(x < 7); //Number of vehicle restriction -new version //y = solver.MakeIntVar(routing.Vehicles(), routing.Vehicles(), "y"); //solver.Add(y <= VCMinMax[1]);//Reduntant // Solve the problem. solution = routing.SolveWithParameters(searchParameters); day.LocationDropped = false; // Display dropped nodes. List <int> droppedNodes = new List <int>(); for (int index = 0; index < routing.Size(); ++index) { if (routing.IsStart(index) || routing.IsEnd(index)) { continue; } if (solution.Value(routing.NextVar(index)) == index) { droppedNodes.Add(manager.IndexToNode((int)index)); day.LocationDropped = true; } } day.DroppedLocations.Clear(); Console.WriteLine(day.Locations.ElementAt(0).Name); if (droppedNodes != null) { foreach (var item in droppedNodes) { Location location = LocationDB.Locations.Where(x => x.Position.strPos_ == day.Addresses[item]).ToList().ElementAt(0); if (location != null) { Console.WriteLine(location.Name); day.DroppedLocations.Add(location); } } } List <int> AssignedNodes = new List <int>(); Console.WriteLine(manager.GetNumberOfNodes()); //Inspect Infeasable Nodes for (int i = 0; i < day.Vehicles.Count; i++) { var index = routing.Start(i); int j = 0; while (routing.IsEnd(index) == false) { j++; index = solution.Value(routing.NextVar(index)); } if (j == 1) { day.InfeasibleNodes = true; foreach (var item in day.DroppedLocations) { LocationDB.Locations.Where(x => x.ClientRef == item.ClientRef).ToList().ElementAt(0).Infeasible = true; } if (day.Vehicles.Count - 1 >= 1) { day.SetVehicleNumber(day.Vehicles.Count - 1); day.ResetResults(); vrpProblem.SolveVrpProblem(day, cfg, vrpProblem, dataOutput, VCMinMax); } return; } } // Inspect solution. day.TotalDur = 0; day.MinDur = 100000; for (int i = 0; i < day.Vehicles.Count; i++) { long routeDuration = 0; var index = routing.Start(i); while (routing.IsEnd(index) == false) { var previousIndex = index; index = solution.Value(routing.NextVar(index)); routeDuration += routing.GetArcCostForVehicle(previousIndex, index, 0); } day.TotalDur += routeDuration; day.MaxDur = Math.Max(routeDuration, day.MaxDur); day.MinDur = Math.Min(routeDuration, day.MinDur); } day.AvgDur = day.TotalDur / day.Vehicles.Count; }