/*
         *
         *  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);
        }
        /*
         *
         * 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;

            // Create a customer path for each vehicle
            List <int>[] customersOnVehicle = buildCustomersOnVehicle();

            // 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(customersOnVehicle, alpha);

                // Local search
                var    totalLSWatch  = System.Diagnostics.Stopwatch.StartNew();
                double routeDistance = newSolution.totalCustomerRouteDistance;
                for (int i = 0; i < 1; i++)
                {
                    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.setWeakCostumerSolution(newSolution.customersWeakRoute, newSolution.vehiculeRouteDistance);
                    solution.bestCustomerLSOrder = localSearchsOrder;

                    solution.customerLevelIterations           = iterator;
                    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;
        }