public static PotvinPDRearrangeMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) { List <int> cities = new List <int>(); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; for (int i = 1; i <= individual.Cities; i++) { if (pdp == null || pdp.GetDemand(i) >= 0) { cities.Add(i); } } if (cities.Count > 0) { int city = cities[rand.Next(cities.Count)]; int tour = individual.Tours.FindIndex(t => t.Stops.Contains(city)); return(new PotvinPDRearrangeMove(city, tour, individual)); } else { return(null); } }
public static void Apply(PotvinEncoding solution, PotvinPDRearrangeMove move, IVRPProblemInstance problemInstance) { Tour tour = solution.Tours[move.Tour]; int position = tour.Stops.IndexOf(move.City); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; if (pdp != null) { int location = pdp.GetPickupDeliveryLocation(move.City); Tour tour2 = solution.Tours.Find(t => t.Stops.Contains(location)); int position2 = tour2.Stops.IndexOf(location); tour.Stops.Remove(move.City); tour2.Stops.Remove(location); solution.InsertPair(tour, move.City, location, problemInstance, position, position2); } else { tour.Stops.Remove(move.City); int place = solution.FindBestInsertionPlace(tour, move.City, position); tour.Stops.Insert(place, move.City); } solution.Repair(); }
protected override PotvinPDShiftMove[] GenerateMoves(PotvinEncoding individual, IVRPProblemInstance problemInstance) { List <PotvinPDShiftMove> result = new List <PotvinPDShiftMove>(); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; int max = individual.Tours.Count; if (individual.Tours.Count >= problemInstance.Vehicles.Value) { max = max - 1; } for (int i = 0; i < individual.Tours.Count; i++) { for (int j = 0; j < individual.Tours[i].Stops.Count; j++) { for (int k = 0; k <= max; k++) { if (k != i) { int city = individual.Tours[i].Stops[j]; if (pdp == null || pdp.GetDemand(city) >= 0) { PotvinPDShiftMove move = new PotvinPDShiftMove( city, i, k, individual); result.Add(move); } } } } } return(result.ToArray()); }
public static PotvinPDExchangeMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) { List <int> cities = new List <int>(); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; for (int i = 1; i <= individual.Cities; i++) { if (pdp == null || pdp.GetDemand(i) >= 0) { cities.Add(i); } } if (cities.Count > 1 && individual.Tours.Count > 1) { PotvinPDExchangeMove move = null; while (cities.Count > 1 && move == null) { int city = cities[rand.Next(cities.Count)]; Tour oldTour = individual.Tours.Find(t => t.Stops.Contains(city)); int oldTourIndex = individual.Tours.IndexOf(oldTour); int max = individual.Tours.Count - 1; int newTourIndex = rand.Next(max); if (newTourIndex >= oldTourIndex) { newTourIndex++; } Tour newTour = individual.Tours[newTourIndex]; List <int> tourCities = new List <int>(); foreach (int stop in newTour.Stops) { if (pdp == null || (pdp.GetDemand(stop) >= 0 && pdp.GetPickupDeliveryLocation(stop) != pdp.GetPickupDeliveryLocation(city) && pdp.GetPickupDeliveryLocation(stop) != city && pdp.GetPickupDeliveryLocation(city) != stop)) { tourCities.Add(stop); } } if (tourCities.Count > 0) { int replaced = tourCities[rand.Next(tourCities.Count)]; move = new PotvinPDExchangeMove(city, oldTourIndex, newTourIndex, replaced, individual); } } return(move); } else { return(null); } }
public override IOperation Apply() { IPickupAndDeliveryProblemInstance pdp = ProblemInstanceParameter.ActualValue as IPickupAndDeliveryProblemInstance; ResultCollection results = ResultsParameter.ActualValue; ItemArray <DoubleValue> qualities = QualityParameter.ActualValue; ItemArray <IntValue> pickupViolations = PickupViolationsParameter.ActualValue; double sigma = SigmaParameter.Value.Value; double phi = PhiParameter.Value.Value; double minPenalty = MinPenaltyFactorParameter.Value.Value; double maxPenalty = MaxPenaltyFactorParameter.Value.Value; for (int j = 0; j < qualities.Length; j++) { qualities[j].Value -= pickupViolations[j].Value * pdp.PickupViolationPenalty.Value; } int validCount = 0; for (int j = 0; j < qualities.Length; j++) { if (pickupViolations[j].Value == 0) { validCount++; } } double factor = 1.0 - ((double)validCount / (double)qualities.Length); double min = pdp.PickupViolationPenalty.Value / (1 + sigma); double max = pdp.PickupViolationPenalty.Value * (1 + phi); pdp.CurrentPickupViolationPenalty = new DoubleValue(min + (max - min) * factor); if (pdp.CurrentPickupViolationPenalty.Value < minPenalty) { pdp.CurrentPickupViolationPenalty.Value = minPenalty; } if (pdp.CurrentPickupViolationPenalty.Value > maxPenalty) { pdp.CurrentPickupViolationPenalty.Value = maxPenalty; } for (int j = 0; j < qualities.Length; j++) { qualities[j].Value += pickupViolations[j].Value * pdp.CurrentPickupViolationPenalty.Value; } if (!results.ContainsKey("Current Pickup Violation Penalty")) { results.Add(new Result("Current Pickup Violation Penalty", new DoubleValue(pdp.CurrentPickupViolationPenalty.Value))); } else { (results["Current Pickup Violation Penalty"].Value as DoubleValue).Value = pdp.CurrentPickupViolationPenalty.Value; } return(base.Apply()); }
protected override void Manipulate(IRandom random, PotvinEncoding individual) { bool allowInfeasible = AllowInfeasibleSolutions.Value.Value; IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance; if (pdp != null) { ApplyManipulation(random, individual, pdp, allowInfeasible); } }
protected override PotvinPDExchangeMove[] GenerateMoves(PotvinEncoding individual, IVRPProblemInstance problemInstance) { List <PotvinPDExchangeMove> result = new List <PotvinPDExchangeMove>(); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; int max = individual.Tours.Count; if (individual.Tours.Count < problemInstance.Vehicles.Value) { max = max - 1; } for (int i = 0; i < individual.Tours.Count; i++) { for (int j = 0; j < individual.Tours[i].Stops.Count; j++) { for (int k = 0; k <= max; k++) { if (k != i) { int city1 = individual.Tours[i].Stops[j]; if (pdp == null || pdp.GetDemand(city1) >= 0) { for (int l = 0; l < individual.Tours[k].Stops.Count; l++) { int city2 = individual.Tours[k].Stops[l]; if (pdp == null || pdp.GetDemand(city2) >= 0) { bool valid = pdp == null || (pdp.GetPickupDeliveryLocation(city2) != pdp.GetPickupDeliveryLocation(city1) && pdp.GetPickupDeliveryLocation(city2) != city1 && pdp.GetPickupDeliveryLocation(city1) != city2); if (valid) { PotvinPDExchangeMove move = new PotvinPDExchangeMove( city1, i, k, city2, individual); result.Add(move); } } } } } } } } return(result.ToArray()); }
protected override void Manipulate(IRandom random, PotvinEncoding individual) { bool allowInfeasible = AllowInfeasibleSolutions.Value.Value; IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance; if (pdp != null) { PotvinEncoding result = ApplyManipulation(random, individual, pdp, allowInfeasible); if (result != null) { VRPToursParameter.ActualValue = result; } } }
protected override PotvinPDRearrangeMove[] GenerateMoves(PotvinEncoding individual, IVRPProblemInstance problemInstance) { List <PotvinPDRearrangeMove> result = new List <PotvinPDRearrangeMove>(); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; for (int i = 1; i <= problemInstance.Cities.Value; i++) { if (pdp == null || pdp.GetDemand(i) >= 0) { int tour = individual.Tours.FindIndex(t => t.Stops.Contains(i)); result.Add(new PotvinPDRearrangeMove(i, tour, individual)); } } return(result.ToArray()); }
public static void Apply(PotvinEncoding solution, PotvinPDExchangeMove move, IVRPProblemInstance problemInstance) { if (move.Tour >= solution.Tours.Count) { solution.Tours.Add(new Tour()); } Tour tour = solution.Tours[move.Tour]; Tour oldTour = solution.Tours.Find(t => t.Stops.Contains(move.City)); oldTour.Stops.Remove(move.City); if (problemInstance is IPickupAndDeliveryProblemInstance) { IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; int location = pdp.GetPickupDeliveryLocation(move.City); Tour oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location)); oldTour2.Stops.Remove(location); location = pdp.GetPickupDeliveryLocation(move.Replaced); oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location)); oldTour2.Stops.Remove(location); tour.Stops.Remove(move.Replaced); solution.InsertPair(tour, move.City, pdp.GetPickupDeliveryLocation(move.City), problemInstance); solution.InsertPair(oldTour, move.Replaced, pdp.GetPickupDeliveryLocation(move.Replaced), problemInstance); } else { tour.Stops.Remove(move.Replaced); int place = solution.FindBestInsertionPlace(tour, move.City); tour.Stops.Insert(place, move.City); place = solution.FindBestInsertionPlace(oldTour, move.Replaced); oldTour.Stops.Insert(place, move.Replaced); } solution.Repair(); }
public static PotvinPDShiftMove Apply(PotvinEncoding individual, IVRPProblemInstance problemInstance, IRandom rand) { List <int> cities = new List <int>(); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; for (int i = 1; i <= individual.Cities; i++) { if (pdp == null || pdp.GetDemand(i) >= 0) { cities.Add(i); } } if (cities.Count >= 1) { int city = cities[rand.Next(cities.Count)]; Tour oldTour = individual.Tours.Find(t => t.Stops.Contains(city)); int oldTourIndex = individual.Tours.IndexOf(oldTour); int max = individual.Tours.Count; if (individual.Tours.Count >= problemInstance.Vehicles.Value) { max = max - 1; } int newTourIndex = rand.Next(max); if (newTourIndex >= oldTourIndex) { newTourIndex++; } return(new PotvinPDShiftMove(city, oldTourIndex, newTourIndex, individual)); } else { return(null); } }
public static void ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) { int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp); if (selectedIndex >= 0) { Tour route1 = individual.Tours[selectedIndex]; int count = route1.Stops.Count; if (count > 0) { int i = random.Next(0, count); int city = route1.Stops[i]; if (!PairwiseMove(individual, pdp, city, allowInfeasible)) i++; count = route1.Stops.Count; } } }
public override IOperation Apply() { ItemList <IItem> tabuList = TabuListParameter.ActualValue; double moveQuality = MoveQualityParameter.ActualValue.Value; bool useAspiration = UseAspirationCriterion.Value; bool isTabu = false; PotvinPDRearrangeMove move = PDRearrangeMoveParameter.ActualValue; foreach (IItem tabuMove in tabuList) { PotvinPDRelocateMoveAttribute attribute = tabuMove as PotvinPDRelocateMoveAttribute; if (attribute != null) { double distance = 0; if (MoveDistanceParameter.ActualValue != null) { distance = MoveDistanceParameter.ActualValue.Value; } double overload = 0; if (MoveOverloadParameter.ActualValue != null) { overload = MoveOverloadParameter.ActualValue.Value; } double tardiness = 0; if (MoveTardinessParameter.ActualValue != null) { tardiness = MoveTardinessParameter.ActualValue.Value; } IVRPProblemInstance instance = ProblemInstanceParameter.ActualValue; double quality = attribute.Distance * instance.DistanceFactor.Value; IHomogenousCapacitatedProblemInstance cvrp = instance as IHomogenousCapacitatedProblemInstance; if (cvrp != null) { quality += attribute.Overload * cvrp.OverloadPenalty.Value; } ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance; if (vrptw != null) { quality += attribute.Tardiness * vrptw.TardinessPenalty.Value; } IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; if (pdp != null) { quality += attribute.PickupViolations * pdp.PickupViolationPenalty.Value; } if (!useAspiration || moveQuality >= quality) { if (attribute.City == move.City && attribute.Tour == move.Tour) { isTabu = true; break; } if (attribute.Distance == distance && attribute.Overload == overload && attribute.Tardiness == tardiness) { isTabu = true; break; } } } } MoveTabuParameter.ActualValue = new BoolValue(isTabu); return(base.Apply()); }
public static bool PairwiseMove(PotvinEncoding individual, IVRPProblemInstance instance, int city, bool allowInfeasible) { bool success; IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; if (pdp != null) { Tour route1 = individual.Tours.Find(t => t.Stops.Contains(city)); int i = route1.Stops.IndexOf(city); int dest = pdp.GetPickupDeliveryLocation(city); Tour destRoute = individual.Tours.Find(t => t.Stops.Contains(dest)); int j = destRoute.Stops.IndexOf(dest); route1.Stops.Remove(city); destRoute.Stops.Remove(dest); int routeToAvoid = -1; if (route1 == destRoute) { routeToAvoid = individual.Tours.IndexOf(route1); } int source, target; if (instance.GetDemand(city) >= 0) { source = city; target = dest; } else { source = dest; target = city; } double bestQuality = double.MaxValue; int bestTour = -1; int bestPositionSource = -1; int bestPositionTarget = -1; for (int tourIdx = 0; tourIdx < individual.Tours.Count; tourIdx++) { if (tourIdx != routeToAvoid) { Tour tour = individual.Tours[tourIdx]; VRPEvaluation eval = instance.EvaluateTour(tour, individual); individual.InsertPair(tour, source, target, instance); VRPEvaluation evalNew = instance.EvaluateTour(tour, individual); double delta = evalNew.Quality - eval.Quality; if (delta < bestQuality && (instance.Feasible(evalNew) || allowInfeasible)) { bestQuality = delta; bestTour = tourIdx; bestPositionSource = tour.Stops.IndexOf(source); bestPositionTarget = tour.Stops.IndexOf(target); } tour.Stops.Remove(source); tour.Stops.Remove(target); } } if (bestTour >= 0) { if (bestPositionTarget < bestPositionSource) { individual.Tours[bestTour].Stops.Insert(bestPositionTarget, target); individual.Tours[bestTour].Stops.Insert(bestPositionSource, source); } else { individual.Tours[bestTour].Stops.Insert(bestPositionSource, source); individual.Tours[bestTour].Stops.Insert(bestPositionTarget, target); } success = true; } else { if (j < i) { destRoute.Stops.Insert(j, dest); route1.Stops.Insert(i, city); } else { route1.Stops.Insert(i, city); destRoute.Stops.Insert(j, dest); } success = false; } } else { success = false; } return(success); }
public static PotvinEncoding ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) { PotvinEncoding result = null; int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp); if (selectedIndex >= 0) { bool performed = false; Tour route1 = individual.Tours[selectedIndex]; if (route1.Stops.Count > 0) { //randomize customer selection Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random); int customer1Position = 0; while (customer1Position < route1.Stops.Count) { performed = false; int customer1 = route1.Stops[perm[customer1Position]]; int customer2 = -1; for (int i = 0; i < individual.Tours.Count; i++) { if (i != selectedIndex) { Tour tour = individual.Tours[i]; for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++) { customer2 = tour.Stops[customer2Position]; if (pdp.GetPickupDeliveryLocation(customer1) != customer2) { result = ReplacePair(individual, pdp, customer2, customer1, allowInfeasible); if (result != null) { individual = result; route1 = individual.Tours[selectedIndex]; performed = true; break; } } } } if (performed) { break; } } if (!performed) customer1Position++; else break; } } } return result; }
public static void ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) { int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp); if (selectedIndex >= 0) { Tour route1 = individual.Tours[selectedIndex]; int count = route1.Stops.Count; if (count > 0) { int i = random.Next(0, count); int city = route1.Stops[i]; if (!PairwiseMove(individual, pdp, city, allowInfeasible)) { i++; } count = route1.Stops.Count; } } }
protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution) { TourInsertionInfo tourInfo = new TourInsertionInfo(solution.GetVehicleAssignment(solution.GetTourIndex(tour))); eval.InsertionInfo.AddTourInsertionInfo(tourInfo); double originalQuality = eval.Quality; IHomogenousCapacitatedProblemInstance cvrpInstance = instance as IHomogenousCapacitatedProblemInstance; DoubleArray demand = instance.Demand; ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance; DoubleArray dueTime = vrptw.DueTime; DoubleArray readyTime = vrptw.ReadyTime; DoubleArray serviceTimes = vrptw.ServiceTime; IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation; double capacity = cvrpInstance.Capacity.Value; double time = 0.0; double waitingTime = 0.0; double serviceTime = 0.0; double tardiness = 0.0; double overweight = 0.0; double distance = 0.0; double currentLoad = 0.0; Dictionary <int, bool> stops = new Dictionary <int, bool>(); int pickupViolations = 0; double tourStartTime = readyTime[0]; time = tourStartTime; //simulate a tour, start and end at depot for (int i = 0; i <= tour.Stops.Count; i++) { int start = 0; if (i > 0) { start = tour.Stops[i - 1]; } int end = 0; if (i < tour.Stops.Count) { end = tour.Stops[i]; } //drive there double currentDistace = vrptw.GetDistance(start, end, solution); time += currentDistace; distance += currentDistace; double arrivalTime = time; //check if it was serviced on time if (time > dueTime[end]) { tardiness += time - dueTime[end]; } //wait double currentWaitingTime = 0.0; if (time < readyTime[end]) { currentWaitingTime = readyTime[end] - time; } double waitTime = readyTime[end] - time; waitingTime += currentWaitingTime; time += currentWaitingTime; double spareTime = dueTime[end] - time; //service double currentServiceTime = serviceTimes[end]; serviceTime += currentServiceTime; time += currentServiceTime; //Pickup / deliver double arrivalSpareCapacity = capacity - currentLoad; bool validPickupDelivery = validPickupDelivery = ((demand[end] >= 0) || (stops.ContainsKey(pickupDeliveryLocation[end]))); if (validPickupDelivery) { currentLoad += demand[end]; } else { pickupViolations++; } if (currentLoad > capacity) { overweight += currentLoad - capacity; } double spareCapacity = capacity - currentLoad; CVRPPDTWInsertionInfo stopInfo = new CVRPPDTWInsertionInfo(start, end, spareCapacity, tourStartTime, arrivalTime, time, spareTime, waitTime, new List <int>(stops.Keys), arrivalSpareCapacity); tourInfo.AddStopInsertionInfo(stopInfo); stops.Add(end, true); } eval.Quality += instance.FleetUsageFactor.Value; eval.Quality += instance.DistanceFactor.Value * distance; eval.Distance += distance; eval.VehicleUtilization += 1; (eval as CVRPEvaluation).Overload += overweight; double tourPenalty = 0; double penalty = overweight * cvrpInstance.OverloadPenalty.Value; eval.Penalty += penalty; eval.Quality += penalty; tourPenalty += penalty; (eval as CVRPTWEvaluation).Tardiness += tardiness; (eval as CVRPTWEvaluation).TravelTime += time; penalty = tardiness * vrptw.TardinessPenalty.Value; eval.Penalty += penalty; eval.Quality += penalty; tourPenalty += penalty; (eval as CVRPPDTWEvaluation).PickupViolations += pickupViolations; penalty = pickupViolations * pdp.PickupViolationPenalty.Value; eval.Penalty += penalty; tourPenalty += penalty; eval.Quality += penalty; eval.Quality += time * vrptw.TimeFactor.Value; tourInfo.Penalty = tourPenalty; tourInfo.Quality = eval.Quality - originalQuality; }
protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, out bool feasible) { CVRPPDTWInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPPDTWInsertionInfo; double costs = 0; feasible = tourInsertionInfo.Penalty < double.Epsilon; bool tourFeasible = true; ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance; double overloadPenalty = cvrp.OverloadPenalty.Value; ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance; DoubleArray dueTime = vrptw.DueTime; DoubleArray readyTime = vrptw.ReadyTime; DoubleArray serviceTimes = vrptw.ServiceTime; double tardinessPenalty = vrptw.TardinessPenalty.Value; IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation; double pickupPenalty = pdp.PickupViolationPenalty.Value; double distance = instance.GetDistance(insertionInfo.Start, insertionInfo.End, solution); double newDistance = instance.GetDistance(insertionInfo.Start, customer, solution) + instance.GetDistance(customer, insertionInfo.End, solution); costs += instance.DistanceFactor.Value * (newDistance - distance); double demand = instance.Demand[customer]; if (demand > insertionInfo.ArrivalSpareCapacity) { tourFeasible = feasible = false; if (insertionInfo.ArrivalSpareCapacity >= 0) { costs += (demand - insertionInfo.ArrivalSpareCapacity) * overloadPenalty; } else { costs += demand * overloadPenalty; } } int destination = pickupDeliveryLocation[customer]; bool validPickup = true; if (demand < 0 && !insertionInfo.Visited.Contains(destination)) { tourFeasible = feasible = false; validPickup = false; costs += pickupPenalty; } double time = 0; double tardiness = 0; if (index > 0) { time = (tourInsertionInfo.GetStopInsertionInfo(index - 1) as CVRPTWInsertionInfo).LeaveTime; } else { time = insertionInfo.TourStartTime; } time += instance.GetDistance(insertionInfo.Start, customer, solution); if (time > dueTime[customer]) { tardiness += time - dueTime[customer]; } if (time < readyTime[customer]) { time += readyTime[customer] - time; } time += serviceTimes[customer]; time += instance.GetDistance(customer, insertionInfo.End, solution); double additionalTime = time - (tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo).ArrivalTime; for (int i = index; i < tourInsertionInfo.GetStopCount(); i++) { CVRPTWInsertionInfo nextStop = tourInsertionInfo.GetStopInsertionInfo(i) as CVRPTWInsertionInfo; if (demand >= 0) { if (nextStop.End == destination) { demand = 0; costs -= pickupPenalty; if (tourInsertionInfo.Penalty == pickupPenalty && tourFeasible) { feasible = true; } } else if (nextStop.SpareCapacity < 0) { costs += demand * overloadPenalty; } else if (nextStop.SpareCapacity < demand) { tourFeasible = feasible = false; costs += (demand - nextStop.SpareCapacity) * overloadPenalty; } } else if (validPickup) { if (nextStop.SpareCapacity < 0) { costs += Math.Max(demand, nextStop.SpareCapacity) * overloadPenalty; } } if (additionalTime < 0) { //arrive earlier than before //wait probably if (nextStop.WaitingTime < 0) { double wait = nextStop.WaitingTime - additionalTime; if (wait > 0) { additionalTime += wait; } } else { additionalTime = 0; } //check due date, decrease tardiness if (nextStop.SpareTime < 0) { costs += Math.Max(nextStop.SpareTime, additionalTime) * tardinessPenalty; } } else { //arrive later than before, probably don't have to wait if (nextStop.WaitingTime > 0) { additionalTime -= Math.Min(additionalTime, nextStop.WaitingTime); } //check due date if (nextStop.SpareTime > 0) { double spare = nextStop.SpareTime - additionalTime; if (spare < 0) { tardiness += -spare; } } else { tardiness += additionalTime; } } } costs += additionalTime * vrptw.TimeFactor.Value; if (tardiness > 0) { tourFeasible = feasible = false; } costs += tardiness * tardinessPenalty; return(costs); }
public static PotvinEncoding CreateSolution(IVRPProblemInstance instance, IRandom random, bool adhereTimeWindows) { PotvinEncoding result = new PotvinEncoding(instance); IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; List <int> customers = new List <int>(); for (int i = 1; i <= instance.Cities.Value; i++) { if (pdp == null || pdp.GetDemand(i) >= 0) { customers.Add(i); } } customers.Sort((city1, city2) => { double angle1 = CalculateAngleToDepot(instance, city1); double angle2 = CalculateAngleToDepot(instance, city2); return(angle1.CompareTo(angle2)); }); Tour currentTour = new Tour(); result.Tours.Add(currentTour); int j = random.Next(customers.Count); for (int i = 0; i < customers.Count; i++) { int index = (i + j) % customers.Count; int stopIdx = 0; if (currentTour.Stops.Count > 0) { stopIdx = result.FindBestInsertionPlace(currentTour, customers[index]); } currentTour.Stops.Insert(stopIdx, customers[index]); if (pdp != null) { stopIdx = result.FindBestInsertionPlace(currentTour, pdp.GetPickupDeliveryLocation(customers[index])); currentTour.Stops.Insert(stopIdx, pdp.GetPickupDeliveryLocation(customers[index])); } CVRPEvaluation evaluation = instance.EvaluateTour(currentTour, result) as CVRPEvaluation; if (result.Tours.Count < instance.Vehicles.Value && ((adhereTimeWindows && !instance.Feasible(evaluation)) || ((!adhereTimeWindows) && evaluation.Overload > double.Epsilon))) { currentTour.Stops.Remove(customers[index]); if (pdp != null) { currentTour.Stops.Remove(pdp.GetPickupDeliveryLocation(customers[index])); } if (currentTour.Stops.Count == 0) { result.Tours.Remove(currentTour); } currentTour = new Tour(); result.Tours.Add(currentTour); currentTour.Stops.Add(customers[index]); if (pdp != null) { currentTour.Stops.Add(pdp.GetPickupDeliveryLocation(customers[index])); } } } if (currentTour.Stops.Count == 0) { result.Tours.Remove(currentTour); } return(result); }
public static PotvinEncoding CreateSolution(IVRPProblemInstance problemInstance, IRandom random, double alphaValue = 0.7, double betaValue = 0.1, double gammaValue = 0.2, double alphaVariance = 0.5, double betaVariance = 0.07, double gammaVariance = 0.14) { PotvinEncoding result = new PotvinEncoding(problemInstance); IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; IMultiDepotProblemInstance mdp = problemInstance as IMultiDepotProblemInstance; double alpha, beta, gamma; alpha = N(alphaValue, Math.Sqrt(alphaVariance), random); beta = N(betaValue, Math.Sqrt(betaVariance), random); gamma = N(gammaValue, Math.Sqrt(gammaVariance), random); List <int> unroutedCustomers = new List <int>(); for (int i = 1; i <= problemInstance.Cities.Value; i++) { if (pdp == null || (problemInstance.GetDemand(i) >= 0)) { unroutedCustomers.Add(i); } } List <int> depots = new List <int>(); if (mdp != null) { for (int i = 0; i < mdp.Depots.Value; i++) { depots.Add(i); } } else { depots.Add(0); } Dictionary <int, List <int> > vehicles = new Dictionary <int, List <int> >(); foreach (int depot in depots) { vehicles[depot] = new List <int>(); int vehicleCount = problemInstance.Vehicles.Value; if (mdp != null) { for (int vehicle = 0; vehicle < mdp.VehicleDepotAssignment.Length; vehicle++) { if (mdp.VehicleDepotAssignment[vehicle] == depot) { vehicles[depot].Add(vehicle); } } } else { for (int vehicle = 0; vehicle < vehicleCount; vehicle++) { vehicles[depot].Add(vehicle); } } } RemoveUnusedDepots(depots, vehicles); Dictionary <int, int> depotAssignment = new Dictionary <int, int>(); unroutedCustomers = SortCustomers( problemInstance, unroutedCustomers, depots, depotAssignment, alpha, beta, gamma); ///////// Tour tour = new Tour(); result.Tours.Add(tour); int currentCustomer = unroutedCustomers[0]; unroutedCustomers.RemoveAt(0); int currentDepot = depotAssignment[currentCustomer]; int currentVehicle = vehicles[currentDepot][0]; vehicles[currentDepot].RemoveAt(0); if (RemoveUnusedDepots(depots, vehicles)) { unroutedCustomers = SortCustomers( problemInstance, unroutedCustomers, depots, depotAssignment, alpha, beta, gamma); } result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle; tour.Stops.Add(currentCustomer); if (pdp != null) { tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer)); } //////// while (unroutedCustomers.Count > 0) { double minimumCost = double.MaxValue; int customer = -1; int indexOfMinimumCost = -1; int indexOfMinimumCost2 = -1; foreach (int unrouted in unroutedCustomers) { VRPEvaluation eval = problemInstance.EvaluateTour(tour, result); double originalCosts = eval.Quality; for (int i = 0; i <= tour.Stops.Count; i++) { tour.Stops.Insert(i, unrouted); eval = problemInstance.EvaluateTour(tour, result); double tourCost = eval.Quality - originalCosts; if (pdp != null) { for (int j = i + 1; j <= tour.Stops.Count; j++) { bool feasible; double cost = tourCost + problemInstance.GetInsertionCosts(eval, result, pdp.GetPickupDeliveryLocation(unrouted), 0, j, out feasible); if (cost < minimumCost && feasible) { customer = unrouted; minimumCost = cost; indexOfMinimumCost = i; indexOfMinimumCost2 = j; } } } else { double cost = tourCost; bool feasible = problemInstance.Feasible(eval); if (cost < minimumCost && feasible) { customer = unrouted; minimumCost = cost; indexOfMinimumCost = i; } } tour.Stops.RemoveAt(i); } } if (indexOfMinimumCost == -1 && vehicles.Count == 0) { indexOfMinimumCost = tour.Stops.Count; indexOfMinimumCost2 = tour.Stops.Count + 1; customer = unroutedCustomers[0]; } // insert customer if found if (indexOfMinimumCost != -1) { tour.Stops.Insert(indexOfMinimumCost, customer); if (pdp != null) { tour.Stops.Insert(indexOfMinimumCost2, pdp.GetPickupDeliveryLocation(customer)); } unroutedCustomers.Remove(customer); } else // no feasible customer found { tour = new Tour(); result.Tours.Add(tour); currentCustomer = unroutedCustomers[0]; unroutedCustomers.RemoveAt(0); currentDepot = depotAssignment[currentCustomer]; currentVehicle = vehicles[currentDepot][0]; vehicles[currentDepot].RemoveAt(0); if (RemoveUnusedDepots(depots, vehicles)) { unroutedCustomers = SortCustomers( problemInstance, unroutedCustomers, depots, depotAssignment, alpha, beta, gamma); } result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle; tour.Stops.Add(currentCustomer); if (pdp != null) { tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer)); } } } if (mdp != null) { List <int> availableVehicles = new List <int>(); for (int i = 0; i < mdp.Vehicles.Value; i++) { availableVehicles.Add(i); } for (int i = 0; i < result.VehicleAssignment.Length; i++) { if (result.VehicleAssignment[i] != -1) { availableVehicles.Remove(result.VehicleAssignment[i]); } } for (int i = 0; i < result.VehicleAssignment.Length; i++) { if (result.VehicleAssignment[i] == -1) { result.VehicleAssignment[i] = availableVehicles[0]; availableVehicles.RemoveAt(0); } } } return(result); }
private static PotvinEncoding ReplacePair(PotvinEncoding individual, IVRPProblemInstance instance, int replaced, int replacing, bool allowInfeasible) { individual = individual.Clone() as PotvinEncoding; IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance; int replacedDest = pdp.GetPickupDeliveryLocation(replaced); int replacedSource, replacedTarget; if (pdp.GetDemand(replaced) >= 0) { replacedSource = replaced; replacedTarget = replacedDest; } else { replacedSource = replacedDest; replacedTarget = replaced; } Tour replacedSourceTour = individual.Tours.Find(t => t.Stops.Contains(replacedSource)); Tour replacedTargetTour = individual.Tours.Find(t => t.Stops.Contains(replacedTarget)); int replacingDest = pdp.GetPickupDeliveryLocation(replacing); int replacingSource, replacingTarget; if (pdp.GetDemand(replacing) >= 0) { replacingSource = replacing; replacingTarget = replacingDest; } else { replacingSource = replacingDest; replacingTarget = replacing; } Tour replacingSourceTour = individual.Tours.Find(t => t.Stops.Contains(replacingSource)); Tour replacingTargetTour = individual.Tours.Find(t => t.Stops.Contains(replacingTarget)); replacingSourceTour.Stops.Remove(replacingSource); replacingTargetTour.Stops.Remove(replacingTarget); replacedSourceTour.Stops[replacedSourceTour.Stops.IndexOf(replacedSource)] = replacingSource; if (!allowInfeasible && !instance.TourFeasible(replacedSourceTour, individual)) { return(null); } replacedTargetTour.Stops[replacedTargetTour.Stops.IndexOf(replacedTarget)] = replacingTarget; if (!allowInfeasible && !instance.TourFeasible(replacedTargetTour, individual)) { return(null); } double bestQuality = double.MaxValue; int bestTour = -1; int bestPositionSource = -1; int bestPositionTarget = -1; int routeToAvoid = individual.Tours.IndexOf(replacingSourceTour); for (int tourIdx = 0; tourIdx < individual.Tours.Count; tourIdx++) { if (tourIdx != routeToAvoid) { Tour tour = individual.Tours[tourIdx]; VRPEvaluation eval = instance.EvaluateTour(tour, individual); individual.InsertPair(tour, replacedSource, replacedTarget, instance); VRPEvaluation evalNew = instance.EvaluateTour(tour, individual); double delta = evalNew.Quality - eval.Quality; if (delta < bestQuality && (instance.Feasible(evalNew) || allowInfeasible)) { bestQuality = delta; bestTour = tourIdx; bestPositionSource = tour.Stops.IndexOf(replacedSource); bestPositionTarget = tour.Stops.IndexOf(replacedTarget); } tour.Stops.Remove(replacedSource); tour.Stops.Remove(replacedTarget); } } if (bestTour != -1) { if (bestPositionTarget < bestPositionSource) { individual.Tours[bestTour].Stops.Insert(bestPositionTarget, replacedTarget); individual.Tours[bestTour].Stops.Insert(bestPositionSource, replacedSource); } else { individual.Tours[bestTour].Stops.Insert(bestPositionSource, replacedSource); individual.Tours[bestTour].Stops.Insert(bestPositionTarget, replacedTarget); } return(individual); } else { return(null); } }
public static PotvinEncoding ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) { PotvinEncoding result = null; int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp); if (selectedIndex >= 0) { bool performed = false; Tour route1 = individual.Tours[selectedIndex]; if (route1.Stops.Count > 0) { //randomize customer selection Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random); int customer1Position = 0; while (customer1Position < route1.Stops.Count) { performed = false; int customer1 = route1.Stops[perm[customer1Position]]; int customer2 = -1; for (int i = 0; i < individual.Tours.Count; i++) { if (i != selectedIndex) { Tour tour = individual.Tours[i]; for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++) { customer2 = tour.Stops[customer2Position]; if (pdp.GetPickupDeliveryLocation(customer1) != customer2) { result = ReplacePair(individual, pdp, customer2, customer1, allowInfeasible); if (result != null) { individual = result; route1 = individual.Tours[selectedIndex]; performed = true; break; } } } } if (performed) { break; } } if (!performed) { customer1Position++; } else { break; } } } } return(result); }
public static void Apply(PotvinEncoding solution, PotvinPDShiftMove move, IVRPProblemInstance problemInstance) { bool newTour = false; if (move.Tour >= solution.Tours.Count) { solution.Tours.Add(new Tour()); newTour = true; } Tour tour = solution.Tours[move.Tour]; Tour oldTour = solution.Tours.Find(t => t.Stops.Contains(move.City)); oldTour.Stops.Remove(move.City); if (problemInstance is IPickupAndDeliveryProblemInstance) { IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance; int location = pdp.GetPickupDeliveryLocation(move.City); Tour oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location)); oldTour2.Stops.Remove(location); solution.InsertPair(tour, move.City, location, problemInstance); } else { int place = solution.FindBestInsertionPlace(tour, move.City); tour.Stops.Insert(place, move.City); } if (newTour) { List <int> vehicles = new List <int>(); for (int i = move.Tour; i < problemInstance.Vehicles.Value; i++) { vehicles.Add(solution.GetVehicleAssignment(i)); } double bestQuality = double.MaxValue; int bestVehicle = -1; int originalVehicle = solution.GetVehicleAssignment(move.Tour); foreach (int vehicle in vehicles) { solution.VehicleAssignment[move.Tour] = vehicle; double quality = problemInstance.EvaluateTour(tour, solution).Quality; if (quality < bestQuality) { bestQuality = quality; bestVehicle = vehicle; } } solution.VehicleAssignment[move.Tour] = originalVehicle; int index = -1; for (int i = move.Tour; i < solution.VehicleAssignment.Length; i++) { if (solution.VehicleAssignment[i] == bestVehicle) { index = i; break; } } solution.VehicleAssignment[index] = originalVehicle; solution.VehicleAssignment[move.Tour] = bestVehicle; } solution.Repair(); }