예제 #1
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;
        }
예제 #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
        /*
         *
         * Applies a list of local searchs
         *
         */
        private void localSearch(CluVRPSolution newSolution)
        {
            // Create a local search handler for cluster-level problem
            CustomerStrongLocalSearch customerLocalSearch = new CustomerStrongLocalSearch(newSolution,
                                                                                          instance,
                                                                                          parameters.Customer_LS_TwoOpt_Iterations,
                                                                                          parameters.Customer_LS_Relocate_Iterations,
                                                                                          parameters.Customer_LS_Exchange_Iterations,
                                                                                          parameters.Customer_LS_SwapCustomers
                                                                                          );


            // If random order for local searchs is activated
            if (parameters.Customer_LS_Order.Length == 0)
            {
                Functions.Shuffle(new Random(), this.localSearchsOrder);
            }

            // Execute local search in the correct order
            for (int i = 0; i < localSearchsOrder.Count; i++)
            {
                // Perform TwoOpt
                if (localSearchsOrder[i] == LocalSearch.TwoOpt && parameters.Customer_LS_TwoOpt_Iterations != 0)
                {
                    var totalWatch = System.Diagnostics.Stopwatch.StartNew();
                    customerLocalSearch.twoOpt();
                    customerLocalSearch.solution.customer_twoOpt_time += totalWatch.ElapsedMilliseconds;
                }

                // Perform Relocate
                if (localSearchsOrder[i] == LocalSearch.Relocate && parameters.Customer_LS_Relocate_Iterations != 0)
                {
                    var totalWatch = System.Diagnostics.Stopwatch.StartNew();
                    customerLocalSearch.relocate();
                    customerLocalSearch.solution.customer_relocate_time += totalWatch.ElapsedMilliseconds;
                }

                // Perform Exchange
                if (localSearchsOrder[i] == LocalSearch.Exchange && parameters.Customer_LS_Exchange_Iterations != 0)
                {
                    var totalWatch = System.Diagnostics.Stopwatch.StartNew();
                    customerLocalSearch.exchange();
                    customerLocalSearch.solution.customer_exchange_time += totalWatch.ElapsedMilliseconds;
                }

                // Perform Customer Swap
                if (localSearchsOrder[i] == LocalSearch.SwapCustomers && parameters.Customer_LS_SwapCustomers != 0)
                {
                    var totalWatch = System.Diagnostics.Stopwatch.StartNew();
                    customerLocalSearch.swapCustomers();
                    customerLocalSearch.solution.customer_swapCustomers_time += totalWatch.ElapsedMilliseconds;
                }
            }
            // Set the solution
            newSolution = customerLocalSearch.solution;
        }
예제 #4
0
        /*
         *
         *  Create a complete Greedy Randomized Solution (with cluster and customers)
         *
         */
        private CluVRPSolution constructGreedyRandomizedSolution(List <int>[] customersOnVehicle, double alpha)
        {
            // Init variables
            int vehiclesNumber = customersOnVehicle.Length;

            List <int>[] customersCircuit      = new List <int> [vehiclesNumber];
            double[]     vehiculeTotalDistance = new double[vehiclesNumber];

            // For each vehicule cluster-route
            for (int vehicle = 0; vehicle < customersCircuit.Length; vehicle++)
            {
                // Init customer circuit for i-vehicle
                List <int> customersToVisit = customersOnVehicle[vehicle].ToList <int>();
                customersCircuit[vehicle] = new List <int>();

                // Add depot as first customer
                customersCircuit[vehicle].Add(1);

                // While exists customers to visit
                while (customersToVisit.Count > 0)
                {
                    // Last customer
                    int lastCustomer = customersCircuit[vehicle][customersCircuit[vehicle].Count - 1];

                    // Create RCL for customer
                    List <int> customerRCL = buildCustomerRCL(customersToVisit, lastCustomer, alpha);

                    // Select customer for RCL
                    int customerSelected = Functions.selectRandomElement(customerRCL);

                    // Add customer to the path
                    customersCircuit[vehicle].Add(customerSelected);

                    // Quit visited customer
                    customersToVisit.Remove(customerSelected);
                }

                // Add depot as final customer
                customersCircuit[vehicle].Add(1);

                // Calculte total inter-cluster distance
                vehiculeTotalDistance[vehicle] = Functions.calculateCustomerTravelDistance(customersCircuit[vehicle], instance.customersDistanceMatrix);
            }

            // Set solution
            CluVRPSolution newSolution = new CluVRPSolution(instance);

            newSolution.setWeakCostumerSolution(customersCircuit, vehiculeTotalDistance);

            // Return solution
            return(newSolution);
        }
예제 #5
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;
 }
예제 #6
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;
 }
예제 #7
0
        internal void logTimeAndIterations(CluVRPSolution solution, string instance)
        {
            string line = instance + '\t' +
                          solution.cluVRPIterations.ToString() + '\t' +

                          //solution.clusterLevelIterations.ToString() + '\t' +
                          //solution.customerLevelIterations.ToString() + '\t' +
                          //solution.LSCycleterations.ToString() + '\t' +

                          (solution.clusterLevelTime).ToString() + '\t' +
                          (solution.customerLevelTime).ToString() + '\t' +
                          solution.cluster_LSCycle_iterations.ToString() + '\t' +
                          solution.customer_LSCycle_iterations.ToString() + '\t' +
                          (solution.cluster_LSCycleTime).ToString() + '\t' +
                          (solution.customer_LSCycleTime).ToString() + '\t' +

                          solution.cluvrp_swapClusters_iterations.ToString() + '\t' +
                          solution.cluvrp_swapClusters_time.ToString() + '\t' +
                          solution.cluvrp_swapVehicle_iterations.ToString() + '\t' +
                          solution.cluvrp_swapVehicle_time.ToString() + '\t' +

                          solution.cluster_twoOpt_iterations.ToString() + '\t' +
                          (solution.cluster_twoOpt_time).ToString() + '\t' +

                          solution.cluster_relocate_iterations.ToString() + '\t' +
                          (solution.cluster_relocate_time).ToString() + '\t' +

                          solution.cluster_exchange_iterations.ToString() + '\t' +
                          (solution.cluster_exchange_time).ToString() + '\t' +

                          solution.cluster_swapClusters_iterations.ToString() + '\t' +
                          (solution.cluster_swapClusters_time).ToString() + '\t' +

                          solution.cluster_swapVehicle_iterations.ToString() + '\t' +
                          (solution.cluster_swapVehicle_time).ToString() + '\t' +

                          solution.cluster_insertVehicle_iterations.ToString() + '\t' +
                          (solution.cluster_insertVehicle_time).ToString() + '\t' +

                          solution.customer_twoOpt_iterations.ToString() + '\t' +
                          (solution.customer_twoOpt_time).ToString() + '\t' +

                          solution.customer_relocate_iterations.ToString() + '\t' +
                          (solution.customer_relocate_time).ToString() + '\t' +

                          solution.customer_exchange_iterations.ToString() + '\t' +
                          (solution.customer_exchange_time).ToString() + '\t' +

                          solution.customer_swapCustomers_iterations.ToString() + '\t' +
                          (solution.customer_swapCustomers_time).ToString();

            try
            {
                using (System.IO.StreamWriter file = System.IO.File.AppendText(logFilePath + "_time"))
                {
                    file.WriteLine(line);
                    if (verbose)
                    {
                        Console.WriteLine(line);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
예제 #8
0
        /*
         *
         * Grasp():
         * M <- calculateCustomerDistance
         * BestSolution = 0
         * While(StopCondition)
         *      Solution <- ConstructGreedySolution()
         *      NewSolution <- LocalSearch(solution)
         *      if NewSolution isBetterThan BestSolution
         *          BestSolution = NewSolution
         * return BestSolution
         *
         */
        override public void Grasp()
        {
            // Set iterator
            int    iterator        = 0;
            int    totalIterations = parameters.Customer_GRASPIterations;
            double alpha           = parameters.Customer_Alpha;

            // Main cycle
            while (iterator < totalIterations)
            {
                // For random alpha
                if (parameters.Customer_Alpha == -1)
                {
                    Random rnd = new Random();
                    alpha = rnd.Next(0, 11) / 10.0;
                }

                // Calculate new initial solution
                CluVRPSolution newSolution = constructGreedyRandomizedSolution(alpha);

                // Local search
                var    totalLSWatch  = System.Diagnostics.Stopwatch.StartNew();
                double routeDistance = newSolution.totalCustomerRouteDistance;
                for (int i = 0; i < 1; i++)
                {
                    // Perform local searchs
                    this.localSearch(newSolution);

                    // For control of best iteration number
                    if (newSolution.totalCustomerRouteDistance < routeDistance)
                    {
                        newSolution.cluster_LSCycle_iterations = i;
                        routeDistance = newSolution.totalCustomerRouteDistance;
                    }
                }
                newSolution.customer_LSCycleTime += totalLSWatch.ElapsedMilliseconds;

                // Update Best solution
                if (newSolution.totalCustomerRouteDistance < solution.totalCustomerRouteDistance)
                {
                    solution.setCostumerSolution(newSolution.customersPaths, newSolution.vehiculeRouteDistance);
                    solution.bestCustomerLSOrder = localSearchsOrder;

                    solution.customerLevelIterations           = iterator;
                    solution.customer_LSCycle_iterations       = newSolution.customer_LSCycle_iterations;
                    solution.customer_twoOpt_iterations        = newSolution.customer_twoOpt_iterations;
                    solution.customer_relocate_iterations      = newSolution.customer_relocate_iterations;
                    solution.customer_exchange_iterations      = newSolution.customer_exchange_iterations;
                    solution.customer_swapCustomers_iterations = newSolution.customer_swapCustomers_iterations;

                    solution.customer_LSCycleTime        = newSolution.customer_LSCycleTime;
                    solution.customer_twoOpt_time        = newSolution.customer_twoOpt_time;
                    solution.customer_relocate_time      = newSolution.customer_relocate_time;
                    solution.customer_exchange_time      = newSolution.customer_exchange_time;
                    solution.customer_swapCustomers_time = newSolution.customer_swapCustomers_time;
                }

                // Increace iterator
                iterator++;
            }

            //End
            return;
        }
예제 #9
0
        /*
         *
         *  Create a complete Greedy Randomized Solution (with cluster and customers)
         *
         */
        private CluVRPSolution constructGreedyRandomizedSolution(double alpha)
        {
            // Init variables
            int[][]          originalClusters         = instance.clusters;
            List <int>[]     clusterRoute             = solution.clusterRouteForVehicule;
            List <int>[][]   customersCircuit         = new List <int> [clusterRoute.Length][];
            Tuple <int, int> customersConnectClusters = new Tuple <int, int>(0, 0);

            double[] vehiculeTotalDistance = new double[instance.vehicles];

            // Start from depot
            int startingCustomer = 1;

            int[][][] clusterRouteWithCustomers = this.clusterRouteWithCustomers(originalClusters, clusterRoute);

            // For each vehicule cluster-route
            for (int vehicle = 0; vehicle < clusterRoute.Length; vehicle++)
            {
                // For each cluster in the i-vehicle route
                int     numbersOfClusters  = clusterRoute[vehicle].Count;
                int[][] clustersOneVehicle = clusterRouteWithCustomers[vehicle];
                customersCircuit[vehicle] = new List <int> [numbersOfClusters];

                // If vehicle has not travel
                if (clusterRoute[vehicle].Count == 2)
                {
                    customersCircuit[vehicle]    = new List <int> [2];
                    customersCircuit[vehicle][0] = new List <int>();
                    customersCircuit[vehicle][1] = new List <int>();
                    customersCircuit[vehicle][0].Add(1);
                    customersCircuit[vehicle][1].Add(1);
                    vehiculeTotalDistance[vehicle] = 0;
                    continue;
                }

                // Visit all cluster for the i-vehicle
                for (int i = 0; i < numbersOfClusters; i++)
                {
                    // Add actual (initial of cluster) customer
                    customersCircuit[vehicle][i] = new List <int>();
                    customersCircuit[vehicle][i].Add(startingCustomer);

                    // For best customer to conect actual cluster to the next
                    // If the cluster only has 1 customer, you only have to know the
                    // customer for the next cluster
                    if (i + 1 < numbersOfClusters && clustersOneVehicle[i].Length > 1)
                    {
                        customersConnectClusters = bestCustomersBetween2Clusters(clustersOneVehicle[i], clustersOneVehicle[i + 1], startingCustomer);
                    }
                    else if (i + 1 < numbersOfClusters && clustersOneVehicle[i].Length == 1)
                    {
                        int nextCustomer = bestNextCustomer(startingCustomer, clustersOneVehicle[i + 1]);
                        customersConnectClusters = new Tuple <int, int>(startingCustomer, nextCustomer);
                    }

                    // Convert array to list
                    List <int> customersToVisit = clustersOneVehicle[i].OfType <int>().ToList();

                    // Remove initial and final customers
                    customersToVisit.Remove(startingCustomer);
                    customersToVisit.Remove(customersConnectClusters.Item1);

                    // While exists customers to visit
                    while (customersToVisit.Count > 0)
                    {
                        // Create RCL for customer
                        List <int> customerRCL = buildCustomerRCL(startingCustomer, customersToVisit, alpha);

                        // Select customer for RCL
                        int customerSelected = Functions.selectRandomElement(customerRCL);

                        // Add customer to the path
                        customersCircuit[vehicle][i].Add(customerSelected);

                        // Quit visited customer
                        customersToVisit.Remove(customerSelected);

                        // Set new actual customer
                        startingCustomer = customerSelected;
                    }

                    // Add final customer that connect to i+1 cluster
                    // In the final cluster the next customer is 0
                    // the it has not be added
                    if (clustersOneVehicle[i].Length > 1 && i + 1 < numbersOfClusters)
                    {
                        customersCircuit[vehicle][i].Add(customersConnectClusters.Item1);
                    }

                    // Next customer of next cluster
                    startingCustomer = customersConnectClusters.Item2;
                }

                // Calculte total inter-cluster distance
                vehiculeTotalDistance[vehicle] = Functions.calculateTotalTravelDistance(customersCircuit, instance.customersDistanceMatrix, vehicle);
            }

            // Set solution
            CluVRPSolution newSolution = new CluVRPSolution(instance);

            newSolution.setCostumerSolution(customersCircuit, vehiculeTotalDistance);

            // Return solution
            return(newSolution);
        }
예제 #10
0
        // Main Function
        static void GraspProcedure(string parametersFilePath, string instanceSetFilePath, string logFilePath, double[] solutionToCompare, CluVRPVersion cluVRPVersion)
        {
            // Star watch to calculate total process time
            var totalWatch = System.Diagnostics.Stopwatch.StartNew();

            // For watch for each instance execution
            long elapsedMs = 0;

            // Number of instances
            int instancesNumber = solutionToCompare.Length;

            // For best results
            Dictionary <CluVRPInstance, CluVRPSolution> bestSolutionForInstance = new Dictionary <CluVRPInstance, CluVRPSolution>();
            CluVRPSolution solution;

            double[] bestSolutionTotalDistance = new double[instancesNumber];
            double[] bestSolutionPropDistance  = new double[instancesNumber];
            double[] bestSolutionTime          = new double[instancesNumber];
            Functions.Populate(bestSolutionTotalDistance, double.MaxValue);
            string[] bestSolutionParameters = new string[instancesNumber];

            // For Average results
            double[] totalDistance           = new double[instancesNumber];
            double[] totalTime               = new double[instancesNumber];
            double[] solutionAvgPropDistance = new double[instancesNumber];
            int[]    instanceOKsolutions     = new int[instancesNumber];

            // Get parameters to run instances
            List <Parameters> parametersList = Parameters.parseParameterFile(parametersFilePath);

            // Get logger
            Logger logger = Logger.GetInstance();

            // To logger verbose on/off
            logger.setVerbose(false);
            logger.setLogFilePath(logFilePath);

            // Get instances
            CluVRPInstance[] instancias = InstanceParser.loadGVRPSetOfInstances(instanceSetFilePath);

            // Log run
            logger.logLine("*****************************************************" + '\n' +
                           "* STARTING TEST:" + '\n' +
                           "* DATE -> " + DateTime.Now.ToString() + '\n' +
                           "* CONFIG -> " + parametersFilePath + '\n' +
                           "* SET INSTANCE -> " + instanceSetFilePath + '\n' +
                           "* LOG FILE -> " + logger.getLogFilePath() + '\n' +
                           "*****************************************************" + '\n');

            // For each instance
            int instanceIterator = 0;

            foreach (CluVRPInstance instance in instancias)
            {
                // For this instance
                double distance;

                // Create new solution
                solution = new CluVRPSolution(instance);

                // For each parameter configuration
                foreach (Parameters parameters in parametersList)
                {
                    // Star watch to calculate time
                    var watch = System.Diagnostics.Stopwatch.StartNew();

                    // If CluVRP_Version in parameters is None(3) it has to be taken from command line
                    if (parameters.CluVRP_Version == CluVRPVersion.None)
                    {
                        parameters.CluVRP_Version = cluVRPVersion;
                    }

                    // Actual Parameter
                    string actualParameters = Functions.parametersToString(parameters);
                    //logger.logLine(actualParameters);

                    // Calculate solution for normal CluVRP or weak cluster constrains
                    solution = CluVRPGrasp.Grasp(instance, parameters);

                    // If not possible solution
                    if (solution.clusterRouteForVehicule == null)
                    {
                        continue;
                    }

                    // Increase instance OK solution iteration
                    instanceOKsolutions[instanceIterator]++;

                    // For this instance solution
                    distance = solution.totalCustomerRouteDistance;

                    // Izquierdo instances results are not integers
                    if (instance.instance_type == Instance.GoldenIzquierdo)
                    {
                        distance = Math.Truncate(100 * distance) / 100;
                    }
                    else
                    {
                        distance = Math.Truncate(distance);
                    }

                    // Stop timer watchers
                    watch.Stop();

                    // Set execution time
                    elapsedMs = watch.ElapsedMilliseconds;
                    double elapsedSeconds = Math.Round(elapsedMs * 1.0 / 1000, 2);

                    // Update solution results
                    totalDistance[instanceIterator] += distance;
                    totalTime[instanceIterator]     += elapsedSeconds;

                    // Update individual instance solution
                    if (distance < bestSolutionTotalDistance[instanceIterator])
                    {
                        bestSolutionTotalDistance[instanceIterator] = distance;
                        bestSolutionPropDistance[instanceIterator]  = (distance - solutionToCompare[instanceIterator]) * 100 / solutionToCompare[instanceIterator];
                        bestSolutionPropDistance[instanceIterator]  = Math.Truncate(100 * bestSolutionPropDistance[instanceIterator]) / 100;
                        bestSolutionParameters[instanceIterator]    = actualParameters;
                        bestSolutionTime[instanceIterator]          = elapsedSeconds;
                        bestSolutionForInstance[instance]           = solution;
                    }
                }

                // Calculate averages
                double averageDistance = totalDistance[instanceIterator] / instanceOKsolutions[instanceIterator];
                double averageTime     = totalTime[instanceIterator] / instanceOKsolutions[instanceIterator];
                averageTime = Math.Round(averageTime, 2);
                double averagePropDistance = (averageDistance - solutionToCompare[instanceIterator]) * 100 / solutionToCompare[instanceIterator];
                averagePropDistance = Math.Truncate(100 * averagePropDistance) / 100;
                bestSolutionPropDistance[instanceIterator] = Math.Truncate(100 * bestSolutionPropDistance[instanceIterator]) / 100;
                solutionAvgPropDistance[instanceIterator]  = averagePropDistance;

                // For log solution
                string s_distance;
                string s_averageDistance;
                string s_bestSolutionPropDistance = bestSolutionPropDistance[instanceIterator].ToString("0.00");
                string s_bestSolutionTime         = bestSolutionTime[instanceIterator].ToString("0.00");
                string s_averagePropDistance      = averagePropDistance.ToString("0.00");
                string s_averageTime = averageTime.ToString("0.00");
                string s_fileName    = Path.GetFileName(instancias[instanceIterator].file_name);
                if (instance.instance_type == Instance.GoldenIzquierdo)
                {
                    s_distance        = bestSolutionTotalDistance[instanceIterator].ToString("0.00");
                    s_averageDistance = averageDistance.ToString("0.00");
                }
                else
                {
                    s_distance        = bestSolutionTotalDistance[instanceIterator].ToString("0");
                    s_averageDistance = averageDistance.ToString("0");
                }

                // Print solution
                string outLine = s_fileName + '\t' + '\t' + s_distance + '\t' + s_bestSolutionPropDistance + "%" + '\t' + s_bestSolutionTime + "s" + '\t' + '\t' + s_averageDistance + '\t' + s_averagePropDistance + "%" + '\t' + s_averageTime + "s";
                logger.logLine(outLine);
                logger.logTimeAndIterations(solution, instance.file_name);

                // Increase distance counter
                instanceIterator++;
            }

            // Stop timer watchers
            totalWatch.Stop();
            var totalElapsedseconds = totalWatch.ElapsedMilliseconds / 1000;

            // Total values
            string s_totalPropBestDistance = (bestSolutionPropDistance.Sum() / instancesNumber).ToString("0.00");
            string s_totalPropAvgDistance  = (solutionAvgPropDistance.Sum() / instancesNumber).ToString("0.00");

            // Show parameters for best solution
            logger.logLine("");
            logger.logLine("*************************************");
            logger.logLine("* PARAMETERS FOR BEST SOLUTIONS:    *");
            logger.logLine("*************************************");
            logger.logLine("TOTAL TIME -> " + totalElapsedseconds + " seconds");
            logger.logLine("TOTAL BEST PROP DISTANCE -> " + s_totalPropBestDistance + "%");
            logger.logLine("TOTAL AVG PROP DISTANCE -> " + s_totalPropAvgDistance + "%");
            logger.logLine("");
            for (int i = 0; i < bestSolutionParameters.Length; i++)
            {
                logger.logLine("-----------------------------------------------------------------");
                logger.logLine("");
                logger.logLine("CONFIGURATION FOR INSTANCE " + i);
                logger.logLine("*****************************");
                logger.logLine(bestSolutionParameters[i].ToString());
            }

            // Draw PNG solution
            foreach (CluVRPInstance instance in bestSolutionForInstance.Keys)
            {
                //CluVRPSolution.solutionDrawPythonCode(instance, bestSolutionForInstance[instance]);
            }

            // Pause
            //System.Console.ReadKey();

            // End
            return;
        }
예제 #11
0
        // Main Function
        static void GraspProcedureCycleParameters(string parametersFilePath, string instanceSetFilePath, string logFilePath, double[] solutionToCompare)
        {
            // Star watch to calculate total process time
            var totalWatch = System.Diagnostics.Stopwatch.StartNew();

            // For watch for each instance execution
            long elapsedMs = 0;

            // For best solution set
            Dictionary <CluVRPInstance, CluVRPSolution> bestSolutionForInstance = new Dictionary <CluVRPInstance, CluVRPSolution>();
            CluVRPSolution solution;

            double[] bestIndividualTotalDistance = new double[solutionToCompare.Length];
            double[] bestIndividualPropDistance  = new double[solutionToCompare.Length];
            double[] bestIndividualTime          = new double[solutionToCompare.Length];
            Functions.Populate(bestIndividualTotalDistance, double.MaxValue);
            string[] bestIndividualParameteres = new string[solutionToCompare.Length];
            double[] bestSolPropDistances      = new double[solutionToCompare.Length];
            Functions.Populate(bestSolPropDistances, double.MaxValue);
            double[] bestSolDistances = new double[solutionToCompare.Length];
            double[] bestSolTimes     = new double[solutionToCompare.Length];
            List <List <LocalSearch> > bestSolClusterLSOrder  = new List <List <LocalSearch> >();
            List <List <LocalSearch> > bestSolCustomerLSOrder = new List <List <LocalSearch> >();
            string bestSolParameters = "";
            double totalAvg          = double.MaxValue;
            double totalAvgTime      = double.MaxValue;

            // Get parameters to run instances
            List <Parameters> parametersList = Parameters.parseParameterFile(parametersFilePath);

            // Get logger
            Logger logger = Logger.GetInstance();

            // To logger verbose on
            logger.setVerbose(true);
            logger.setLogFilePath(logFilePath);

            // Get instances
            CluVRPInstance[] instancias = InstanceParser.loadGVRPSetOfInstances(instanceSetFilePath);

            // Log run
            logger.logLine("*****************************************************" + '\n' +
                           "* STARTING TEST:" + '\n' +
                           "* CONFIG -> " + parametersFilePath + '\n' +
                           "* SET INSTANCE -> " + instanceSetFilePath + '\n' +
                           "* LOG FILE -> " + logger.getLogFilePath() + '\n' +
                           "******************************************************" + '\n');


            // For each parameter configuration
            foreach (Parameters parameters in parametersList)
            {
                // String for parameter set and print
                logger.logLine("=============================================" + '\n' +
                               "=       EXECUTING NEW TEST CASE             =" + '\n' +
                               "=============================================" + '\n');
                string actualParameters = Functions.parametersToString(parameters);
                logger.logLine(actualParameters);

                // For this configuration run
                double[] propDistances = new double[solutionToCompare.Length];
                double[] distances     = new double[solutionToCompare.Length];
                double[] times         = new double[solutionToCompare.Length];
                List <List <LocalSearch> > LSClusterOrder  = new List <List <LocalSearch> >();
                List <List <LocalSearch> > LSCustomerOrder = new List <List <LocalSearch> >();

                // For each instance
                int instanceCounter = 0;
                foreach (CluVRPInstance instance in instancias)
                {
                    // Star watch to calculate time
                    var watch = System.Diagnostics.Stopwatch.StartNew();

                    // Set max distance value
                    double distance       = 0;
                    string fitAlgoBestSol = "";

                    // Create a new solution
                    solution = new CluVRPSolution(instance);

                    // Calculate solution for normal CluVRP or weak cluster constrains
                    solution = CluVRPGrasp.Grasp(instance, parameters);

                    // If not possible solution
                    if (solution.clusterRouteForVehicule == null)
                    {
                        logger.logLine(instance.file_name + '\t' + "No solution for this instance");
                        propDistances[instanceCounter] = 10;
                        instanceCounter++;
                        continue;
                    }

                    // Sets strings to show - FOR DEBUG
                    string s1 = instance.file_name + '\t' + solution.totalCustomerRouteDistance + '\t' +
                                parameters.Cluster_AlphaCapacity + '\t' + parameters.Cluster_AlphaDistance + '\t';
                    //Console.WriteLine(s1);

                    // For this instance solution
                    distance = solution.totalCustomerRouteDistance;
                    //solution.customersPaths[0][5][0] = 20;
                    //solution.customersPaths[0][5][1] = 19;
                    //distance = Functions.calculateTotalTravelDistance(solution.customersPaths, instance.customersDistanceMatrix);
                    if (instance.instance_type == Instance.GoldenIzquierdo)
                    {
                        distance = Math.Truncate(100 * distance) / 100;
                    }
                    else
                    {
                        distance = Math.Truncate(distance);
                    }
                    LSClusterOrder.Add(solution.bestClusterLSOrder);
                    LSCustomerOrder.Add(solution.bestCustomerLSOrder);

                    // Stop timer watchers
                    watch.Stop();

                    // Set execution time
                    elapsedMs = watch.ElapsedMilliseconds;
                    double elapsedSeconds = Math.Round(elapsedMs * 1.0 / 1000, 2);

                    // Update solution results
                    distances[instanceCounter]     = distance;
                    propDistances[instanceCounter] = (distance - solutionToCompare[instanceCounter]) * 100 / solutionToCompare[instanceCounter];
                    propDistances[instanceCounter] = Math.Truncate(100 * propDistances[instanceCounter]) / 100;
                    times[instanceCounter]         = elapsedSeconds;

                    // Update individual instance solution
                    if (distances[instanceCounter] < bestIndividualTotalDistance[instanceCounter])
                    {
                        bestIndividualTotalDistance[instanceCounter] = distances[instanceCounter];
                        bestIndividualPropDistance[instanceCounter]  = (distance - solutionToCompare[instanceCounter]) * 100 / solutionToCompare[instanceCounter];
                        bestIndividualPropDistance[instanceCounter]  = Math.Truncate(100 * bestIndividualPropDistance[instanceCounter]) / 100;
                        bestIndividualParameteres[instanceCounter]   = actualParameters;
                        bestIndividualTime[instanceCounter]          = elapsedSeconds;
                        bestSolutionForInstance[instance]            = solution;
                    }

                    // Log solution
                    string s_distance;
                    if (instance.instance_type == Instance.GoldenIzquierdo)
                    {
                        s_distance = distance.ToString("0.00");
                    }
                    else
                    {
                        s_distance = distance.ToString("0");
                    }
                    string outLine = instance.file_name + '\t' + s_distance + '\t' + propDistances[instanceCounter] + "%" + '\t' + (elapsedMs * 1.0 / 1000).ToString("0.00") + "s" + '\t' + fitAlgoBestSol;
                    logger.logLine(outLine);

                    // Increase distance counter
                    instanceCounter++;
                }

                // Show total final proporcional differente and times
                totalAvg     = Math.Truncate(100 * propDistances.Sum() / propDistances.Length) / 100;
                totalAvgTime = Math.Truncate(100 * times.Sum() / times.Length) / 100;
                logger.logLine("");
                logger.logLine("####################################");
                logger.logLine("# TOTAL PROP DIFFERENCE -> " + totalAvg);
                logger.logLine("# TOTAL TIME -> " + times.Sum().ToString("0.00"));
                logger.logLine("# TOTAL AVERAGE TIME -> " + totalAvgTime.ToString("0.00"));
                logger.logLine("####################################");

                // Compare best AVG
                if (propDistances.Sum() < bestSolPropDistances.Sum())
                {
                    // Update to new best set solution
                    bestSolPropDistances   = propDistances;
                    bestSolParameters      = actualParameters;
                    bestSolDistances       = distances;
                    bestSolTimes           = times;
                    bestSolClusterLSOrder  = LSClusterOrder;
                    bestSolCustomerLSOrder = LSCustomerOrder;
                    totalAvg     = Math.Truncate(100 * bestSolPropDistances.Sum() / bestSolPropDistances.Length) / 100;
                    totalAvgTime = Math.Truncate(100 * bestSolTimes.Sum() / bestSolTimes.Length) / 100;
                    bestSolTimes = times;

                    // Show AVG distance
                    logger.logLine("");
                    logger.logLine("-----------------------------------------------------------------------");
                    logger.logLine("-------------------------NEW BEST DISTANCE-----------------------------");
                    logger.logLine("-----------------------------------------------------------------------");
                    //logger.logLine("NEW PROPORTIONAL BEST SET DISTANCE -> " + bestSolPropDistances.Sum());
                    logger.logLine("DISTANCES -> " + Functions.arrayToString(bestSolDistances));
                    logger.logLine("PROP DISTANCES -> " + Functions.arrayToString(bestSolPropDistances));
                    logger.logLine("TOTAL AVERAGE DIFERENCE DISTANCE -> " + totalAvg);
                    logger.logLine("TOTAL AVERAGE TIME -> " + totalAvgTime);
                    logger.logLine("-----------------------------------------------------------------------");
                    logger.logLine("-----------------------------------------------------------------------");
                    logger.logLine("-----------------------------------------------------------------------");
                }

                // New line for new config
                logger.logLine("");
            }

            // Stop timer watchers
            totalWatch.Stop();
            var totalElapsedseconds = totalWatch.ElapsedMilliseconds / 1000;

            // Log best solution
            logger.logLine("");
            logger.logLine("******************");
            logger.logLine("* BEST SOLUTION: *");
            logger.logLine("******************");
            logger.logLine("TOTAL TIME -> " + totalElapsedseconds + " seconds");
            //logger.logLine("PROPORTIONAL BEST SET DISTANCE -> " + bestSolPropDistances.Sum());
            //logger.logLine("DISTANCES -> " + Functions.arrayToString(bestSolDistances));
            //logger.logLine("PROPORTIONA DIFF DISTANCES -> " + Functions.arrayToString(bestSolPropDistances));
            totalAvg     = Math.Truncate(100 * bestSolPropDistances.Sum() / bestSolPropDistances.Length) / 100;
            totalAvgTime = Math.Truncate(100 * bestSolTimes.Sum() / bestSolTimes.Length) / 100;
            logger.logLine("TOTAL AVERAGE DIFERENCE DISTANCE -> " + totalAvg);
            logger.logLine("TOTAL AVERAGE TIME -> " + totalAvgTime);
            logger.logLine("");
            logger.logLine("LIST OF RESULTS");
            logger.logLine("***************");
            for (int i = 0; i < bestSolDistances.Length; i++)
            {
                string outLine = instancias[i].file_name + '\t' + bestSolDistances[i] + '\t' + bestSolPropDistances[i] + "%" + '\t' + bestSolTimes[i];
                logger.logLine(outLine);
            }
            logger.logLine("");
            logger.logLine("PARAMETERS: ");
            logger.logLine("***********");
            logger.logLine(bestSolParameters);
            logger.logLine("CLUSTER LS ORDER:");
            logger.logLine("*****************");
            for (int i = 0; i < bestSolClusterLSOrder.Count; i++)
            {
                logger.logLine((Functions.arrayToString(bestSolClusterLSOrder[i])));
            }
            logger.logLine("");
            logger.logLine("CUSTOMER LS ORDER:");
            logger.logLine("******************");
            for (int i = 0; i < bestSolCustomerLSOrder.Count; i++)
            {
                logger.logLine((Functions.arrayToString(bestSolCustomerLSOrder[i])));
            }
            logger.logLine("");
            logger.logLine("");
            logger.logLine("============================");
            logger.logLine("= BEST INDIVIDUAL RESULTS =:");
            logger.logLine("============================");
            totalAvg     = Math.Truncate(100 * bestIndividualPropDistance.Sum() / bestIndividualPropDistance.Length) / 100;
            totalAvgTime = Math.Truncate(100 * bestIndividualTime.Sum() / bestIndividualTime.Length) / 100;
            //logger.logLine("DISTANCES -> " + Functions.arrayToString(bestIndividualTotalDistance));
            //logger.logLine("PROPORTIONA DIFF DISTANCES -> " + Functions.arrayToString(bestIndividualPropDistance));
            //logger.logLine("PROPORTIONAL TOTAL DISTANCE -> " + bestIndividualPropDistance.Sum().ToString("00.00"));
            logger.logLine("TOTAL AVERAGE DIFERENCE DISTANCE -> " + totalAvg);
            logger.logLine("TOTAL AVERAGE TIME -> " + totalAvgTime);
            logger.logLine("");
            logger.logLine("LIST OF RESULTS");
            logger.logLine("***************");
            for (int i = 0; i < bestIndividualTotalDistance.Length; i++)
            {
                string outLine = instancias[i].file_name + '\t' + bestIndividualTotalDistance[i] + '\t' + bestIndividualPropDistance[i] + "%" + '\t' + bestIndividualTime[i];
                logger.logLine(outLine);
            }
            logger.logLine("");
            for (int i = 0; i < bestSolClusterLSOrder.Count; i++)
            {
                logger.logLine("-----------------------------------------------------------------");
                logger.logLine("");
                logger.logLine("CONFIGURATION FOR INSTANCE " + i);
                logger.logLine("*****************************");
                logger.logLine(bestIndividualParameteres[i].ToString());
            }

            foreach (CluVRPInstance instance in bestSolutionForInstance.Keys)
            {
                CluVRPSolution.solutionDrawPythonCode(instance, bestSolutionForInstance[instance]);
            }

            // Pause
            //System.Console.ReadKey();

            // End
            return;
        }
예제 #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
        // 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;
        }
예제 #14
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);
        }
예제 #15
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;
        }