コード例 #1
0
ファイル: SolveForDay.cs プロジェクト: SCY95/VRP-Optimization
        public static void SolveForAssignedDay(IDataInput dataInput, IDataOutput dataOutput,
                                               VrpProblem vrpProblem, Day day, ConfigParams cfg, int[] VCMinMax)
        {
            //TimeMatrixInit(day, cfg);

            //SaveTimeMatrix(day);
            //LoadTimeMatrix(day);
            CalculateTMWithHaversineFormula(day);

            //vrpProblem.SolveVrpProblem(day, cfg);

            int min = VCMinMax[0];
            int max = VCMinMax[1];

            while (day.LocationDropped && !day.InfeasibleNodes && max >= min)
            {
                day.SetVehicleNumber(min);
                day.ResetResults();

                vrpProblem.SolveVrpProblem(day, cfg, vrpProblem, dataOutput, VCMinMax);

                dataOutput.PrintSolution(vrpProblem.day, vrpProblem.routing, vrpProblem.manager, vrpProblem.solution);
                dataOutput.PrintStatus(vrpProblem.routing);
                min++;
            }
            foreach (var item in day.DroppedLocations)//Remove unassigned locations from list
            {
                day.Locations.Remove(item);
            }

            return;
        }
コード例 #2
0
ファイル: SolveForDay.cs プロジェクト: SCY95/VRP-Optimization
        public static void AssignAndSolveForDay(IDataInput dataInput, IDataOutput dataOutput,
                                                VrpProblem vrpProblem, Day day, ConfigParams cfg, int[] VCMinMax)
        {
            CalculateTMWithHaversineFormula(day);

            int min = VCMinMax[0];
            int max = VCMinMax[1];

            while (!day.InfeasibleNodes && max >= min)
            {
                day.SetVehicleNumber(min);
                day.ResetResults();
                vrpProblem.SolveVrpProblem(day, cfg, vrpProblem, dataOutput, VCMinMax);

                if (day.Locations.Count > 1)
                {
                    dataOutput.PrintSolution(vrpProblem.day, vrpProblem.routing, vrpProblem.manager, vrpProblem.solution);
                    dataOutput.PrintStatus(vrpProblem.routing);
                }

                min++;
            }
            foreach (var item in day.DroppedLocations)//Remove unassigned locations from list
            {
                day.Locations.Remove(item);
            }
            foreach (var item in day.Locations)
            {
                if (!item.Infeasible)
                {
                    item.VisitDay = day.DayNum;
                }
            }
        }
コード例 #3
0
ファイル: VrpTest.cs プロジェクト: SCY95/VRP-Optimization
        public static void Main(String[] args)
        {
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("En");

            // Instantiate the data problem.
            DataInput    dataInput  = new DataInput();  //Config interface
            DataOutput   dataOutput = new DataOutput(); //Output interface
            VrpProblem   vrpProblem = new VrpProblem();
            ConfigParams cfg        = new ConfigParams();

            //Period(x) => period for x days
            Period period       = new Period(14);
            bool   AssignToDays = true;

            int[] VCMinMax = new int[2];//Vehicle Count
            dataInput.GetVCMinMax(VCMinMax);



            if (AssignToDays == true)
            {
                LocationDB.ResetVisitDays(LocationDB.Locations);

                for (int i = 0; i < period.Days.Count; i++)
                {
                    if (i == 6 || i == 13)
                    {
                        continue;
                    }
                    GetInput(dataInput, cfg, period.Days.ElementAt(i));
                    if (i < 6)
                    {
                        period.Days.ElementAt(i).SetDay(LocationDB.Locations.Where(x => x.VisitDay == 0 && x.Infeasible == false).ToList());
                        period.Days.ElementAt(i).DayNum = i + 1;
                        AssignAndSolveForDay(dataInput, dataOutput, vrpProblem, period.Days.ElementAt(i), cfg, VCMinMax);
                    }
                    if (i > 6)
                    {
                        List <Location> locations = new List <Location>();
                        foreach (var item in period.Days.ElementAt(i - 7).Locations.Where(x => x.VisitPeriod == 7).ToList())
                        {
                            item.Penalty = 1000000;
                            locations.Add(item);
                        }
                        locations.AddRange(LocationDB.Locations.Where(x => x.VisitDay == 0 && x.VisitPeriod == 14 && x.Infeasible == false).ToList());

                        period.Days.ElementAt(i).SetDay(locations);

                        period.Days.ElementAt(i).DayNum = i + 1;

                        AssignAndSolveForDay(dataInput, dataOutput, vrpProblem, period.Days.ElementAt(i), cfg, VCMinMax);
                    }
                }
                period.PrintSummary();
            }
            else
            {
                SetLocationsForDays(period);

                LocationDB.GetLocationDataFromDB();

                for (int i = 0; i < period.Days.Count; i++)
                {
                    if (period.Days.ElementAt(i).Locations.Count != 0)
                    {
                        GetInput(dataInput, cfg, period.Days.ElementAt(i));
                        SolveForAssignedDay(dataInput, dataOutput, vrpProblem, period.Days.ElementAt(i), cfg, VCMinMax);
                    }
                }

                period.PrintSummary();
            }



            Console.ReadLine();
            return;
        }
コード例 #4
0
        //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;
        }