Free cookie consent management tool by TermsFeed Policy Generator

source: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinPairwiseTwoLevelExchangeManipulator.cs @ 6967

Last change on this file since 6967 was 6967, checked in by svonolfe, 12 years ago

Fixed small issue in pairwise manipulator (#1177)

File size: 7.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HeuristicLab.Core;
23using HeuristicLab.Encodings.PermutationEncoding;
24using HeuristicLab.Parameters;
25using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
26using HeuristicLab.Data;
27using System.Collections.Generic;
28using HeuristicLab.Common;
29using HeuristicLab.Problems.VehicleRouting.Variants;
30using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
31
32namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
33  [Item("PotvinPairwiseTwoLevelExchangeManipulator", "The 2M operator which manipulates a VRP representation.  It is implemented as described in Potvin, J.-Y. and Bengio, S. (1996). The Vehicle Routing Problem with Time Windows - Part II: Genetic Search. INFORMS Journal of Computing, 8:165–172.  It was adapted to the PDP formulation.")]
34  [StorableClass]
35  public sealed class PotvinPairwiseTwoLevelExchangeManipulator : PotvinManipulator {
36    [StorableConstructor]
37    private PotvinPairwiseTwoLevelExchangeManipulator(bool deserializing) : base(deserializing) { }
38
39    public PotvinPairwiseTwoLevelExchangeManipulator() : base() { }
40
41    public override IDeepCloneable Clone(Cloner cloner) {
42      return new PotvinPairwiseTwoLevelExchangeManipulator(this, cloner);
43    }
44
45    private PotvinPairwiseTwoLevelExchangeManipulator(PotvinPairwiseTwoLevelExchangeManipulator original, Cloner cloner)
46      : base(original, cloner) {
47    }
48
49    private PotvinEncoding ReplacePair(PotvinEncoding individual, int replaced, int replacing, bool allowInfeasible) {
50      individual = individual.Clone() as PotvinEncoding;
51      IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance;
52
53      int replacedDest = pdp.GetPickupDeliveryLocation(replaced);
54      int replacedSource, replacedTarget;
55      if (pdp.GetDemand(replaced) >= 0) {
56        replacedSource = replaced;
57        replacedTarget = replacedDest;
58      } else {
59        replacedSource = replacedDest;
60        replacedTarget = replaced;
61      }
62      Tour replacedSourceTour = individual.Tours.Find(t => t.Stops.Contains(replacedSource));
63      Tour replacedTargetTour = individual.Tours.Find(t => t.Stops.Contains(replacedTarget));
64
65      int replacingDest = pdp.GetPickupDeliveryLocation(replacing);
66      int replacingSource, replacingTarget;
67      if (pdp.GetDemand(replacing) >= 0) {
68        replacingSource = replacing;
69        replacingTarget = replacingDest;
70      } else {
71        replacingSource = replacingDest;
72        replacingTarget = replacing;
73      }
74      Tour replacingSourceTour = individual.Tours.Find(t => t.Stops.Contains(replacingSource));
75      Tour replacingTargetTour = individual.Tours.Find(t => t.Stops.Contains(replacingTarget));
76
77      replacingSourceTour.Stops.Remove(replacingSource);
78      replacingTargetTour.Stops.Remove(replacingTarget);
79
80      replacedSourceTour.Stops[replacedSourceTour.Stops.IndexOf(replacedSource)] = replacingSource;
81      if (!allowInfeasible && !ProblemInstance.TourFeasible(replacedSourceTour, individual))
82        return null;
83
84      replacedTargetTour.Stops[replacedTargetTour.Stops.IndexOf(replacedTarget)] = replacingTarget;
85      if (!allowInfeasible && !ProblemInstance.TourFeasible(replacedTargetTour, individual))
86        return null;
87
88      double bestQuality = double.MaxValue;
89      int bestTour = -1;
90      int bestPositionSource = -1;
91      int bestPositionTarget = -1;
92
93      int routeToAvoid = individual.Tours.IndexOf(replacingSourceTour);
94
95      for (int tourIdx = 0; tourIdx < individual.Tours.Count; tourIdx++) {
96        if (tourIdx != routeToAvoid) {
97          Tour tour = individual.Tours[tourIdx];
98          VRPEvaluation eval = ProblemInstance.EvaluateTour(tour, individual);
99          individual.InsertPair(tour, replacedSource, replacedTarget, ProblemInstance);
100          VRPEvaluation evalNew = ProblemInstance.EvaluateTour(tour, individual);
101
102          double delta = evalNew.Quality - eval.Quality;
103
104          if (delta < bestQuality &&
105              (ProblemInstance.Feasible(evalNew) || allowInfeasible)) {
106            bestQuality = delta;
107            bestTour = tourIdx;
108            bestPositionSource = tour.Stops.IndexOf(replacedSource);
109            bestPositionTarget = tour.Stops.IndexOf(replacedTarget);
110          }
111
112          tour.Stops.Remove(replacedSource);
113          tour.Stops.Remove(replacedTarget);
114        }
115      }
116
117      if (bestTour != -1) {
118        if (bestPositionTarget < bestPositionSource) {
119          individual.Tours[bestTour].Stops.Insert(bestPositionTarget, replacedTarget);
120          individual.Tours[bestTour].Stops.Insert(bestPositionSource, replacedSource);
121        } else {
122          individual.Tours[bestTour].Stops.Insert(bestPositionSource, replacedSource);
123          individual.Tours[bestTour].Stops.Insert(bestPositionTarget, replacedTarget);
124        }
125
126        return individual;
127      } else {
128        return null;
129      }
130    }
131
132    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
133      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
134      IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance;
135
136      if (pdp != null) {
137        int selectedIndex = SelectRandomTourBiasedByLength(random, individual);
138        if (selectedIndex >= 0) {
139          bool performed = false;
140          Tour route1 = individual.Tours[selectedIndex];
141
142          if (route1.Stops.Count > 0) {
143            //randomize customer selection
144            Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random);
145            int customer1Position = 0;
146
147            while (customer1Position < route1.Stops.Count) {
148              performed = false;
149
150              int customer1 = route1.Stops[perm[customer1Position]];
151              int customer2 = -1;
152
153              for (int i = 0; i < individual.Tours.Count; i++) {
154                if (i != selectedIndex) {
155                  Tour tour = individual.Tours[i];
156                  for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++) {
157                    customer2 = tour.Stops[customer2Position];
158
159                    if (pdp.GetPickupDeliveryLocation(customer1) != customer2) {
160                      PotvinEncoding result = ReplacePair(individual, customer2, customer1, allowInfeasible);
161                      if (result != null) {
162                        VRPToursParameter.ActualValue = result;
163                        individual = result;
164
165                        route1 = individual.Tours[selectedIndex];
166                        performed = true;
167                        break;
168                      }
169                    }
170                  }
171                }
172
173                if (performed) {
174                  break;
175                }
176              }
177
178              if (!performed)
179                customer1Position++;
180              else
181                break;
182            }
183          }
184        }
185      }
186    }
187  }
188}
Note: See TracBrowser for help on using the repository browser.