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); }
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; }
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(); } }
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); }