예제 #1
0
        public void ExecuteMetaheuristic(ref Solution bestSolution)
        {
            ShiftInter            = 0;
            IntraRouteInsertionOP = 0;
            WRI_IntraOP           = 0;
            IntraSwap             = 0;

            Debug.WriteLine("\n\nNueva búsuqeda: ");
            bool ls1 = true;
            bool ls2 = true;
            bool ls3 = true;
            bool ls4 = true;

            while (ls1 || ls2 || ls3 || ls4)
            {
                List <int> localInternal = Enumerable.Range(0, 3).ToList();
                do
                {
                    var variable = localInternal[_random.Next(0, localInternal.Count)];
                    switch (variable)
                    {
                    case 0:
                        ls1 = WRI_Intra(ref bestSolution);
                        localInternal.Remove(0);
                        break;

                    case 1:
                        ls3 = IntraRouteInsertion(ref bestSolution);
                        localInternal.Remove(1);
                        break;

                    case 2:
                        ls4 = Swap_Intra(ref bestSolution);
                        localInternal.Remove(2);
                        break;
                    }
                }while (localInternal.Count > 0);
                //ls4 = Swap_Intra(ref bestSolution);
                //ls1 = WRI_Intra(ref bestSolution);
                ls2 = Shift1_0Inter(ref bestSolution);
                //ls3 = IntraRouteInsertion(ref bestSolution);
                //ls1 = false;
                //ls2 = false;
                //ls3 = false;
                //ls4 = false;
            }



            DARPAlgorithms.UpdateConstraintsSolution(ref bestSolution, _problem);
            CheckFesiability(ref bestSolution);
        }
예제 #2
0
        public static List <Solution> Optimization(RunMetaheuristicInput input)
        {
            var problems = input.Problems;

            //Set randomized value.
            _random = input.Random;
            List <Solution> Solutions = new List <Solution>();

            var default_Metaheuristic = Constants.TypeMetaheuristics.ILS;

            IMetaheuristic metaheuristic = MetaheuristicFactory.CreateMetaheuristic(default_Metaheuristic, input.HeuristicSettings, input.Problems.First(), input.Random);



            //Ejecutar cada problema.
            foreach (var problem in problems)
            {
                //Primer paso. Preprocesar los problemas (ajustar ventanas de tiempo cuando sea posible).
                SplashGlobalData.SetSplashData(Constants.SPLASH_NAME_PROBLEM, problem.ID_Problem);
                SplashGlobalData.SetSplashData(Constants.SPLASH_PROGRESS, 0.0);
                //Create Solution
                for (int number_Repetition = 0; number_Repetition < input.HeuristicSettings.MaxRepetitions; number_Repetition++)
                {
                    var      watch    = System.Diagnostics.Stopwatch.StartNew();
                    Solution solution = new Solution(problem.ID_Problem);
                    DARPAlgorithms.BuildInitialSolution(ref solution, problem, ref _random);
                    solution.InitialSolution = GenericCopier <Solution> .DeepCopy(solution);

                    //Update Splash.
                    SplashGlobalData.SetSplashData(Constants.SPLASH_NUMBER_REPETITION, number_Repetition + 1);
                    SplashGlobalData.SetSplashData(Constants.SPLASH_PROGRESS, Convert.ToDouble(SplashGlobalData.GetSplashData <double>(Constants.SPLASH_PROGRESS)) + 1);

                    //Execute Heuristic
                    metaheuristic.ExecuteMetaheuristic(ref solution);
                    watch.Stop();
                    solution.ExecutionTime = watch.ElapsedMilliseconds;
                    Solutions.Add(solution);
                    //Validation.Validator.ValidateSolution(ref solution, problem);
                }
            }

            return(Solutions);
        }
예제 #3
0
        public void ExecuteMetaheuristic(ref Solution bestSolution)
        {
            int      bestIteration   = 0;
            Solution partialSolution = GenericCopier <Solution> .DeepCopy(bestSolution);

            int            control_Diversify = 0;
            SummaryDetails summary           = new SummaryDetails();

            Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_BEST_SOLUTION, bestSolution.Fitness);
            double pertCost = 0, vnsCost = 0;

            int iterations = 0;

            //Guardar coste inicial.
            summary.ILSSummary.InitCost = bestSolution.Parc_Cost;
            for (int i = 0; iterations < _ilsSettings.MaxILSIterations && i < _ilsSettings.MaxILSNoImprovement; i++)
            {
                //Control de intensificación-diversificación.
                if (i % _DIVERSIFY_MAX == 0)
                {
                    _diversify--;
                }
                _diversify = _diversify < 3 ? 3 : _diversify;
                if (i % 100 == 0)
                {
                    _diversify = _DIVERSIFY_MAX;
                }
                //Guardar valores estadísticos.
                var initCost    = partialSolution.Parc_Cost;
                var initFitness = partialSolution.Fitness;

                Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_ILS_TOTAL_ITERATIONS, iterations + 1);
                //Apply VNS local search.
                _vns.ExecuteMetaheuristic(ref partialSolution);


                //Validator.ValidateSolution(ref partialSolution, _problem);
                bool feasible = partialSolution.Feasible;
                //Guardar valores estadísticos.
                vnsCost = Costs.ParcialCostSolution(partialSolution, _problem); // partialSolution.Parc_Cost;
                var vnsFitness = partialSolution.Fitness;

                if (vnsFitness < initFitness)
                {
                    summary.ILSSummary.TotalImpPrevious++; //Incrementar el número de veces que se mejora la solución previa (perturbada).
                }
                if (bestSolution.Feasible)
                {
                    if (partialSolution.Feasible && (Math.Round(partialSolution.Fitness, 2) < Math.Round(bestSolution.Fitness, 2)))
                    {
                        bestSolution = GenericCopier <Solution> .DeepCopy(partialSolution);

                        //Actualizar la mejor solución con los nuevos parámetros.
                        control_Diversify = 0;
                        bestIteration     = i;
                        i          = 0;
                        _diversify = _DIVERSIFY_MAX;
                        summary.ILSSummary.BestIteration = iterations + 1; //Guardar mejor iteración encontrada.
                        summary.ILSSummary.TotalImpBest++;                 //Incrementar el número de veces que se mejora la mejor solución.
                        Singleton.Instance.UpdatePenaltyTerms(partialSolution);
                        Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_ILS_IMPROVEMENTS, summary.ILSSummary.TotalImpBest);
                        Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_BEST_SOLUTION, Math.Round(bestSolution.Fitness, 2));
                    }
                    else
                    {
                        control_Diversify++;
                    }
                }
                else
                {
                    if (partialSolution.Feasible || Math.Round(partialSolution.Fitness, 2) < Math.Round(bestSolution.Fitness, 2))
                    {
                        if (partialSolution.Feasible && summary.ILSSummary.FirstItFeasible == null)
                        {
                            summary.ILSSummary.FirstItFeasible = iterations + 1; //Guardar primera iteración factible.
                        }
                        bestSolution = GenericCopier <Solution> .DeepCopy(partialSolution);

                        control_Diversify = 0;
                        i          = 0;
                        _diversify = _DIVERSIFY_MAX;
                        summary.ILSSummary.BestIteration = iterations + 1; //Guardar mejor iteración encontrada.
                        summary.ILSSummary.TotalImpBest++;                 //Incrementar el número de veces que se mejora la mejor solución.
                        Singleton.Instance.UpdatePenaltyTerms(partialSolution);
                        //bestSolution.Fitness = Costs.EvaluationSolution(bestSolution, _problem);
                        Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_ILS_IMPROVEMENTS, summary.ILSSummary.TotalImpBest);
                        Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_BEST_SOLUTION, bestSolution.Fitness);
                    }
                    else
                    {
                        control_Diversify++;
                    }
                }

                if (control_Diversify > _diversify)
                {
                    partialSolution = GenericCopier <Solution> .DeepCopy(bestSolution);

                    control_Diversify = 0;
                }

                var perturbation = _perturbations.ExecutePerturbation(ref partialSolution);
                //Guardar valores estadísticos.
                pertCost = partialSolution.Parc_Cost;
                var pertFitness = partialSolution.Fitness;

                //Añadir resumen de la iteración.
                summary.VNSOperators.Add(new VNSOperators(iterations, _vns.ShiftInter, 0, _vns.WRI_IntraOP, _vns.IntraRouteInsertionOP, _vns.IntraSwap));
                summary.ILSEvolution.Add(new ILSEvolution(iterations, Math.Round(initCost, 2), Math.Round(initFitness, 2), Math.Round(vnsCost, 2), Math.Round(vnsFitness, 2), perturbation, Math.Round(pertFitness, 2), Math.Round(pertCost, 2), feasible));
                Splash.SplashGlobalData.SetSplashData(Constants.SPLASH_PROGRESS, Convert.ToDouble(Splash.SplashGlobalData.GetSplashData <double>(Constants.SPLASH_PROGRESS)) + _coef_Updater_Splash);
                //Guardar cambios de cada operador.



                iterations++;
            }

            //Recalcular con el proceso de 8 pasos y actualizar el coste.
            foreach (var vehicle in bestSolution.Vehicles)
            {
                DARPAlgorithms.EightStepsEvaluationProcedure(ref bestSolution, vehicle, _problem);
            }
            bestSolution.TotalDuration       = bestSolution.Vehicles.Sum(t => t.VehicleDuration);
            bestSolution.TimeWindowViolation = bestSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
            bestSolution.RideTimeViolation   = bestSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
            bestSolution.DurationViolation   = bestSolution.Vehicles.Sum(d => d.TotalDurationViolation);
            bestSolution.LoadViolation       = bestSolution.Vehicles.Sum(l => l.TotalLoadViolation);
            bestSolution.TotalWaitingTime    = bestSolution.Vehicles.Sum(t => t.TotalWaitingTime);
            DARPAlgorithms.UpdateConstraintsSolution(ref bestSolution, _problem);
            bestSolution.Fitness   = Costs.EvaluationSolution(bestSolution, _problem);
            bestSolution.Parc_Cost = Costs.ParcialCostSolution(bestSolution, _problem);

            summary.ILSSummary.TotalIterations = iterations + 1;
            summary.ILSSummary.FinalCost       = bestSolution.Parc_Cost;


            bestSolution.SummaryDetails = summary;
        }
예제 #4
0
        private void ShiftPerturbation(ref Solution solution)
        {
            int v1 = -1, v2 = -1;

            //marcar todos los vehículos como no perturbados.
            solution.Vehicles = solution.Vehicles.Select(t => { t.Perturbed = true; return(t); }).ToList();

            //Recorrer todos los vehículos
            //for (int v = 0; v < solution.Vehicles.Count; v++)
            //{
            //Seleccionar el primer vehículo.
            do
            {
                v1 = _random.Next(0, PerturbationMechanism.Keys.Count);
            }while (solution.Vehicles[v1].Requests.Count <= 4);
            if (PerturbationMechanism[v1].Count == 0)
            {
                ResetPerturbationMechanism(false, v1);
            }

            do
            {
                v2 = PerturbationMechanism[v1][_random.Next(0, PerturbationMechanism[v1].Count)];
            }while (v1 == v2);

            //Seleccionar aleatoriamente un cliente de v1.
            List <Request> nodes = new List <Request>();

            var node             = solution.Vehicles[v1].Requests[_random.Next(1, solution.Vehicles[v1].Requests.Count - 1)];

            nodes = solution.Vehicles[v1].Requests.FindAll(t => t.PairID.Equals(node.PairID)); //Extraemos inicio y destino.

            //Siguiente paso. Insertarlos en su mejor posición posible.
            var origin         = nodes.Find(t => t.Origin == true);
            int posOrigin      = solution.Vehicles[v1].Requests.IndexOf(origin);
            var destination    = nodes.Find(t => t.Origin == false);
            int posDestination = solution.Vehicles[v1].Requests.IndexOf(destination);

            if (solution.Vehicles[v2].Requests.Count == 2)
            {
                solution.Vehicles[v2].Requests.Insert(1, destination);
                solution.Vehicles[v2].Requests.Insert(1, origin);
            }
            else
            {
                solution.Vehicles[v1].Requests.RemoveAll(t => t.PairID.Equals(nodes.First().PairID)); //Los eliminamos de su ruta inicio.

                //Determinamos nodo crítico (será el primero a insertar).
                Request critical;
                Request notCritical;
                if (origin.IsCritical)
                {
                    critical    = origin;
                    notCritical = destination;
                }
                else
                {
                    critical    = destination;
                    notCritical = origin;
                }

                //Seleccionar posiciones en el vehículo v2

                Dictionary <int, int> bestPair = new Dictionary <int, int>();
                int    bestPosSource           = -1;
                double min = double.MaxValue;


                for (int pos = 1; pos < solution.Vehicles[v2].Requests.Count; pos++)
                {
                    double twDist = 0.0;
                    if (pos == 1)
                    {
                        if ((critical.TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[pos].ID_Unique]) > solution.Vehicles[v2].Requests[pos].TimeWindow.UpperBound)
                        {
                            continue;
                        }
                        twDist = CalculateDistance(critical, v2, pos, solution);
                    }
                    else if (pos == solution.Vehicles[v2].Requests.Count - 1)
                    {
                        if ((solution.Vehicles[v2].Requests[pos].TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[pos].ID_Unique]) > critical.TimeWindow.UpperBound)
                        {
                            continue;
                        }
                        twDist = CalculateDistance(critical, v2, pos - 1, solution);
                    }
                    else
                    {
                        if (((solution.Vehicles[v2].Requests[pos - 1].TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[pos - 1].ID_Unique]) > critical.TimeWindow.UpperBound) ||
                            (critical.TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[pos].ID_Unique]) > solution.Vehicles[v2].Requests[pos].TimeWindow.UpperBound)
                        {
                            continue;
                        }
                        twDist = (CalculateDistance(critical, v2, pos, solution) + CalculateDistance(critical, v2, pos - 1, solution)) / 2.0;
                    }
                    if (twDist < min)
                    {
                        bestPosSource = pos;
                        min           = twDist;
                    }
                }

                if (bestPosSource == -1) //Insertar en pos = 1;
                {
                    bestPosSource = 1;
                }

                solution.Vehicles[v2].Requests.Insert(bestPosSource, critical);

                int notCriticalPos = -1;

                min = double.MaxValue;
                //Insertar no crítico.
                if (critical.Origin)
                {
                    //De pos en adelante.
                    for (int init = bestPosSource + 1; init < solution.Vehicles[v2].Requests.Count; init++)
                    {
                        if ((solution.Vehicles[v2].Requests[init - 1].TimeWindow.LowerBound + _problem.Distances[solution.Vehicles[v2].Requests[init - 1].ID_Unique][notCritical.ID_Unique]) > notCritical.TimeWindow.UpperBound)
                        {
                            continue;
                        }
                        double twDist = 0.0;
                        if (init == solution.Vehicles[v2].Requests.Count)
                        {
                            if ((solution.Vehicles[v2].Requests[init - 1].TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[init - 1].ID_Unique]) > critical.TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(critical, v2, init - 1, solution);
                        }
                        else
                        {
                            if (((solution.Vehicles[v2].Requests[init - 1].TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[init - 1].ID_Unique]) > critical.TimeWindow.UpperBound) ||
                                (critical.TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[init].ID_Unique]) > solution.Vehicles[v2].Requests[init].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = (CalculateDistance(critical, v2, init, solution) + CalculateDistance(critical, v2, init - 1, solution)) / 2.0;
                        }
                        //var diff = Problem.EuclideanDistance(notCritical.TimeWindow.LowerBound, notCritical.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[init - 1].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[init - 1].TimeWindow.UpperBound);
                        if (twDist < min)
                        {
                            notCriticalPos = init;
                            min            = twDist;
                        }
                    }
                }
                else
                {
                    //De pos hacia atrás.
                    for (int init = bestPosSource; init > 0; init--)
                    {
                        if ((notCritical.TimeWindow.LowerBound + _problem.Distances[notCritical.ID_Unique][solution.Vehicles[v2].Requests[init].ID_Unique]) > solution.Vehicles[v2].Requests[init].TimeWindow.UpperBound)
                        {
                            continue;
                        }

                        //var diff = Problem.EuclideanDistance(notCritical.TimeWindow.LowerBound, notCritical.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[init].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[init].TimeWindow.UpperBound);
                        double twDist = 0.0;
                        if (init == 1)
                        {
                            if ((critical.TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[init].ID_Unique]) > solution.Vehicles[v2].Requests[init].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(critical, v2, init, solution);
                        }
                        else
                        {
                            if (((solution.Vehicles[v2].Requests[init - 1].TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[init - 1].ID_Unique]) > critical.TimeWindow.UpperBound) ||
                                (critical.TimeWindow.LowerBound + _problem.Distances[critical.ID_Unique][solution.Vehicles[v2].Requests[init].ID_Unique]) > solution.Vehicles[v2].Requests[init].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(critical, v2, init, solution);
                        }
                        if (twDist < min)
                        {
                            notCriticalPos = init;
                            min            = twDist;
                        }
                    }
                }

                solution.Vehicles[v2].Requests.Insert(notCriticalPos, notCritical);
            }
            //  }

            //Recalcular con el proceso de 8 pasos y actualizar el coste.
            foreach (var vehicle in solution.Vehicles)
            {
                DARPAlgorithms.EightStepsEvaluationProcedure(ref solution, vehicle, _problem);
            }
            solution.TotalDuration       = solution.Vehicles.Sum(t => t.VehicleDuration);
            solution.TimeWindowViolation = solution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
            solution.RideTimeViolation   = solution.Vehicles.Sum(r => r.TotalRideTimeViolation);
            solution.DurationViolation   = solution.Vehicles.Sum(d => d.TotalDurationViolation);
            solution.LoadViolation       = solution.Vehicles.Sum(l => l.TotalLoadViolation);
            solution.TotalWaitingTime    = solution.Vehicles.Sum(t => t.TotalWaitingTime);
            DARPAlgorithms.UpdateConstraintsSolution(ref solution, _problem);
            solution.Fitness = Costs.EvaluationSolution(solution, _problem);

            try
            {
                Validator.Positions(ref solution, _problem);
                Validation.Validator.ValidateSolution(ref solution, _problem);
            }
            catch (Exception ex)
            {
                Console.WriteLine();
            }
        }
예제 #5
0
        private void ChainPerturbation(ref Solution solution)
        {
            try
            {
                //marcar todos los vehículos como no perturbados.
                solution.Vehicles = solution.Vehicles.Select(t => { t.Perturbed = false; return(t); }).ToList();

                //Seleccionar el primer vehículo.
                int v1 = _random.Next(0, PerturbationMechanism.Keys.Count);
                if (PerturbationMechanism[v1].Count == 0)
                {
                    ResetPerturbationMechanism(false, v1);
                }

                int v2;
                do
                {
                    v2 = PerturbationMechanism[v1][_random.Next(0, PerturbationMechanism[v1].Count)];
                }while (v1 == v2);
                //routes.Remove(v2);

                PerturbationMechanism[v1].Remove(v2);
                PerturbationMechanism[v2].Remove(v1);

                //Seleccionar el tamaño de la cadena
                int maxSizeR1 = Math.Min(2, solution.Vehicles[v1].Requests.Count - 2);
                int maxSizeR2 = Math.Min(2, solution.Vehicles[v2].Requests.Count - 2);

                if (maxSizeR1 == 0)
                {
                    maxSizeR1 = 1;
                }
                if (maxSizeR2 == 0)
                {
                    maxSizeR2 = 1;
                }

                int size_R1 = _random.Next(1, maxSizeR1);
                int size_R2 = _random.Next(1, maxSizeR2);



                //Posición inicial desde la que coger elementos.
                int init_PosR1 = _random.Next(1, solution.Vehicles[v1].Requests.Count - 1);
                int init_PosR2 = _random.Next(1, solution.Vehicles[v2].Requests.Count - 1);

                if (init_PosR1 <= 0)
                {
                    init_PosR1 = 1;
                }
                if (init_PosR2 <= 0)
                {
                    init_PosR2 = 1;
                }



                //Obtener los elementos seleccionados en cada rango.
                var elementsR1 = solution.Vehicles[v1].Requests.GetRange(init_PosR1, size_R1);
                var elementsR2 = solution.Vehicles[v2].Requests.GetRange(init_PosR2, size_R2);

                foreach (var element in elementsR1)
                {
                    solution.Vehicles[v1].Requests.RemoveAll(t => t.PairID == element.ID_Unique);
                }

                foreach (var element in elementsR2)
                {
                    solution.Vehicles[v2].Requests.RemoveAll(t => t.PairID == element.ID_Unique);
                }

                //Marcar ambas rutas como perturbadas.
                solution.Vehicles[v1].Perturbed = true;
                solution.Vehicles[v2].Perturbed = true;

                List <Node> chainR1ToR2 = new List <Node>();
                List <Node> chainR2ToR1 = new List <Node>();


                List <int> tabu = new List <int>();
                foreach (var node in elementsR1)
                {
                    if (tabu.Contains(node.PairID))
                    {
                        continue;
                    }
                    tabu.Add(node.PairID);
                    var secondNode = _problem.Requests.Find(t => t.PairID == node.PairID && t.Origin != node.Origin);
                    //solution.Vehicles[v1].Requests.RemoveAll(t => t.PairID.Equals(node.PairID)); //Eliminar el destino y el origen


                    Request criticalNode;
                    Request notCriticalNode;
                    if (node.IsCritical)
                    {
                        criticalNode    = node;
                        notCriticalNode = secondNode;
                    }
                    else
                    {
                        criticalNode    = secondNode;
                        notCriticalNode = node;
                    }


                    double min_Dif         = double.MaxValue;
                    int    bestCriticalPos = -1;
                    //Si el nodo actual es crítico, insertarlo en su primera posición válida respecto a TW.
                    for (int i = 1; i < solution.Vehicles[v2].Requests.Count; i++)
                    {
                        //if (!_problem.FeasibleTravel[solution.Vehicles[v2].Requests[i].ID_Unique][criticalNode.ID_Unique]) continue;
                        double twDist = 0.0;
                        if (i == 1)
                        {
                            if ((criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[i].ID_Unique]) > solution.Vehicles[v2].Requests[i].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(criticalNode, v2, i, solution);
                        }
                        else if (i == solution.Vehicles[v2].Requests.Count - 1)
                        {
                            if ((solution.Vehicles[v2].Requests[i - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[i - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(criticalNode, v2, i - 1, solution);
                        }
                        else
                        {
                            if (((solution.Vehicles[v2].Requests[i - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[i - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound) ||
                                (criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[i].ID_Unique]) > solution.Vehicles[v2].Requests[i].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = (CalculateDistance(criticalNode, v2, i, solution) + CalculateDistance(criticalNode, v2, i - 1, solution)) / 2.0;
                        }
                        if (twDist < min_Dif)
                        {
                            min_Dif         = twDist;
                            bestCriticalPos = i;
                        }
                    }

                    if (bestCriticalPos == -1)
                    {
                        bestCriticalPos = 1;
                        solution.Vehicles[v2].Requests.Insert(1, criticalNode);
                    }
                    else
                    {
                        solution.Vehicles[v2].Requests.Insert(bestCriticalPos, criticalNode);
                    }

                    //La posición actual es válida para insertar el nodo crítico. Insertar el no crítico en su mejor posición
                    if (criticalNode.Origin)
                    {
                        double bestCost = double.PositiveInfinity;
                        int    bestPos  = bestCriticalPos + 1;
                        //Insertar el nodo no crítico después.
                        for (int j = bestCriticalPos + 1; j < solution.Vehicles[v2].Requests.Count; j++)
                        {
                            if (!_problem.FeasibleTravel[notCriticalNode.ID_Unique][solution.Vehicles[v2].Requests[j].ID_Unique])
                            {
                                continue;
                            }

                            //var diff = Problem.EuclideanDistance(notCriticalNode.TimeWindow.LowerBound, notCriticalNode.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.UpperBound);
                            double twDist = 0.0;
                            if (j == solution.Vehicles[v2].Requests.Count - 1)
                            {
                                if ((solution.Vehicles[v2].Requests[j - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[j - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = CalculateDistance(notCriticalNode, v2, j - 1, solution);
                            }
                            else
                            {
                                if (((solution.Vehicles[v2].Requests[j - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[j - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound) ||
                                    (criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[j].ID_Unique]) > solution.Vehicles[v2].Requests[j].TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = (CalculateDistance(notCriticalNode, v2, j, solution) + CalculateDistance(notCriticalNode, v2, j - 1, solution)) / 2.0;
                            }
                            if (twDist < bestCost)
                            {
                                bestPos  = j;
                                bestCost = twDist;
                            }
                        }
                        //Insertar en la mejor posición declarada.
                        solution.Vehicles[v2].Requests.Insert(bestPos, notCriticalNode);
                    }
                    else //El nodo no crítico es el origen.
                    {
                        double bestCost = double.PositiveInfinity;
                        int    bestPos  = bestCriticalPos;
                        //Insertar el nodo no crítico después.
                        //Insertar el nodo no crítico antes.
                        for (int j = bestCriticalPos; j > 0; j--)
                        {
                            if (!_problem.FeasibleTravel[solution.Vehicles[v2].Requests[j - 1].ID_Unique][notCriticalNode.ID_Unique])
                            {
                                continue;
                            }
                            //var diff = Problem.EuclideanDistance(notCriticalNode.TimeWindow.LowerBound, notCriticalNode.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.UpperBound);
                            double twDist = 0.0;
                            if (j == 1)
                            {
                                if ((criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[j].ID_Unique]) > solution.Vehicles[v2].Requests[j].TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = CalculateDistance(notCriticalNode, v2, j, solution);
                            }
                            else
                            {
                                if (((solution.Vehicles[v2].Requests[j - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[j - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound) ||
                                    (criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v2].Requests[j].ID_Unique]) > solution.Vehicles[v2].Requests[j].TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = (CalculateDistance(notCriticalNode, v2, j, solution) + CalculateDistance(notCriticalNode, v2, j - 1, solution)) / 2.0;
                            }
                            if (twDist < bestCost)
                            {
                                bestPos  = j;
                                bestCost = twDist;
                            }
                        }
                        //Insertar en la mejor posición declarada.
                        solution.Vehicles[v2].Requests.Insert(bestPos, notCriticalNode);
                        //break; //terminamos.
                    }
                }

                //Mismo proceso para los elementos de R2.
                tabu.Clear();
                foreach (var node in elementsR2)
                {
                    if (tabu.Contains(node.PairID))
                    {
                        continue;
                    }
                    tabu.Add(node.PairID);
                    var secondNode = _problem.Requests.Find(t => t.PairID == node.PairID && t.Origin != node.Origin); //solution.Vehicles[v2].Requests.Find(t => t.PairID == node.PairID && t.Origin != node.Origin);
                    //solution.Vehicles[v2].Requests.RemoveAll(t => t.PairID.Equals(node.PairID)); //Eliminar el destino y el origen


                    Request criticalNode;
                    Request notCriticalNode;
                    if (node.IsCritical)
                    {
                        criticalNode    = node;
                        notCriticalNode = secondNode;
                    }
                    else
                    {
                        criticalNode    = secondNode;
                        notCriticalNode = node;
                    }


                    double min_Dif         = double.MaxValue;
                    int    bestCriticalPos = -1;
                    //Si el nodo actual es crítico, insertarlo en su primera posición válida respecto a TW.
                    for (int i = 1; i < solution.Vehicles[v1].Requests.Count; i++)
                    {
                        double twDist = 0.0;
                        if (i == 1)
                        {
                            if ((criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[i].ID_Unique]) > solution.Vehicles[v1].Requests[i].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(criticalNode, v1, i, solution);
                        }
                        else if (i == solution.Vehicles[v1].Requests.Count - 1)
                        {
                            if ((solution.Vehicles[v1].Requests[i - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[i - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = CalculateDistance(criticalNode, v1, i - 1, solution);
                        }
                        else
                        {
                            if (((solution.Vehicles[v1].Requests[i - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[i - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound) ||
                                (criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[i].ID_Unique]) > solution.Vehicles[v1].Requests[i].TimeWindow.UpperBound)
                            {
                                continue;
                            }
                            twDist = (CalculateDistance(criticalNode, v1, i, solution) + CalculateDistance(criticalNode, v1, i - 1, solution)) / 2.0;
                        }
                        if (twDist < min_Dif)
                        {
                            min_Dif         = twDist;
                            bestCriticalPos = i;
                        }
                    }

                    if (bestCriticalPos == -1)
                    {
                        bestCriticalPos = 1;
                        solution.Vehicles[v1].Requests.Insert(1, criticalNode);
                    }
                    else
                    {
                        solution.Vehicles[v1].Requests.Insert(bestCriticalPos, criticalNode);
                    }

                    //La posición actual es válida para insertar el nodo crítico. Insertar el no crítico en su mejor posición
                    if (criticalNode.Origin)
                    {
                        double bestCost = double.PositiveInfinity;
                        int    bestPos  = bestCriticalPos + 1;
                        //Insertar el nodo no crítico después.
                        for (int j = bestCriticalPos + 1; j < solution.Vehicles[v1].Requests.Count; j++)
                        {
                            if (!_problem.FeasibleTravel[notCriticalNode.ID_Unique][solution.Vehicles[v1].Requests[j].ID_Unique])
                            {
                                continue;
                            }

                            //var diff = Problem.EuclideanDistance(notCriticalNode.TimeWindow.LowerBound, notCriticalNode.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.UpperBound);
                            double twDist = 0.0;
                            if (j == solution.Vehicles[v1].Requests.Count - 1)
                            {
                                if ((solution.Vehicles[v1].Requests[j - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[j - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = CalculateDistance(notCriticalNode, v1, j - 1, solution);
                            }
                            else
                            {
                                if (((solution.Vehicles[v1].Requests[j - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[j - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound) ||
                                    (criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[j].ID_Unique]) > solution.Vehicles[v1].Requests[j].TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = (CalculateDistance(notCriticalNode, v1, j, solution) + CalculateDistance(notCriticalNode, v1, j - 1, solution)) / 2.0;
                            }
                            if (twDist < bestCost)
                            {
                                bestPos  = j;
                                bestCost = twDist;
                            }
                        }
                        //Insertar en la mejor posición declarada.
                        solution.Vehicles[v1].Requests.Insert(bestPos, notCriticalNode);
                        //break; //terminamos.
                    }
                    else //El nodo no crítico es el origen.
                    {
                        double bestCost = double.PositiveInfinity;
                        int    bestPos  = bestCriticalPos;
                        //Insertar el nodo no crítico después.
                        //Insertar el nodo no crítico antes.
                        for (int j = bestCriticalPos; j > 0; j--)
                        {
                            if (!_problem.FeasibleTravel[solution.Vehicles[v1].Requests[j - 1].ID_Unique][notCriticalNode.ID_Unique])
                            {
                                continue;
                            }
                            //var diff = Problem.EuclideanDistance(notCriticalNode.TimeWindow.LowerBound, notCriticalNode.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[j + 1].TimeWindow.UpperBound);
                            double twDist = 0.0;
                            if (j == 1)
                            {
                                if ((criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[j].ID_Unique]) > solution.Vehicles[v1].Requests[j].TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = CalculateDistance(notCriticalNode, v1, j, solution);
                            }
                            else
                            {
                                if (((solution.Vehicles[v1].Requests[j - 1].TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[j - 1].ID_Unique]) > criticalNode.TimeWindow.UpperBound) ||
                                    (criticalNode.TimeWindow.LowerBound + _problem.Distances[criticalNode.ID_Unique][solution.Vehicles[v1].Requests[j].ID_Unique]) > solution.Vehicles[v1].Requests[j].TimeWindow.UpperBound)
                                {
                                    continue;
                                }
                                twDist = (CalculateDistance(notCriticalNode, v1, j, solution) + CalculateDistance(notCriticalNode, v1, j - 1, solution)) / 2.0;
                            }
                            if (twDist < bestCost)
                            {
                                bestPos  = j;
                                bestCost = twDist;
                            }
                        }
                        //Insertar en la mejor posición declarada.
                        solution.Vehicles[v1].Requests.Insert(bestPos, notCriticalNode);
                        //break; //terminamos.
                    }
                }


                //CorrectPositions(solution.Vehicles);
                //Recalcular con el proceso de 8 pasos y actualizar el coste.
                foreach (var vehicle in solution.Vehicles)
                {
                    DARPAlgorithms.EightStepsEvaluationProcedure(ref solution, vehicle, _problem);
                }


                solution.TotalDuration       = solution.Vehicles.Sum(t => t.VehicleDuration);
                solution.TimeWindowViolation = solution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                solution.RideTimeViolation   = solution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                solution.DurationViolation   = solution.Vehicles.Sum(d => d.TotalDurationViolation);
                solution.LoadViolation       = solution.Vehicles.Sum(l => l.TotalLoadViolation);
                solution.TotalWaitingTime    = solution.Vehicles.Sum(t => t.TotalWaitingTime);
                solution.Fitness             = Costs.EvaluationSolution(solution, _problem);

                Validator.ValidateSolution(ref solution, _problem);
            }
            catch (Exception ex)
            {
                Console.WriteLine();
            }
        }
예제 #6
0
        private void SpecialPerturbation(ref Solution solution)
        {
            solution.Vehicles = solution.Vehicles.Select(t => { t.Perturbed = true; return(t); }).ToList();
            //1. Sacar un vehículo aleatorio.
            var vehicle = solution.Vehicles[_random.Next(0, solution.Vehicles.Count - 1)];


            List <int> numbers = new List <int>();
            //2. Sacar un cliente crítico.
            var client = vehicle.Requests[_random.Next(1, vehicle.Requests.Count - 1)];

            List <Tuple <Request, Tuple <int, int> > > data = new List <Tuple <Request, Tuple <int, int> > >();

            if (!client.Origin)
            {
                client = vehicle.Requests.Find(t => t.Origin && t.PairID == client.PairID);
            }

            var vehicle_pos = solution.Vehicles.IndexOf(vehicle);
            var client_pos  = vehicle.Requests.IndexOf(client);

            numbers.Add(client.PairID);

            data.Add(new Tuple <Request, Tuple <int, int> >(client, new Tuple <int, int>(vehicle_pos, client_pos)));

            //3. Sacar sus N vecinos críticos.
            var            neighbours = _problem.CloseTWMatrix[client.ID_Unique];
            List <Request> vecinos    = new List <Request>();

            for (int i = 0; vecinos.Count < Convert.ToInt32(Math.Sqrt(_problem.NumRequests)) && i < neighbours.Count; i++)
            {
                if (_problem.Requests.Find(t => t.ID_Unique == neighbours[i]).Origin)
                {
                    vecinos.Add(_problem.Requests.Find(t => t.ID_Unique == neighbours[i]));
                    numbers.Add(vecinos[vecinos.Count - 1].PairID);
                }
            }

            //4. Sacar vehículo y posición de cada uno
            foreach (var v in vecinos)
            {
                for (int i = 0; i < solution.Vehicles.Count; i++)
                {
                    if (solution.Vehicles[i].Requests.Find(t => t.ID_Unique == v.ID_Unique) != null)
                    {
                        data.Add(new Tuple <Request, Tuple <int, int> >(v, new Tuple <int, int>(i, solution.Vehicles[i].Requests.IndexOf(solution.Vehicles[i].Requests.Find(t => t.ID_Unique == v.ID_Unique)))));
                    }
                }
            }

            List <Tuple <Request, Tuple <int, int> > > movements = new List <Tuple <Request, Tuple <int, int> > >();

            foreach (var element in data)
            {
                var request  = element.Item1;
                int selected = -1;
                if (numbers.Count == 1 && numbers.First() == element.Item1.PairID)
                {
                    break;
                }
                //5. Mezclarlos.
                do
                {
                    selected = numbers[_random.Next(0, numbers.Count)];
                }while (selected == request.ID_Unique);
                numbers.Remove(selected); //eliminarlo.

                var posInterchange = data.Find(t => t.Item1.ID_Unique == selected);

                //solution.Vehicles[element.Item2.Item1].Requests[element.Item2.Item2] = posInterchange.Item1;
                //solution.Vehicles[posInterchange.Item2.Item1].Requests[posInterchange.Item2.Item2] = element.Item1;
                //los destinos.
                var destinoElement     = solution.Vehicles[element.Item2.Item1].Requests.Find(t => t.PairID == element.Item1.PairID && t.Origin == false);
                var destinoInterchange = solution.Vehicles[posInterchange.Item2.Item1].Requests.Find(t => t.PairID == posInterchange.Item1.PairID && t.Origin == false);
                //solution.Vehicles[element.Item2.Item1].Requests[solution.Vehicles[element.Item2.Item1].Requests.IndexOf(destinoElement)] = destinoInterchange;
                //solution.Vehicles[posInterchange.Item2.Item1].Requests[solution.Vehicles[posInterchange.Item2.Item1].Requests.IndexOf(destinoInterchange)] = destinoElement;

                movements.Add(new Tuple <Request, Tuple <int, int> >(element.Item1, new Tuple <int, int>(posInterchange.Item2.Item1, posInterchange.Item2.Item2)));
                movements.Add(new Tuple <Request, Tuple <int, int> >(destinoElement, new Tuple <int, int>(posInterchange.Item2.Item1, solution.Vehicles[posInterchange.Item2.Item1].Requests.IndexOf(destinoInterchange))));
            }

            foreach (var entry in movements)
            {
                solution.Vehicles[entry.Item2.Item1].Requests[entry.Item2.Item2] = entry.Item1;
            }
            //Recalcular con el proceso de 8 pasos y actualizar el coste.
            foreach (var veh in solution.Vehicles)
            {
                DARPAlgorithms.EightStepsEvaluationProcedure(ref solution, veh, _problem);
            }
            solution.TotalDuration       = solution.Vehicles.Sum(t => t.VehicleDuration);
            solution.TimeWindowViolation = solution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
            solution.RideTimeViolation   = solution.Vehicles.Sum(r => r.TotalRideTimeViolation);
            solution.DurationViolation   = solution.Vehicles.Sum(d => d.TotalDurationViolation);
            solution.LoadViolation       = solution.Vehicles.Sum(l => l.TotalLoadViolation);
            solution.TotalWaitingTime    = solution.Vehicles.Sum(t => t.TotalWaitingTime);
            DARPAlgorithms.UpdateConstraintsSolution(ref solution, _problem);
            solution.Fitness = Costs.EvaluationSolution(solution, _problem);
        }
예제 #7
0
        private void SwapPerturbation(ref Solution solution)
        {
            solution.Vehicles = solution.Vehicles.Select(t => { t.Perturbed = false; return(t); }).ToList();
            //Seleccionar el primer vehículo.
            int v1 = _random.Next(0, PerturbationMechanism.Keys.Count);

            if (PerturbationMechanism[v1].Count == 0)
            {
                ResetPerturbationMechanism(false, v1);
            }

            int v2;

            do
            {
                v2 = PerturbationMechanism[v1][_random.Next(0, PerturbationMechanism[v1].Count)];
            }while (v1 == v2);

            PerturbationMechanism[v1].Remove(v2);
            PerturbationMechanism[v2].Remove(v1);

            var posA  = _random.Next(1, solution.Vehicles[v1].Requests.Count - 1);
            var node1 = solution.Vehicles[v1].Requests[posA];
            var node2 = solution.Vehicles[v1].Requests.Find(t => t.PairID == node1.PairID && t.Origin != node1.Origin);
            var posB  = solution.Vehicles[v1].Requests.IndexOf(node2);

            //Determinamos nodo crítico (será el primero a insertar).
            Request originA;
            Request destinationA;

            int posOriginA      = -1;
            int posDestinationA = -1;

            if (node1.Origin)
            {
                originA         = node1;
                destinationA    = node2;
                posOriginA      = posA;
                posDestinationA = posB;
            }
            else
            {
                originA         = node2;
                destinationA    = node1;
                posOriginA      = posB;
                posDestinationA = posA;
            }



            int    minPos = -1;
            double min    = Double.MaxValue;

            for (int i = 1; i < solution.Vehicles[v2].Requests.Count - 1; i++)
            {
                //if (!ValidTimeWindow(solution, node1, _problem, i + 1, v2)) continue;
                // var distance = Problem.EuclideanDistance(node1.TimeWindow.LowerBound, node1.TimeWindow.UpperBound, solution.Vehicles[v2].Requests[i].TimeWindow.LowerBound, solution.Vehicles[v2].Requests[i].TimeWindow.UpperBound);

                double twDist = 0.0;
                if (i == 1)
                {
                    if (!ValidTimeWindow(solution, node1, _problem, i + 1, v2))
                    {
                        continue;
                    }
                    twDist = CalculateDistance(node1, v2, i - 1, solution);
                }
                else if (i == solution.Vehicles[v2].Requests.Count - 2)
                {
                    if (!ValidTimeWindow(solution, node1, _problem, i - 1, v2))
                    {
                        continue;
                    }
                    twDist = CalculateDistance(node1, v2, i - 1, solution);
                }
                else
                {
                    if (!ValidTimeWindow(solution, node1, _problem, i + 1, v2) || !ValidTimeWindow(solution, node1, _problem, i - 1, v2))
                    {
                        continue;
                    }
                    twDist = (CalculateDistance(node1, v2, i + 1, solution) + CalculateDistance(node1, v2, i - 1, solution)) / 2.0;
                }
                if (twDist < min)
                {
                    minPos = i;
                    min    = twDist;
                }
            }

            if (minPos == -1)
            {
                return;
            }

            var nodeB1    = solution.Vehicles[v2].Requests[minPos];
            var nodeB2    = solution.Vehicles[v2].Requests.Find(t => t.PairID == nodeB1.PairID && t.Origin != nodeB1.Origin);
            var posNodeB2 = solution.Vehicles[v2].Requests.IndexOf(nodeB2);

            //Determinamos nodo crítico (será el primero a insertar).
            Request originB;
            Request destinationB;

            if (nodeB1.Origin)
            {
                originB      = nodeB1;
                destinationB = nodeB2;
            }
            else
            {
                originB      = nodeB2;
                destinationB = nodeB1;
                var aux = minPos;
                minPos    = posNodeB2;
                posNodeB2 = aux;
            }

            solution.Vehicles[v2].Requests[minPos]          = originA;
            solution.Vehicles[v2].Requests[posNodeB2]       = destinationA;
            solution.Vehicles[v1].Requests[posOriginA]      = originB;
            solution.Vehicles[v1].Requests[posDestinationA] = destinationB;


            Validator.Positions(ref solution, _problem);

            solution.Vehicles[v2].Perturbed = true;
            solution.Vehicles[v1].Perturbed = true;

            DARPAlgorithms.EightStepsEvaluationProcedure(ref solution, solution.Vehicles[v1], _problem);
            DARPAlgorithms.EightStepsEvaluationProcedure(ref solution, solution.Vehicles[v2], _problem);

            solution.TotalDuration       = solution.Vehicles.Sum(t => t.VehicleDuration);
            solution.TimeWindowViolation = solution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
            solution.RideTimeViolation   = solution.Vehicles.Sum(r => r.TotalRideTimeViolation);
            solution.DurationViolation   = solution.Vehicles.Sum(d => d.TotalDurationViolation);
            solution.LoadViolation       = solution.Vehicles.Sum(l => l.TotalLoadViolation);
            solution.TotalWaitingTime    = solution.Vehicles.Sum(t => t.TotalWaitingTime);
            solution.Fitness             = Costs.EvaluationSolution(solution, _problem);
            Validator.Positions(ref solution, _problem);
        }
예제 #8
0
        private bool Shift1_0Inter(ref Solution solution)
        {
            Solution optSolution = solution;
            bool     improvement = false;
            double   bestCost    = optSolution.Fitness;
            bool     exit        = false;
            int      v1_aux;

Init:
            var vehicle = optSolution.Vehicles;

            for (int v1 = 0; v1 < optSolution.Vehicles.Count; v1++)
            {
                if (optSolution.Vehicles[v1].Requests.Count == 4)
                {
                    continue;
                }
                for (int v2 = 0; v2 < optSolution.Vehicles.Count; v2++)
                {
                    if (v1 == v2 || (!optSolution.Vehicles[v1].Perturbed || !optSolution.Vehicles[v2].Perturbed))
                    {
                        continue;
                    }
                    for (int i = 1; i < optSolution.Vehicles[v1].Requests.Count - 1; i++)
                    {
                        var critical    = vehicle[v1].Requests[i];
                        var criticalPos = i;
                        if (!critical.IsCritical)
                        {
                            continue;
                        }
                        var notCritical    = vehicle[v1].Requests.Find(t => t.PairID == critical.PairID && t.Origin != critical.Origin);
                        var notCriticalPos = vehicle[v1].Requests.IndexOf(notCritical);
                        var v1DurV         = vehicle[v1].TotalDurationViolation;
                        var v1TWV          = vehicle[v1].TotalTimeWindowViolation;
                        var v1RTV          = vehicle[v1].TotalRideTimeViolation;
                        var v1LV           = vehicle[v1].TotalLoadViolation;
                        var v1TWT          = vehicle[v1].TotalWaitingTime;
                        var v1Dur          = vehicle[v1].VehicleDuration;

                        vehicle[v1].Requests.RemoveAll(t => t.PairID == critical.PairID);
                        DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v1], _problem);

                        for (int j = 1; j < vehicle[v2].Requests.Count - 1; j++)
                        {
                            if (_problem.FeasibleTravel[vehicle[v2].Requests[j - 1].ID_Unique][critical.ID_Unique] && _problem.FeasibleTravel[critical.ID_Unique][vehicle[v2].Requests[j].ID_Unique])
                            {
                                vehicle[v2].Requests.Insert(j, critical);
                                if (critical.Origin)
                                {
                                    int index_Target = j + 1;
                                    while (index_Target < vehicle[v2].Requests.Count) //Desde la posición actual a la primera posición.
                                    {
                                        if (_problem.FeasibleTravel[vehicle[v2].Requests[index_Target - 1].ID_Unique][notCritical.ID_Unique] && _problem.FeasibleTravel[notCritical.ID_Unique][vehicle[v2].Requests[index_Target].ID_Unique])
                                        {
                                            vehicle[v2].Requests.Insert(index_Target, notCritical);
                                            //Salvar estados vehículo actuales.
                                            var v2DurV = vehicle[v2].TotalDurationViolation;
                                            var v2TWV  = vehicle[v2].TotalTimeWindowViolation;
                                            var v2RTV  = vehicle[v2].TotalRideTimeViolation;
                                            var v2LV   = vehicle[v2].TotalLoadViolation;
                                            var v2TWT  = vehicle[v2].TotalWaitingTime;
                                            var v2Dur  = vehicle[v2].VehicleDuration;


                                            DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v2], _problem);

                                            //Actualizar estado de la solución.
                                            var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                                            var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                                            var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                                            var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                                            var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                                            var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                                            var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                                            if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                                            {
                                                bestCost = cost;
                                                ShiftInter++;
                                                optSolution.TotalDuration       = vd;
                                                optSolution.TimeWindowViolation = twv;
                                                optSolution.RideTimeViolation   = rtv;
                                                optSolution.DurationViolation   = tdv;
                                                optSolution.LoadViolation       = lv;
                                                optSolution.TotalWaitingTime    = wt;
                                                improvement = true;
                                                goto Init;
                                            }
                                            else
                                            {
                                                //Deshacer el movimiento de inserción.
                                                vehicle[v2].Requests.Remove(notCritical);
                                                //Copiar estados anteriores a las modificaciones.
                                                optSolution.Vehicles[v2].TotalDurationViolation   = v2DurV;
                                                optSolution.Vehicles[v2].TotalTimeWindowViolation = v2TWV;
                                                optSolution.Vehicles[v2].TotalRideTimeViolation   = v2RTV;
                                                optSolution.Vehicles[v2].TotalLoadViolation       = v2LV;
                                                optSolution.Vehicles[v2].TotalWaitingTime         = v2TWT;
                                                optSolution.Vehicles[v2].VehicleDuration          = v2Dur;
                                            }
                                        }
                                        index_Target++;
                                    }
                                }
                                else
                                {
                                    int index_Target = j;
                                    while (index_Target > 0) //mientras no se llegue a la petición destino.
                                    {
                                        if (_problem.FeasibleTravel[vehicle[v2].Requests[index_Target - 1].ID_Unique][notCritical.ID_Unique] && _problem.FeasibleTravel[notCritical.ID_Unique][vehicle[v2].Requests[index_Target].ID_Unique])
                                        {
                                            vehicle[v2].Requests.Insert(index_Target, notCritical);
                                            //Marcar rutas que han sido modificadas.
                                            var v2DurV = optSolution.Vehicles[v2].TotalDurationViolation;
                                            var v2TWV  = optSolution.Vehicles[v2].TotalTimeWindowViolation;
                                            var v2RTV  = optSolution.Vehicles[v2].TotalRideTimeViolation;
                                            var v2LV   = optSolution.Vehicles[v2].TotalLoadViolation;
                                            var v2TWT  = optSolution.Vehicles[v2].TotalWaitingTime;
                                            var v2Dur  = optSolution.Vehicles[v2].VehicleDuration;
                                            DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v2], _problem);

                                            //Actualizar estado de la solución.
                                            var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                                            var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                                            var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                                            var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                                            var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                                            var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                                            var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                                            if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                                            {
                                                bestCost = cost;
                                                ShiftInter++;
                                                optSolution.TotalDuration       = vd;
                                                optSolution.TimeWindowViolation = twv;
                                                optSolution.RideTimeViolation   = rtv;
                                                optSolution.DurationViolation   = tdv;
                                                optSolution.LoadViolation       = lv;
                                                optSolution.TotalWaitingTime    = wt;
                                                improvement = true;
                                                goto Init;
                                            }
                                            else
                                            {
                                                //Deshacer el movimiento Swap1_1
                                                vehicle[v2].Requests.Remove(notCritical);
                                                //Copiar estados anteriores a las modificaciones.
                                                optSolution.Vehicles[v2].TotalDurationViolation   = v2DurV;
                                                optSolution.Vehicles[v2].TotalTimeWindowViolation = v2TWV;
                                                optSolution.Vehicles[v2].TotalRideTimeViolation   = v2RTV;
                                                optSolution.Vehicles[v2].TotalLoadViolation       = v2LV;
                                                optSolution.Vehicles[v2].TotalWaitingTime         = v2TWT;
                                                optSolution.Vehicles[v2].VehicleDuration          = v2Dur;
                                            }
                                        }
                                        index_Target--;
                                    }
                                }
                                vehicle[v2].Requests.Remove(critical);
                            }
                        }
                        if (criticalPos < notCriticalPos)
                        {
                            vehicle[v1].Requests.Insert(criticalPos, critical);
                            vehicle[v1].Requests.Insert(notCriticalPos, notCritical);
                            exit = true;
                        }
                        else
                        {
                            vehicle[v1].Requests.Insert(notCriticalPos, notCritical);
                            vehicle[v1].Requests.Insert(criticalPos, critical);
                            exit   = true;
                            v1_aux = v1;
                        }
                        vehicle[v1].TotalDurationViolation   = v1DurV;
                        vehicle[v1].TotalTimeWindowViolation = v1TWV;
                        vehicle[v1].TotalRideTimeViolation   = v1RTV;
                        vehicle[v1].TotalLoadViolation       = v1LV;
                        vehicle[v1].TotalWaitingTime         = v1TWT;
                        vehicle[v1].VehicleDuration          = v1Dur;
                    }
                }
            }

            optSolution.Fitness = bestCost;
            return(improvement);
        }
예제 #9
0
        private bool Swap_Intra(ref Solution solution)
        {
            Solution optSolution = solution;
            bool     improvement = false;
            double   bestCost    = optSolution.Fitness;
            double   parcCost    = optSolution.Parc_Cost;

Init:
            var vehicle = optSolution.Vehicles;

            for (int v = 0; v < vehicle.Count; v++)
            {
                //Vehicle selection.
                var requests = vehicle[v].Requests;
                if (!vehicle[v].Perturbed)
                {
                    continue; //NO hay sido modificado.
                }
                for (int i = 1; i < requests.Count - 1; i++)
                {
                    var node1V1 = requests[i];
                    if (!node1V1.Origin)
                    {
                        continue;
                    }
                    var node2V1      = requests.Find(t => t.PairID == node1V1.PairID && t.Origin != node1V1.Origin);
                    var indexNode2V1 = requests.IndexOf(node2V1);
                    for (int j = 1; j < requests.Count - 1; j++)
                    {
                        var node1V2 = requests[j];
                        if (!node1V2.Origin)
                        {
                            continue;
                        }
                        if (i == j || node1V1.PairID == node1V2.PairID)
                        {
                            continue;                                             //omitir mismas posiciones
                        }
                        var node2V2      = requests.Find(t => t.PairID == node1V2.PairID && t.Origin != node1V2.Origin);
                        var indexNode2V2 = requests.IndexOf(node2V2);

                        if (!CheckTimeWindowSwap1_1_Intra(ref optSolution, vehicle[v].Requests, i, j) && !_problem.NeighborhoodTW[node1V1.PairID][node1V2.PairID] && !_problem.NeighborhoodTW[node1V2.PairID][node1V1.PairID])
                        {
                            continue;
                        }

                        requests[i]            = node1V2;
                        requests[j]            = node1V1;
                        requests[indexNode2V1] = node2V2;
                        requests[indexNode2V2] = node2V1;



                        var v1DurV = optSolution.Vehicles[v].TotalDurationViolation;
                        var v1TWV  = optSolution.Vehicles[v].TotalTimeWindowViolation;
                        var v1RTV  = optSolution.Vehicles[v].TotalRideTimeViolation;
                        var v1LV   = optSolution.Vehicles[v].TotalLoadViolation;
                        var v1TWT  = optSolution.Vehicles[v].TotalWaitingTime;
                        var v1Dur  = optSolution.Vehicles[v].VehicleDuration;
                        DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v], _problem);


                        //Actualizar estado de la solución.
                        var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                        var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                        var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                        var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                        var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                        var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                        var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                        if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                        {
                            bestCost = cost;
                            optSolution.TotalDuration       = vd;
                            optSolution.TimeWindowViolation = twv;
                            optSolution.RideTimeViolation   = rtv;
                            optSolution.DurationViolation   = tdv;
                            optSolution.LoadViolation       = lv;
                            optSolution.TotalWaitingTime    = wt;
                            IntraSwap++;
                            improvement = true;
                            goto Init;
                        }
                        else
                        {
                            //Deshacer el movimiento de intercambio
                            requests[i]            = node1V1;
                            requests[j]            = node1V2;
                            requests[indexNode2V1] = node2V1;
                            requests[indexNode2V2] = node2V2;
                            //Copiar estados anteriores a las modificaciones.
                            optSolution.Vehicles[v].TotalDurationViolation   = v1DurV;
                            optSolution.Vehicles[v].TotalTimeWindowViolation = v1TWV;
                            optSolution.Vehicles[v].TotalRideTimeViolation   = v1RTV;
                            optSolution.Vehicles[v].TotalLoadViolation       = v1LV;
                            optSolution.Vehicles[v].TotalWaitingTime         = v1TWT;
                            optSolution.Vehicles[v].VehicleDuration          = v1Dur;
                        }
                    }
                }
            }
            optSolution.Fitness   = bestCost;
            optSolution.Parc_Cost = parcCost;
            return(improvement);
        }
예제 #10
0
        private bool WRI_Intra(ref Solution solution)
        {
            bool     improvement = false;
            Solution optSolution = solution;
            double   bestCost    = optSolution.Fitness;
            double   parcCost    = optSolution.Parc_Cost;

Init:
            var vehicle = optSolution.Vehicles;

            for (int v = 0; v < vehicle.Count; v++)
            {
                if (!vehicle[v].Perturbed)
                {
                    continue; //NO hay sido modificado.
                }
                //Vehicle selection.
                var requests = vehicle[v].Requests;
                for (int i = 1; i < requests.Count - 1; i++)
                {
                    var node = requests[i];
                    requests.RemoveAt(i); //Eliminar de su posición de origen.
                    if (node.Origin)
                    {
                        var index_Destination = requests.IndexOf(requests.Find(t => t.PairID == node.PairID && t.Origin != node.Origin));
                        for (int j = 1; j <= index_Destination; j++)
                        {
                            if (!CheckTimeWindowShift1_0(ref optSolution, requests, node, j))
                            {
                                continue;
                            }
                            requests.Insert(j, node); //Insertar el nodo en su nueva posición.

                            var v1DurV = optSolution.Vehicles[v].TotalDurationViolation;
                            var v1TWV  = optSolution.Vehicles[v].TotalTimeWindowViolation;
                            var v1RTV  = optSolution.Vehicles[v].TotalRideTimeViolation;
                            var v1LV   = optSolution.Vehicles[v].TotalLoadViolation;
                            var v1TWT  = optSolution.Vehicles[v].TotalWaitingTime;
                            var v1Dur  = optSolution.Vehicles[v].VehicleDuration;
                            DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v], _problem);


                            //Actualizar estado de la solución.
                            var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                            var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                            var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                            var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                            var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                            var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                            var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                            if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                            {
                                bestCost = cost;
                                optSolution.TotalDuration       = vd;
                                optSolution.TimeWindowViolation = twv;
                                optSolution.RideTimeViolation   = rtv;
                                optSolution.DurationViolation   = tdv;
                                optSolution.LoadViolation       = lv;
                                optSolution.TotalWaitingTime    = wt;
                                WRI_IntraOP++;
                                improvement = true;
                                goto Init;
                            }
                            else
                            {
                                //Deshacer el movimiento SHIFT
                                requests.RemoveAt(j); //Eliminar de su posición de origen.
                                optSolution.Vehicles[v].TotalDurationViolation   = v1DurV;
                                optSolution.Vehicles[v].TotalTimeWindowViolation = v1TWV;
                                optSolution.Vehicles[v].TotalRideTimeViolation   = v1RTV;
                                optSolution.Vehicles[v].TotalLoadViolation       = v1LV;
                                optSolution.Vehicles[v].TotalWaitingTime         = v1TWT;
                                optSolution.Vehicles[v].VehicleDuration          = v1Dur;
                            }
                        }
                        requests.Insert(i, node); //No ha habido cambios e insertarlo en su posición original
                    }
                    else
                    {
                        var index_Destination = requests.IndexOf(requests.Find(t => t.PairID == node.PairID && t.Origin != node.Origin));
                        for (int j = requests.Count - 1; j > index_Destination; j--)
                        {
                            if (!CheckTimeWindowShift1_0(ref optSolution, requests, node, j))
                            {
                                continue;
                            }
                            requests.Insert(j, node); //Insertar el nodo en su nueva posición.

                            var v1DurV = optSolution.Vehicles[v].TotalDurationViolation;
                            var v1TWV  = optSolution.Vehicles[v].TotalTimeWindowViolation;
                            var v1RTV  = optSolution.Vehicles[v].TotalRideTimeViolation;
                            var v1LV   = optSolution.Vehicles[v].TotalLoadViolation;
                            var v1TWT  = optSolution.Vehicles[v].TotalWaitingTime;
                            var v1Dur  = optSolution.Vehicles[v].VehicleDuration;
                            DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v], _problem);


                            //Actualizar estado de la solución.
                            var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                            var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                            var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                            var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                            var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                            var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                            var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                            if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                            {
                                bestCost = cost;
                                optSolution.TotalDuration       = vd;
                                optSolution.TimeWindowViolation = twv;
                                optSolution.RideTimeViolation   = rtv;
                                optSolution.DurationViolation   = tdv;
                                optSolution.LoadViolation       = lv;
                                optSolution.TotalWaitingTime    = wt;
                                WRI_IntraOP++;
                                improvement = true;
                                goto Init;
                            }
                            else
                            {
                                //Deshacer el movimiento SHIFT
                                requests.RemoveAt(j); //Eliminar de su posición de origen.
                                optSolution.Vehicles[v].TotalDurationViolation   = v1DurV;
                                optSolution.Vehicles[v].TotalTimeWindowViolation = v1TWV;
                                optSolution.Vehicles[v].TotalRideTimeViolation   = v1RTV;
                                optSolution.Vehicles[v].TotalLoadViolation       = v1LV;
                                optSolution.Vehicles[v].TotalWaitingTime         = v1TWT;
                                optSolution.Vehicles[v].VehicleDuration          = v1Dur;
                            }
                        }
                        requests.Insert(i, node); //No ha habido cambios e insertarlo en su posición original
                    }
                }
            }
            optSolution.Fitness = bestCost;
            return(improvement);
        }
예제 #11
0
        private bool IntraRouteInsertion(ref Solution solution)
        {
            bool     improvement = false;
            Solution optSolution = solution;
            double   bestCost    = optSolution.Fitness;

Init:
            var vehicle = optSolution.Vehicles;

            for (int v = 0; v < vehicle.Count; v++)
            {
                if (!vehicle[v].Perturbed)
                {
                    continue;
                }
                //Vehicle selection.
                for (int i = 1; i < vehicle[v].Requests.Count - 1; i++)
                {
                    var critical    = vehicle[v].Requests[i];
                    var criticalPos = i;
                    if (!critical.IsCritical)
                    {
                        continue;
                    }
                    var notCritical    = vehicle[v].Requests.Find(t => t.PairID == critical.PairID && t.Origin != critical.Origin);
                    var notCriticalPos = vehicle[v].Requests.IndexOf(notCritical);
                    vehicle[v].Requests.RemoveAll(t => t.PairID == critical.PairID);
                    for (int j = 1; j < vehicle[v].Requests.Count - 1; j++)
                    {
                        if (CheckTimeWindowShift1_0(ref optSolution, vehicle[v].Requests, critical, j))
                        {
                            vehicle[v].Requests.Insert(j, critical);
                            if (critical.Origin)
                            {
                                int index_Target = j + 1;
                                while (index_Target < vehicle[v].Requests.Count) //Desde la posición actual a la primera posición.
                                {
                                    if (CheckTimeWindowShift1_0(ref optSolution, vehicle[v].Requests, notCritical, index_Target))
                                    {
                                        vehicle[v].Requests.Insert(index_Target, notCritical);
                                        //Salvar estados vehículo actuales.
                                        var v1DurV = vehicle[v].TotalDurationViolation;
                                        var v1TWV  = vehicle[v].TotalTimeWindowViolation;
                                        var v1RTV  = vehicle[v].TotalRideTimeViolation;
                                        var v1LV   = vehicle[v].TotalLoadViolation;
                                        var v1TWT  = vehicle[v].TotalWaitingTime;
                                        var v1Dur  = vehicle[v].VehicleDuration;

                                        DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v], _problem);

                                        //Actualizar estado de la solución.
                                        var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                                        var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                                        var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                                        var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                                        var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                                        var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                                        var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                                        if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                                        {
                                            bestCost = cost;
                                            IntraRouteInsertionOP++;
                                            optSolution.TotalDuration       = vd;
                                            optSolution.TimeWindowViolation = twv;
                                            optSolution.RideTimeViolation   = rtv;
                                            optSolution.DurationViolation   = tdv;
                                            optSolution.LoadViolation       = lv;
                                            optSolution.TotalWaitingTime    = wt;
                                            improvement = true;
                                            goto Init;
                                        }
                                        else
                                        {
                                            //Deshacer el movimiento de inserción.
                                            vehicle[v].Requests.Remove(notCritical);
                                            //Copiar estados anteriores a las modificaciones.
                                            optSolution.Vehicles[v].TotalDurationViolation   = v1DurV;
                                            optSolution.Vehicles[v].TotalTimeWindowViolation = v1TWV;
                                            optSolution.Vehicles[v].TotalRideTimeViolation   = v1RTV;
                                            optSolution.Vehicles[v].TotalLoadViolation       = v1LV;
                                            optSolution.Vehicles[v].TotalWaitingTime         = v1TWT;
                                            optSolution.Vehicles[v].VehicleDuration          = v1Dur;
                                            //if (vehicle[v].Requests[index_Target - 1].DepartureTime - vehicle[v].Requests[index_Target - 1].SlackTime + _problem.Distances[vehicle[v].Requests[index_Target - 1].ID_Unique][notCritical.ID_Unique] > notCritical.TimeWindow.UpperBound)
                                            //    break;
                                        }
                                    }
                                    index_Target++;
                                }
                            }
                            else
                            {
                                int index_Target = j;
                                while (index_Target > 0) //mientras no se llegue a la petición destino.
                                {
                                    if (CheckTimeWindowShift1_0(ref optSolution, vehicle[v].Requests, notCritical, index_Target))
                                    {
                                        vehicle[v].Requests.Insert(index_Target, notCritical);
                                        //Marcar rutas que han sido modificadas.
                                        var v1DurV = optSolution.Vehicles[v].TotalDurationViolation;
                                        var v1TWV  = optSolution.Vehicles[v].TotalTimeWindowViolation;
                                        var v1RTV  = optSolution.Vehicles[v].TotalRideTimeViolation;
                                        var v1LV   = optSolution.Vehicles[v].TotalLoadViolation;
                                        var v1TWT  = optSolution.Vehicles[v].TotalWaitingTime;
                                        var v1Dur  = optSolution.Vehicles[v].VehicleDuration;
                                        DARPAlgorithms.EightStepsEvaluationProcedure(ref optSolution, optSolution.Vehicles[v], _problem);

                                        //Actualizar estado de la solución.
                                        var vd  = optSolution.Vehicles.Sum(t => t.VehicleDuration);
                                        var twv = optSolution.Vehicles.Sum(t => t.TotalTimeWindowViolation);
                                        var rtv = optSolution.Vehicles.Sum(r => r.TotalRideTimeViolation);
                                        var tdv = optSolution.Vehicles.Sum(d => d.TotalDurationViolation);
                                        var lv  = optSolution.Vehicles.Sum(l => l.TotalLoadViolation);
                                        var wt  = optSolution.Vehicles.Sum(t => t.TotalWaitingTime);

                                        var cost = Costs.EvaluationSolution(ref optSolution, twv, rtv, tdv, lv, _problem);
                                        if (Math.Round(cost, 2) < Math.Round(bestCost, 2))
                                        {
                                            bestCost = cost;
                                            IntraRouteInsertionOP++;
                                            optSolution.TotalDuration       = vd;
                                            optSolution.TimeWindowViolation = twv;
                                            optSolution.RideTimeViolation   = rtv;
                                            optSolution.DurationViolation   = tdv;
                                            optSolution.LoadViolation       = lv;
                                            optSolution.TotalWaitingTime    = wt;
                                            improvement = true;
                                            goto Init;
                                        }
                                        else
                                        {
                                            //Deshacer el movimiento Swap1_1
                                            vehicle[v].Requests.Remove(notCritical);
                                            //Copiar estados anteriores a las modificaciones.
                                            optSolution.Vehicles[v].TotalDurationViolation   = v1DurV;
                                            optSolution.Vehicles[v].TotalTimeWindowViolation = v1TWV;
                                            optSolution.Vehicles[v].TotalRideTimeViolation   = v1RTV;
                                            optSolution.Vehicles[v].TotalLoadViolation       = v1LV;
                                            optSolution.Vehicles[v].TotalWaitingTime         = v1TWT;
                                            optSolution.Vehicles[v].VehicleDuration          = v1Dur;
                                            //if (vehicle[v].Requests[index_Target - 1].DepartureTime - vehicle[v].Requests[index_Target - 1].SlackTime + _problem.Distances[vehicle[v].Requests[index_Target - 1].ID_Unique][notCritical.ID_Unique] > notCritical.TimeWindow.UpperBound)
                                            //     break;
                                        }
                                    }
                                    index_Target--;
                                }
                            }
                            vehicle[v].Requests.Remove(critical);
                        }
                    }
                    if (criticalPos < notCriticalPos)
                    {
                        vehicle[v].Requests.Insert(criticalPos, critical);
                        vehicle[v].Requests.Insert(notCriticalPos, notCritical);
                    }
                    else
                    {
                        vehicle[v].Requests.Insert(notCriticalPos, notCritical);
                        vehicle[v].Requests.Insert(criticalPos, critical);
                    }
                }
            }
            optSolution.Fitness = bestCost;
            return(improvement);
        }