コード例 #1
0
        // Check demand attended by vehicles is correct respect the capacity - FOR DEBUG
        public static void checkDemand(CluVRPInstance instance, List <int>[] clusterRouteForVehicule, int[] vehicleRemSpace)
        {
            // Vehicle remmaining capacity is correct respect to cluster demand
            int[] clusterDemand = instance.clusters_demand;
            int   totalDemand   = 0;

            // Sum the total demand for vehicle
            for (int vehicle = 0; vehicle < clusterRouteForVehicule.Length; vehicle++)
            {
                int totalDemandOnVehicle = 0;
                for (int clusterIt = 0; clusterIt < clusterRouteForVehicule[vehicle].Count; clusterIt++)
                {
                    int cluster = clusterRouteForVehicule[vehicle][clusterIt];
                    totalDemandOnVehicle += clusterDemand[cluster];
                }

                // Sum the total demand of all vehicles
                totalDemand += totalDemandOnVehicle;

                // Asserts
                Debug.Assert(instance.capacity - totalDemandOnVehicle < 0);
                Debug.Assert(instance.capacity - totalDemandOnVehicle != vehicleRemSpace[vehicle] || vehicleRemSpace[vehicle] < 0);
            }

            // Assert
            Debug.Assert(totalDemand == clusterDemand.Sum());
        }
コード例 #2
0
        /*
         *
         * Constructor
         *
         */
        public CustomerStrongGRASP(CluVRPInstance instance, CluVRPSolution solution, Parameters parameters)
        {
            // Set variables
            this.instance   = instance;
            this.solution   = solution;
            this.parameters = parameters;

            // For local search execute order
            if (parameters.Customer_LS_Order.Length == 0)
            {
                this.localSearchsOrder = new List <LocalSearch> {
                    LocalSearch.TwoOpt,
                    LocalSearch.Relocate, LocalSearch.Exchange, LocalSearch.SwapCustomers
                };
            }
            else
            {
                this.localSearchsOrder = new List <LocalSearch>();
                for (int i = 0; i < parameters.Customer_LS_Order.Length; i++)
                {
                    localSearchsOrder.Add((LocalSearch)parameters.Customer_LS_Order[i]);
                }
            }

            // End of constructor
        }
コード例 #3
0
        // Customer solution verification
        public void verifyCustomerSolution(CluVRPInstance instance)
        {
            // Verify number of vehicles
            int numberOfVehicles;

            if (instance.instance_type != Instance.GoldenIzquierdo)
            {
                numberOfVehicles = instance.vehicles;
                Debug.Assert(customersPaths.Length == numberOfVehicles, "The number of vehicles on the  customer path is incorrect");
                Debug.Assert(vehiculeRouteDistance.Length == numberOfVehicles, "The number of vehicles on the route distance is incorrect");
            }
            else
            {
                numberOfVehicles = customersPaths.Length;
            }

            // Verify number of clusters
            int numberOfClusters = instance.clusters.Length;
            int clustersCounter  = 0;

            for (int i = 0; i < customersPaths.Length; i++)
            {
                clustersCounter += customersPaths[i].Length;
            }
            Debug.Assert(numberOfClusters == clustersCounter - (customersPaths.Length * 2) + 1, "The number of cluster in the complete travel is incorrect");

            // Verify number of customers
            int numberOfCustomers = instance.dimension;
            int customersCounter  = 0;

            for (int i = 0; i < customersPaths.Length; i++)
            {
                for (int j = 0; j < customersPaths[i].Length; j++)
                {
                    customersCounter += customersPaths[i][j].Count;
                }
            }
            Debug.Assert(numberOfCustomers == customersCounter - (numberOfVehicles * 2) + 1);

            // All clusters are correct
            List <int>[] vehicleRoute = clusterRouteForVehicule;
            for (int vehicle = 0; vehicle < vehicleRoute.Length; vehicle++)
            {
                List <int> clusterList = vehicleRoute[vehicle];
                for (int clusterIt = 0; clusterIt < clusterList.Count; clusterIt++)
                {
                    int        clusterNumber   = clusterList[clusterIt];
                    List <int> cluster         = customersPaths[vehicle][clusterIt].ToList <int>();
                    List <int> clusterInstance = instance.clusters[clusterNumber].ToList <int>();
                    bool       containsAll     = Functions.ContainsAllItems(cluster, clusterInstance);
                    if (vehicleRoute[vehicle].Count != 2)
                    {
                        Debug.Assert(containsAll && cluster.Count == clusterInstance.Count, "All the clusters on the travel are not correct respect to their clients");
                    }
                }
            }

            // Total distance is correct
            Debug.Assert(Math.Truncate(totalCustomerRouteDistance) == Math.Truncate(Functions.calculateTotalTravelDistance(customersPaths, instance.customersDistanceMatrix, instance)), "The final distance is not correct");
        }
コード例 #4
0
        // New LS to final solutions
        public static void cluVRPLocalSearchs(CluVRPSolution cluVRPSolution, CluVRPInstance instance, Parameters parameters)
        {
            // Perform LS at cluster level
            double oldTotalDistance = cluVRPSolution.totalCustomerRouteDistance;
            var    totalWatch       = System.Diagnostics.Stopwatch.StartNew();

            swapClusters(cluVRPSolution, instance, parameters);
            cluVRPSolution.cluvrp_swapClusters_time += totalWatch.ElapsedMilliseconds;

            totalWatch = System.Diagnostics.Stopwatch.StartNew();
            swapVehicle(cluVRPSolution, instance, parameters);
            cluVRPSolution.cluvrp_swapVehicle_time += totalWatch.ElapsedMilliseconds;

            // If some cluster position change make LS at customer level
            if (cluVRPSolution.totalCustomerRouteDistance < oldTotalDistance)
            {
                // Create a local search handler for cluster-level problem
                CustomerStrongLocalSearch customerLocalSearch = new CustomerStrongLocalSearch(cluVRPSolution,
                                                                                              instance,
                                                                                              parameters.Customer_LS_TwoOpt_Iterations,
                                                                                              parameters.Customer_LS_Relocate_Iterations,
                                                                                              parameters.Customer_LS_Exchange_Iterations,
                                                                                              parameters.Customer_LS_SwapCustomers
                                                                                              );

                // Perform one iteration of LS at customer level
                customerLocalSearch.twoOpt();
                customerLocalSearch.exchange();
                customerLocalSearch.relocate();
                customerLocalSearch.swapCustomers();
            }

            // End
            return;
        }
コード例 #5
0
        // Cluster solution verification
        public void verifyClusterSolution(CluVRPInstance instance)
        {
            // All cluster was visited
            bool wasVisited = false;

            for (int cluster = 0; cluster < instance.clusters.Length; cluster++)
            {
                for (int vehicle = 0; vehicle < clusterRouteForVehicule.Length; vehicle++)
                {
                    if (clusterRouteForVehicule[vehicle].Contains(cluster))
                    {
                        wasVisited = true;
                        break;
                    }
                }
                Debug.Assert(wasVisited, "All clusters are not visited");
                wasVisited = false;
            }

            // Number of clusters visited is correct
            int totalLength = 0;

            for (int vehicle = 0; vehicle < clusterRouteForVehicule.Length; vehicle++)
            {
                totalLength += clusterRouteForVehicule[vehicle].Count;
            }
            Debug.Assert(instance.clusters.Length == totalLength - (2 * clusterRouteForVehicule.Length) + 1, "Number of cluster visited is incorrect");

            // Vehicle remmaining capacity is correct respect to cluster demand
            int[] clusterDemand = instance.clusters_demand;
            int   totalDemand   = 0;

            // Sum the total demand for vehicle
            for (int vehicle = 0; vehicle < clusterRouteForVehicule.Length; vehicle++)
            {
                int totalDemandOnVehicle = 0;
                for (int clusterIt = 0; clusterIt < clusterRouteForVehicule[vehicle].Count; clusterIt++)
                {
                    int cluster = clusterRouteForVehicule[vehicle][clusterIt];
                    totalDemandOnVehicle += clusterDemand[cluster];
                }

                // Sum the total demand of all vehicles
                totalDemand += totalDemandOnVehicle;
                Debug.Assert(instance.capacity - totalDemandOnVehicle >= 0, "The total demand is more big than the capacity of a vehicle");
            }
            Debug.Assert(totalDemand == clusterDemand.Sum(), "The total demand is more big than the total capacity");

            // Verify if all vehicules visit at least 1 cluster
            // This is necessary for GVRP and GoldelBattarra instances
            if (instance.instance_type == Instance.GVRP || instance.instance_type == Instance.GoldenBattarra)
            {
                for (int vehicle = 0; vehicle < clusterRouteForVehicule.Length; vehicle++)
                {
                    Debug.Assert(clusterRouteForVehicule[vehicle].Count > 2, "There are vehicles that no visit clusters");
                }
            }
        }
コード例 #6
0
        /*
         *
         * Read every instance file of InstanceSetName file and create a instance of it
         *
         */
        static public CluVRPInstance[] loadGVRPSetOfInstances(string InstanceSetName)
        {
            // Init variables
            string filePath = InstanceSetName;

            CluVRPInstance[] gvrpInstances;

            // Main Cycle
            try
            {
                string[] lines = System.IO.File.ReadAllLines(filePath);
                gvrpInstances = new CluVRPInstance[lines.Length];

                // Get all the instances setted on the file
                int i = 0;
                foreach (string instanceFilePath in lines)
                {
                    // Try to parse instance
                    try
                    {
                        CluVRPInstance instance;
                        string[]       instanceFileText = System.IO.File.ReadAllLines(instanceFilePath);
                        if (instanceFilePath.Contains("rho"))
                        {
                            instance = parseGoldenIzquierdoInstance(instanceFilePath, instanceFileText);
                        }
                        else if (instanceFilePath.Contains("Golden"))
                        {
                            instance = parseGoldenBattarraInstance(instanceFilePath, instanceFileText);
                        }
                        else
                        {
                            instance = parseGVRPInstance(instanceFilePath, instanceFileText);
                        }
                        gvrpInstances[i] = instance;
                        i++;
                    }
                    catch (Exception e)
                    {
                        Logger.GetInstance().logLine(e.ToString());
                    }
                }
            }catch (Exception e)
            {
                Logger.GetInstance().logLine(e.ToString());
                return(null);
            }

            // Return array of instances
            return(gvrpInstances);
        }
コード例 #7
0
 // Constructor
 public CustomerStrongLocalSearch(CluVRPSolution solution,
                                  CluVRPInstance instance,
                                  int maxIterationsWithoutImprovementTwoOpt        = 100,
                                  int maxIterationsWithoutImprovementRelocate      = 100,
                                  int maxIterationsWithoutImprovementExchange      = 100,
                                  int maxIterationsWithoutImprovementSwapCustomers = 100)
 {
     this.solution = solution;
     this.instance = instance;
     this.maxIterationsWithoutImprovementTwoOpt        = maxIterationsWithoutImprovementTwoOpt;
     this.maxIterationsWithoutImprovementRelocate      = maxIterationsWithoutImprovementRelocate;
     this.maxIterationsWithoutImprovementExchange      = maxIterationsWithoutImprovementExchange;
     this.maxIterationsWithoutImprovementSwapCustomers = maxIterationsWithoutImprovementSwapCustomers;
 }
コード例 #8
0
        // Customer solution verification
        public void verifyCustomerWeakSolution(CluVRPInstance instance)
        {
            // Verify number of vehicles
            int numberOfVehicles;

            if (instance.instance_type != Instance.GoldenIzquierdo)
            {
                numberOfVehicles = instance.vehicles;
            }
            else
            {
                numberOfVehicles = customersWeakRoute.Length;
            }
            Debug.Assert(customersWeakRoute.Length == numberOfVehicles, "CustomerWeak - The number of vehicles is incorrect respect to customer path");
            Debug.Assert(vehiculeRouteDistance.Length == numberOfVehicles, "CustomerWeak - The number of vehicles is incorrect respect to vehicles distance vector");

            // Verify number of customers and all paths start and end on depot
            int numberOfCustomers = instance.dimension;
            int customersCounter  = 0;

            for (int i = 0; i < customersWeakRoute.Length; i++)
            {
                customersCounter += customersWeakRoute[i].Count;
                Debug.Assert(customersWeakRoute[i][0] == 1 && customersWeakRoute[i][customersWeakRoute[i].Count - 1] == 1, "CustomerWeak - There is a customer path that not start or end on the depot");
            }
            Debug.Assert(numberOfCustomers == customersCounter - (numberOfVehicles * 2) + 1, "CustomerWeak - The number of total customers is incorrect on the travel");

            // All clusters are correct
            List <int>[] vehicleRoute = clusterRouteForVehicule;
            for (int vehicle = 0; vehicle < vehicleRoute.Length; vehicle++)
            {
                List <int> clusterList        = vehicleRoute[vehicle];
                int        allClustersSizeSum = 0;
                for (int clusterIt = 0; clusterIt < clusterList.Count; clusterIt++)
                {
                    int        clusterNumber   = clusterList[clusterIt];
                    List <int> cluster         = customersWeakRoute[vehicle].ToList <int>();
                    List <int> clusterInstance = instance.clusters[clusterNumber].ToList <int>();
                    allClustersSizeSum += clusterInstance.Count;
                    bool containsAll = Functions.ContainsAllItems(cluster, clusterInstance);
                    Debug.Assert(containsAll, "CustomerWeak - All the clusters not contains the corrects customers");
                }
                Debug.Assert(customersWeakRoute[vehicle].Count == allClustersSizeSum, "The total sum of customers is not correct on the travel");
            }

            // Total distance is correct
            Debug.Assert(Math.Truncate(totalCustomerRouteDistance) == Math.Truncate(Functions.calculateCustomerTotalTravelDistanceForVehicle(customersWeakRoute, instance.customersDistanceMatrix, instance)), "CustomerWeak - The final distance is not correct");
        }
コード例 #9
0
 // Constructor
 public ClusterLocalSearch(CluVRPSolution solution,
                           CluVRPInstance instance,
                           int maxIterationsWithoutImprovementTwoOpt   = 100,
                           int maxIterationsWithoutImprovementRelocate = 100,
                           int maxIterationsWithoutImprovementExchange = 100,
                           //int maxIterationsWithoutImprovementIVRS = 100,
                           //int maxIterationsWithoutImprovementIVRC = 100,
                           int maxIterationsWithoutImprovementIV = 100,
                           int maxIterationsWithoutImprovementSV = 100,
                           int maxIterationsWithoutImprovementSC = 100
                           )
 {
     this.solution = solution;
     this.instance = instance;
     this.maxIterationsWithoutImprovementTwoOpt   = maxIterationsWithoutImprovementTwoOpt;
     this.maxIterationsWithoutImprovementRelocate = maxIterationsWithoutImprovementRelocate;
     this.maxIterationsWithoutImprovementExchange = maxIterationsWithoutImprovementExchange;
     //this.maxIterationsWithoutImprovementIVRS = maxIterationsWithoutImprovementIVRS;
     //this.maxIterationsWithoutImprovementIVRC = maxIterationsWithoutImprovementIVRC;
     this.maxIterationsWithoutImprovementIV = maxIterationsWithoutImprovementIV;
     this.maxIterationsWithoutImprovementSV = maxIterationsWithoutImprovementSV;
     this.maxIterationsWithoutImprovementSC = maxIterationsWithoutImprovementSC;
 }
コード例 #10
0
        // Calculate the total customer distance of a all vehicles
        public static double calculateCustomerTotalTravelDistanceForVehicle(List <int>[] travel, double[][] customersDistanceMatrix, CluVRPInstance instance)
        {
            // Set variables
            double totalDistance = 0;

            for (int vehicle = 0; vehicle < travel.Length; vehicle++)
            {
                if (instance.instance_type == Instance.GoldenBattarra || instance.instance_type == Instance.GVRP)
                {
                    totalDistance += (int)calculateCustomerTravelDistance(travel[vehicle], customersDistanceMatrix);
                }
                if (instance.instance_type == Instance.GoldenIzquierdo)
                {
                    totalDistance += calculateCustomerTravelDistance(travel[vehicle], customersDistanceMatrix);
                }
            }

            // Return total distance
            return(totalDistance);
        }
コード例 #11
0
        // Calculate the total travel (visiting all the custer and customers by each vehicle)
        static public double calculateTotalTravelDistance(List <int>[][] customersCircuit, double[][] customersDistanceMatrix, CluVRPInstance instance)
        {
            double distance = 0;

            for (int vehicle = 0; vehicle < customersCircuit.Length; vehicle++)
            {
                if (instance.instance_type == Instance.GoldenBattarra || instance.instance_type == Instance.GVRP)
                {
                    distance += (int)calculateTotalTravelDistance(customersCircuit, customersDistanceMatrix, vehicle);
                }
                if (instance.instance_type == Instance.GoldenIzquierdo)
                {
                    distance += calculateTotalTravelDistance(customersCircuit, customersDistanceMatrix, vehicle);
                }
            }

            return(distance);
        }
コード例 #12
0
        // Write a python script to draw the solution
        public static void solutionDrawPythonCode(CluVRPInstance instance, CluVRPSolution solution)
        {
            // Lines of file
            List <string> lines = new List <string>();

            // Add initial lines to script
            lines.Add("import matplotlib.pyplot as plt");
            lines.Add("plt.figure(num=None, figsize=(24, 16), dpi=120, facecolor='w', edgecolor='k')");

            // For python vars
            string[] abc = new string[] { "a", "b", "c", "d", "f", "g", "h", "i", "j", "k", "l", "m", "k", "r", "t", "u", "v", "w", "y", "z",
                                          "aa", "ab", "ac", "ad", "af", "ag", "ah", "ai", "aj", "ak", "al", "am", "ak", "ar", "at", "au", "av", "aw", "ay", "az",
                                          "ca", "cb", "cc", "cd", "cf", "cg", "ch", "ci", "cj", "ck", "cl", "cm", "ck", "cr", "ct", "cu", "cv", "cw", "cy", "cz" };

            // Array of colors
            string[] colors         = new string[] { "aqua", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "green", "greenyellow", "grey", "honeydew", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen" };
            string[] vehicle_colors = new string[] { "red", "green", "blue", "orange", "purple", "cyan", "magenta", "lime", "pink", "teal", "lavender", "brown", "beige", "maroon", "mint", "olive", "coral", "navy", "grey", "white", "black" };

            // Variables
            int    colorIt     = 0;
            int    var1        = 0;
            int    var2        = 1;
            string outFileName = instance.file_name + ".py";

            // Code for draw the customers points
            // All customers of one cluster have the same color
            string array1 = abc[var1] + "= [" + instance.nodes[0].x.ToString().Replace(',', '.') + "]";
            string array2 = abc[var2] + "= [" + instance.nodes[0].y.ToString().Replace(',', '.') + "]";
            string array3 = "plt.plot(" + abc[0] + "," + abc[1] + ",'ro', markersize= 44, color = '" + colors[0] + "')";

            lines.Add(array1);
            lines.Add(array2);
            lines.Add(array3);
            var1 = var1 + 2;
            var2 = var2 + 2;
            colorIt++;
            for (int clusterIt = 1; clusterIt < instance.clusters.Length; clusterIt++)
            {
                array1 = abc[var1] + "= [";
                array2 = abc[var2] + "= [";

                for (int customerIt = 0; customerIt < instance.clusters[clusterIt].Length; customerIt++)
                {
                    int customer = instance.clusters[clusterIt][customerIt] - 1;
                    array1 += instance.nodes[customer].x.ToString().Replace(',', '.') + ",";
                    array2 += instance.nodes[customer].y.ToString().Replace(',', '.') + ",";
                }

                StringBuilder sb = new StringBuilder(array1);
                sb[sb.Length - 1] = ']';
                array1            = sb.ToString();
                sb = new StringBuilder(array2);
                sb[sb.Length - 1] = ']';
                array2            = sb.ToString();
                array3            = "plt.plot(" + abc[var1] + "," + abc[var2] + ",'ro', color = '" + colors[colorIt] + "')";

                // For centroides
                var1 = (var1 + 2) % abc.Length;
                var2 = (var1 + 2) % abc.Length;
                string array4 = abc[var1] + "= [";
                string array5 = abc[var2] + "= [";
                array4 += instance.clustersCentroid[clusterIt].Item1.ToString().Replace(',', '.') + "]";
                array5 += instance.clustersCentroid[clusterIt].Item2.ToString().Replace(',', '.') + "]";
                string array6 = "plt.plot(" + abc[var1] + "," + abc[var2] + ",'ro',markersize=22, color = '" + colors[colorIt] + "')";

                // Write python code for clusters and customers
                lines.Add(array1);
                lines.Add(array2);
                lines.Add(array3);
                lines.Add(array4);
                lines.Add(array5);
                lines.Add(array6);

                // Change color and variables name for next cluster
                var1    = (var1 + 2) % abc.Length;
                var2    = (var2 + 2) % abc.Length;
                colorIt = (colorIt + 1) % colors.Length;
            }

            // Draw vehicle travel
            var1    = 0;
            var2    = 1;
            colorIt = 0;
            for (int vehicle = 0; vehicle < solution.customersPaths.Length; vehicle++)
            {
                array1 = abc[var1] + "= [";
                array2 = abc[var2] + "= [";
                for (int clusterIt = 0; clusterIt < solution.customersPaths[vehicle].Length; clusterIt++)
                {
                    for (int customerIt = 0; customerIt < solution.customersPaths[vehicle][clusterIt].Count; customerIt++)
                    {
                        int customer = solution.customersPaths[vehicle][clusterIt][customerIt] - 1;
                        array1 += instance.nodes[customer].x.ToString().Replace(',', '.') + ",";
                        array2 += instance.nodes[customer].y.ToString().Replace(',', '.') + ",";
                    }
                }
                StringBuilder sb = new StringBuilder(array1);
                sb[sb.Length - 1] = ']';
                array1            = sb.ToString();
                sb = new StringBuilder(array2);
                sb[sb.Length - 1] = ']';
                array2            = sb.ToString();

                array3 = "plt.plot(" + abc[var1] + "," + abc[var2] + ", color = '" + vehicle_colors[colorIt] + "')";

                // Write python code for clusters and customers
                lines.Add(array1);
                lines.Add(array2);
                lines.Add(array3);

                // Change color and variables name for next cluster
                var1    = (var1 + 2) % abc.Length;
                var2    = (var2 + 2) % abc.Length;
                colorIt = (colorIt + 1) % vehicle_colors.Length;
            }

            // Add final line
            lines.Add("plt.savefig('" + instance.file_name + ".png')");

            // Write file
            try
            {
                System.IO.File.WriteAllLines(outFileName, lines);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            // Excute script
            System.Diagnostics.Process.Start(PYTHON_PATH, outFileName);
        }
コード例 #13
0
 // Constructor
 public CluVRPSolution(CluVRPInstance instance)
 {
     totalClusterRouteDistance = double.MaxValue;
     instaceType = instance.instance_type;
 }
コード例 #14
0
        // Try to swap all the clusters (one bye one) for all vehicles (one by one)
        public static void swapVehicle(CluVRPSolution solution, CluVRPInstance instance, Parameters parameters)
        {
            // Cluster demand
            int[] clusterDemand = instance.clusters_demand;

            // More than 1 vehicle is needed
            if (solution.clusterRouteForVehicule.Length < 2)
            {
                return;
            }

            // Main cycle
            int iterations = 0;

            while (iterations < parameters.CluVRP_LS_SwapVehicle)
            {
                // For random order on iterations
                List <int> rndPosition = new List <int>();
                for (int i = 0; i < solution.clusterRouteForVehicule.Length; i++)
                {
                    rndPosition.Add(i);
                }
                Functions.Shuffle <int>(new Random(), rndPosition);

                // For each vehicle 1
                for (int vehicleIt1 = 0; vehicleIt1 < solution.clusterRouteForVehicule.Length; vehicleIt1++)
                {
                    // For each vehicle 2
                    for (int vehicleIt2 = 0; vehicleIt2 < solution.clusterRouteForVehicule.Length; vehicleIt2++)
                    {
                        // When is not the same vehicle
                        if (vehicleIt1 != vehicleIt2)
                        {
                            // Select vehicle index from random position
                            int vehicle1 = rndPosition[vehicleIt1];
                            int vehicle2 = rndPosition[vehicleIt2];

                            // For each cluster 1 on vehicle 1
                            for (int cluster1 = 1; cluster1 < solution.clusterRouteForVehicule[vehicle1].Count; cluster1++)
                            {
                                // For each cluster 2 on vehicle 2
                                for (int cluster2 = 1; cluster2 < solution.clusterRouteForVehicule[vehicle2].Count; cluster2++)
                                {
                                    // Calculate the space on vehicle if make a swap
                                    int clusterSwappedV1 = solution.clusterRouteForVehicule[vehicle1][cluster1];
                                    int clusterSwappedV2 = solution.clusterRouteForVehicule[vehicle2][cluster2];

                                    int newSpaceV1 = solution.vehicleRemSpace[vehicle1] + clusterDemand[clusterSwappedV1] - clusterDemand[clusterSwappedV2];
                                    int newSpaceV2 = solution.vehicleRemSpace[vehicle2] + clusterDemand[clusterSwappedV2] - clusterDemand[clusterSwappedV1];

                                    // If swap is possible
                                    if (newSpaceV1 > 0 && newSpaceV2 > 0 && clusterSwappedV1 != 0 && clusterSwappedV2 != 0 && clusterSwappedV1 != clusterSwappedV2)
                                    {
                                        int lastClusterSwappedV1 = solution.clusterRouteForVehicule[vehicle1][cluster1 - 1];
                                        int lastClusterSwappedV2 = solution.clusterRouteForVehicule[vehicle2][cluster2 - 1];
                                        int nextClusterSwappedV1 = solution.clusterRouteForVehicule[vehicle1][cluster1 + 1];
                                        int nextClusterSwappedV2 = solution.clusterRouteForVehicule[vehicle2][cluster2 + 1];

                                        // Calculate old distances for each vehicle
                                        double oldDistanceVehicle1 = Functions.calculateCustomerTotalTravelDistanceForVehicle(solution.customersPaths[vehicle1], instance.customersDistanceMatrix, instance);
                                        double oldDistanceVehicle2 = Functions.calculateCustomerTotalTravelDistanceForVehicle(solution.customersPaths[vehicle2], instance.customersDistanceMatrix, instance);

                                        // Swap clusters
                                        List <int> cluster1Swp = solution.customersPaths[vehicle1][cluster1];
                                        List <int> cluster2Swp = solution.customersPaths[vehicle2][cluster2];
                                        solution.customersPaths[vehicle1][cluster1] = cluster2Swp;
                                        solution.customersPaths[vehicle2][cluster2] = cluster1Swp;

                                        // Calculate new distances for each vehicle
                                        double newDistanceVehicle1 = Functions.calculateCustomerTotalTravelDistanceForVehicle(solution.customersPaths[vehicle1], instance.customersDistanceMatrix, instance);
                                        double newDistanceVehicle2 = Functions.calculateCustomerTotalTravelDistanceForVehicle(solution.customersPaths[vehicle2], instance.customersDistanceMatrix, instance);

                                        // Calculate new total distance
                                        double newDistance = solution.totalClusterRouteDistance - (oldDistanceVehicle1 + oldDistanceVehicle2) + (newDistanceVehicle1 + newDistanceVehicle2);

                                        // If new distance is short
                                        if (newDistance + 0.0001 < solution.totalClusterRouteDistance)
                                        {
                                            // Update distance and space remaining
                                            solution.totalClusterRouteDistance = newDistance;
                                            solution.vehicleRemSpace[vehicle1] = newSpaceV1;
                                            solution.vehicleRemSpace[vehicle2] = newSpaceV2;
                                            solution.clusterRouteForVehicule[vehicle1][cluster1] = clusterSwappedV2;
                                            solution.clusterRouteForVehicule[vehicle2][cluster1] = clusterSwappedV1;

                                            // Reset iterator
                                            if (solution.cluvrp_swapVehicle_iterations <= iterations)
                                            {
                                                solution.cluster_insertVehicle_iterations = iterations;
                                            }
                                            iterations = 0;

                                            // DEBUG
                                            Logger.GetInstance().logLine("DEBUG - Improve on swapVehicle");
                                        }
                                        // If new distance is not short
                                        else
                                        {
                                            // Undo swap
                                            solution.customersPaths[vehicle1][cluster1] = cluster1Swp;
                                            solution.customersPaths[vehicle2][cluster2] = cluster2Swp;

                                            // Increase iterator
                                            iterations++;
                                        }
                                    }
                                    else
                                    {
                                        iterations++;
                                    }
                                    // End if swap is possible
                                } // End for cluster 2
                            }     // End for cluster 1
                        }         // End if is not the same vehicle
                    }             // End for vehicle 2
                }                 // End for vehicle 1
            }

            //End
            return;
        }
コード例 #15
0
        // Main GRASP handle main iteration depending if use Complete version or TwoPhase
        public static CluVRPSolution Grasp(CluVRPInstance instance, Parameters parameters)
        {
            // For best solution
            CluVRPSolution bestSolution = new CluVRPSolution(instance);

            // Main cycle
            int iterator = 0;

            while (iterator < parameters.CluVRP_GRASPIterations)
            {
                // New Grasp for Cluster level instance
                ClusterGRASP clusterGrasp = new ClusterGRASP(instance, parameters);

                // Execute Grasp procedure
                var            totalWatch     = System.Diagnostics.Stopwatch.StartNew();
                CluVRPSolution cluVRPSolution = clusterGrasp.Grasp();
                cluVRPSolution.clusterLevelTime = totalWatch.ElapsedMilliseconds;

                // If solutions is not available continue with next iteration
                if (cluVRPSolution.clusterRouteForVehicule == null)
                {
                    iterator++;
                    continue;
                }

                // Verify if cluster solution is correct
                cluVRPSolution.verifyClusterSolution(instance);

                // New Grasp for Cluster level instance
                CustomerLevel customerGrasp = null;
                if (parameters.CluVRP_Version == CluVRPVersion.Strong)
                {
                    customerGrasp = new CustomerStrongGRASP(instance, cluVRPSolution, parameters);
                }
                else if (parameters.CluVRP_Version == CluVRPVersion.Weak)
                {
                    customerGrasp = new CustomerWeakGRASP(instance, cluVRPSolution, parameters);
                }

                // Execute Grasp procedure
                totalWatch = System.Diagnostics.Stopwatch.StartNew();
                customerGrasp.Grasp();
                cluVRPSolution.customerLevelTime = totalWatch.ElapsedMilliseconds;

                //if solution is not available continue with next iteration
                if (cluVRPSolution.customersPaths == null && cluVRPSolution.customersWeakRoute == null)
                {
                    continue;
                }

                // Perform LS
                if ((parameters.CluVRP_LS_SwapClusters > 0 || parameters.CluVRP_LS_SwapVehicle > 0) && parameters.CluVRP_Version == CluVRPVersion.Strong)
                {
                    cluVRPLocalSearchs(cluVRPSolution, instance, parameters);
                }

                // Verify if customer solution is correct
                if (parameters.CluVRP_Version == CluVRPVersion.Strong)
                {
                    cluVRPSolution.verifyCustomerSolution(instance);
                }
                else if (parameters.CluVRP_Version == CluVRPVersion.Weak)
                {
                    cluVRPSolution.verifyCustomerWeakSolution(instance);
                }

                // Update best solution
                if (cluVRPSolution.totalCustomerRouteDistance < bestSolution.totalCustomerRouteDistance)
                {
                    bestSolution = cluVRPSolution;
                    bestSolution.cluVRPIterations = iterator;
                }

                // Increase iterator
                iterator++;
            }

            // Return best solution
            return(bestSolution);
        }
コード例 #16
0
        // Swap Cluster heuristic (diff to the cluster levels because the customers paths has been builded)
        public static void swapClusters(CluVRPSolution solution, CluVRPInstance instance, Parameters parameters)
        {
            // Calculate old distances for each vehicle
            double[] bestVehicleDistance = new double[solution.clusterRouteForVehicule.Length];
            for (int vehicleIt = 0; vehicleIt < bestVehicleDistance.Length; vehicleIt++)
            {
                bestVehicleDistance[vehicleIt] = Functions.calculateTotalTravelDistance(solution.customersPaths, instance.customersDistanceMatrix, vehicleIt);
            }

            // For each vehicle
            for (int vehicle = 0; vehicle < solution.customersPaths.Length; vehicle++)
            {
                // Main cycle
                while (true)
                {
                    // If solution improves try with new iteration
                    bool solutionImproves = false;

                    // For each cluster1
                    for (int clusterIt1 = 1; clusterIt1 + 1 < solution.customersPaths[vehicle].Length; clusterIt1++)
                    {
                        // For each cluster2
                        for (int clusterIt2 = 1; clusterIt2 + 1 < solution.customersPaths[vehicle].Length; clusterIt2++)
                        {
                            // If is not the same cluster
                            if (clusterIt1 != clusterIt2)
                            {
                                // Calculate last and next cluster for cluster1
                                List <int> cluster1Last = solution.customersPaths[vehicle][clusterIt1 - 1];
                                List <int> cluster1     = solution.customersPaths[vehicle][clusterIt1];
                                List <int> cluster1Next = solution.customersPaths[vehicle][clusterIt1 + 1];

                                // Calculate last and next cluster for cluster2
                                List <int> cluster2Last = solution.customersPaths[vehicle][clusterIt2 - 1];
                                List <int> cluster2     = solution.customersPaths[vehicle][clusterIt2];
                                List <int> cluster2Next = solution.customersPaths[vehicle][clusterIt2 + 1];

                                // Perform swap
                                solution.customersPaths[vehicle][clusterIt1] = cluster2;
                                solution.customersPaths[vehicle][clusterIt2] = cluster1;
                                Functions.Swap(solution.clusterRouteForVehicule[vehicle], clusterIt1, clusterIt2);

                                // Calculate new distance
                                double newDistance = Functions.calculateTotalTravelDistance(solution.customersPaths, instance.customersDistanceMatrix, vehicle);

                                // If new distance is not better
                                if (solution.vehiculeRouteDistance[vehicle] <= newDistance + 0.00001)
                                {
                                    // Back the changes
                                    solution.customersPaths[vehicle][clusterIt1] = cluster1;
                                    solution.customersPaths[vehicle][clusterIt2] = cluster2;
                                    Functions.Swap(solution.clusterRouteForVehicule[vehicle], clusterIt1, clusterIt2);
                                }
                                else
                                {
                                    // If new solution is better update distance
                                    solution.vehiculeRouteDistance[vehicle] = newDistance;
                                    solutionImproves = true;
                                }
                            }
                        }
                    }

                    // If solution not improves jump to next vehicle
                    if (!solutionImproves)
                    {
                        break;
                    }
                }
            }

            // End
            return;
        }