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