Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/Manipulators/PotvinCustomerRelocationManipulator.cs @ 8670

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

Added first version of the dynamic vehicle routing addon (#1955)

File size: 9.4 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 System.Linq;
31
32namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
33  [Item("PotvinCustomerRelocationMainpulator", "A customer relocation operator")]
34  [StorableClass]
35  public sealed class PotvinCustomerRelocationMainpulator : PotvinManipulator, IPickupAndDeliveryOperator {
36    [StorableConstructor]
37    private PotvinCustomerRelocationMainpulator(bool deserializing) : base(deserializing) { }
38
39    public PotvinCustomerRelocationMainpulator() : base() { }
40
41    public override IDeepCloneable Clone(Cloner cloner) {
42      return new PotvinCustomerRelocationMainpulator(this, cloner);
43    }
44
45    private PotvinCustomerRelocationMainpulator(PotvinCustomerRelocationMainpulator original, Cloner cloner)
46      : base(original, cloner) {
47    }
48
49    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
50      bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
51      bool performed = false;
52
53      int selectedIndex;
54      Tour route1;
55
56      int mode = random.Next(0,3);
57
58      //Try pickup and delivery first
59      IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance;
60      if (pdp != null && mode == 0) {
61        selectedIndex = SelectRandomTourBiasedByLength(random, individual);
62        route1 =
63          individual.Tours[selectedIndex];
64
65        List<int> deliveryViolations = new List<int>();
66
67        Dictionary<int, bool> visited = new Dictionary<int, bool>();
68        for (int i = 0; i < route1.Stops.Count; i++) {
69          int stop = route1.Stops[i];
70          if (ProblemInstance.GetDemand(stop) < 0
71            && pdp.GetPickupDeliveryLocation(stop) != stop) {
72            int source = pdp.GetPickupDeliveryLocation(stop);
73            if (source > 0) {
74              if (!visited.ContainsKey(source))
75                deliveryViolations.Add(stop);
76            } else {
77              if (-source != individual.GetVehicleAssignment(selectedIndex))
78                deliveryViolations.Add(stop);
79            }
80          }
81
82          visited.Add(stop, true);
83        }
84
85        if (deliveryViolations.Count > 0) {
86          int selected =
87            deliveryViolations[random.Next(deliveryViolations.Count)];
88
89          int source = pdp.GetPickupDeliveryLocation(selected);
90         
91          //find route of source
92          Tour found = null;
93
94          if (source > 0) {
95            foreach (Tour tour in individual.Tours) {
96              if (tour.Stops.Contains(source)) {
97                found = tour;
98                break;
99              }
100            }
101          } else {
102            int vehicle = -source;
103            int tourIdx = new List<int>(individual.VehicleAssignment).IndexOf(vehicle);
104            if (tourIdx < individual.Tours.Count)
105              found = individual.Tours[tourIdx];
106            else {
107              found = new Tour();
108              int tmp = individual.VehicleAssignment[individual.Tours.Count];
109              individual.VehicleAssignment[individual.Tours.Count] = vehicle;
110              individual.VehicleAssignment[tourIdx] = tmp;
111              individual.Tours.Add(found);
112            }
113          }
114
115          if (found != null) {
116            double rand = random.NextDouble();
117            if (rand < 0.33 || source <= 0) {
118              route1.Stops.Remove(selected);
119
120              int index = individual.FindBestInsertionPlace(found, selected);
121              found.Stops.Insert(index, selected);
122              performed = true;
123
124              if (route1.Stops.Count == 0)
125                individual.Tours.Remove(route1);
126            } else if (rand < 0.66) {
127              found.Stops.Remove(source);
128
129              int index = individual.FindBestInsertionPlace(route1, source);
130              route1.Stops.Insert(index, source);
131              performed = true;
132
133              if (found.Stops.Count == 0)
134                individual.Tours.Remove(found);
135            } else {
136              found.Stops.Remove(source);
137              route1.Stops.Remove(selected);
138
139              int chosenRoute = random.Next(individual.Tours.Count);
140              Tour tour = individual.Tours[chosenRoute];
141
142              int index = individual.FindBestInsertionPlace(tour, source);
143              tour.Stops.Insert(index, source);
144              index = individual.FindBestInsertionPlace(tour, selected);
145              tour.Stops.Insert(index, selected);
146
147              if (found.Stops.Count == 0)
148                individual.Tours.Remove(found);
149              if (route1.Stops.Count == 0)
150                individual.Tours.Remove(route1);
151            }
152          }
153        }
154      }
155
156      //then try tw
157      if (!performed && mode == 1) {
158        ITimeWindowedProblemInstance vrptw = ProblemInstance as ITimeWindowedProblemInstance;
159
160        if (vrptw != null) {
161          selectedIndex = SelectRandomTourBiasedByLength(random, individual);
162          route1 =
163            individual.Tours[selectedIndex];
164
165          List<int> timeWindowViolations = new List<int>();
166
167          int depots = 1;
168          DoubleArray dueTime = vrptw.DueTime;
169          DoubleArray readyTime = vrptw.ReadyTime;
170          DoubleArray serviceTimes = vrptw.ServiceTime;
171
172          int depot = 0;
173          IMultiDepotProblemInstance mdp = ProblemInstance as IMultiDepotProblemInstance;
174          if (mdp != null) {
175            IntArray vehicleAssignment = mdp.VehicleDepotAssignment;
176            int vehicle = individual.GetVehicleAssignment(selectedIndex);
177            depot = vehicleAssignment[vehicle];
178            depots = mdp.Depots.Value;
179          }
180
181          double time = readyTime[depot];
182
183          for (int i = 0; i < route1.Stops.Count; i++) {
184            int start = 0;
185            if (i > 0)
186              start = route1.Stops[i - 1];
187            int end = 0;
188            if (i < route1.Stops.Count)
189              end = route1.Stops[i];
190
191            //drive there
192            double currentDistace = vrptw.GetDistance(start, end, individual);
193            time += currentDistace;
194
195            int endIndex;
196            if (end == 0)
197              endIndex = depot;
198            else
199              endIndex = end + depots - 1;
200
201            //check if it was serviced on time
202            if (time > dueTime[endIndex]) {
203              timeWindowViolations.Add(end);
204            }
205
206            //wait
207            double currentWaitingTime = 0.0;
208            if (time < readyTime[endIndex])
209              currentWaitingTime = readyTime[endIndex] - time;
210            time += currentWaitingTime;
211
212            //service
213            double currentServiceTime = serviceTimes[end-1];
214            time += currentServiceTime;
215          }
216
217          if (timeWindowViolations.Count > 0) {
218            int selected =
219              timeWindowViolations[random.Next(timeWindowViolations.Count)];
220
221            int oldIndex = route1.Stops.IndexOf(selected);
222            route1.Stops.Remove(selected);
223
224            int route, place;
225            if (FindInsertionPlace(individual, selected, -1, allowInfeasible, out route, out place)) {
226              Tour newTour = individual.Tours[route];
227              newTour.Stops.Insert(place, selected);
228              performed = true;
229            } else {
230              route1.Stops.Insert(oldIndex, selected);
231            }
232
233            if (route1.Stops.Count == 0)
234              individual.Tours.Remove(route1);
235          }
236        }
237      }
238
239      //finally relocate random customer
240      if (!performed) {
241        selectedIndex = SelectRandomTourBiasedByLength(random, individual);
242        route1 =
243          individual.Tours[selectedIndex];
244
245        int selected = route1.Stops[random.Next(route1.Stops.Count)];
246        int oldIndex = route1.Stops.IndexOf(selected);
247        route1.Stops.Remove(selected);
248
249        int route, place;
250        if (FindInsertionPlace(individual, selected, selectedIndex, allowInfeasible, out route, out place)) {
251          Tour tour = individual.Tours[route];
252          tour.Stops.Insert(place, selected);
253          performed = true;
254        } else {
255          route1.Stops.Insert(oldIndex, selected);
256        }
257
258        if (route1.Stops.Count == 0)
259          individual.Tours.Remove(route1);
260      }
261    }
262  }
263}
Note: See TracBrowser for help on using the repository browser.