Example #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);
        }
Example #2
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;
        }
Example #3
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();
            }
        }
Example #4
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);
        }