Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ParameterBinding/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Prins/Manipulators/PrinsLSManipulator.cs @ 4745

Last change on this file since 4745 was 4722, checked in by swagner, 14 years ago

Merged cloning refactoring branch back into trunk (#922)

File size: 13.5 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 System.Collections.Generic;
23using HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Parameters;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Problems.VehicleRouting.Encodings.Prins {
30  [Item("PrinsLSManipulator", "An operator which manipulates a VRP representation by using the Prins local search.  It is implemented as described in Prins, C. (2004). A simple and effective evolutionary algorithm for the vehicle routing problem. Computers & Operations Research, 12:1985-2002.")]
31  [StorableClass]
32  public abstract class PrinsLSManipulator : PrinsManipulator {
33    public IValueParameter<IntValue> Iterations {
34      get { return (IValueParameter<IntValue>)Parameters["Iterations"]; }
35    }
36       
37    [StorableConstructor]
38    protected PrinsLSManipulator(bool deserializing) : base(deserializing) { }
39    protected PrinsLSManipulator(PrinsLSManipulator original, Cloner cloner) : base(original, cloner) { }
40    public PrinsLSManipulator()
41      : base() {
42      Parameters.Add(new ValueParameter<IntValue>("Iterations", "The number of max iterations.", new IntValue(5)));
43    }
44
45    protected double GetQuality(PrinsEncoding individual) {
46      return VRPEvaluator.Evaluate(individual,
47        VehiclesParameter.ActualValue,
48        DueTimeParameter.ActualValue,
49        ServiceTimeParameter.ActualValue,
50        ReadyTimeParameter.ActualValue,
51        DemandParameter.ActualValue,
52        CapacityParameter.ActualValue,
53        FleetUsageFactor.ActualValue,
54        TimeFactor.ActualValue,
55        DistanceFactor.ActualValue,
56        OverloadPenalty.ActualValue,
57        TardinessPenalty.ActualValue,
58        CoordinatesParameter.ActualValue,
59        DistanceMatrixParameter,
60        UseDistanceMatrixParameter.ActualValue).Quality;
61    }
62
63    private int FindCity(PrinsEncoding individual, int city) {
64      int index = -1;
65
66      int i = 0;
67      while (i < individual.Length && index == -1) {
68        if (individual[i] == city)
69          index = i;
70       
71        i++;
72      }
73
74      return index;
75    }
76
77    protected const int depot = -1;
78
79    private Tour FindTour(PrinsEncoding individual, int city) {
80      Tour found = null;
81
82      List<Tour> tours = individual.GetTours(DistanceMatrixParameter);
83      int i = 0;
84
85      while (found == null && i < tours.Count) {
86        if (tours[i].Cities.Contains(city))
87          found = tours[i];
88       
89        i++;
90      }
91
92      return found;
93    }
94
95    //inserts u after v in the child
96    private void InsertAfter(int u, int v, PrinsEncoding parent, PrinsEncoding child) {
97      int pi = 0;
98      int ci = 0;
99
100      while (ci != child.Length) {
101        if (parent[pi] != u) {
102          child[ci] = parent[pi];
103          ci++;
104        }
105        if (parent[pi] == v) {
106          child[ci] = u;
107          ci++;
108        }
109
110        pi++;
111      }
112    }
113
114    //inserts (u, x) after v in the child
115    private void InsertAfter(int u, int x, int v, PrinsEncoding parent, PrinsEncoding child) {
116      int pi = 0;
117      int ci = 0;
118
119      while (ci != child.Length) {
120        if (parent[pi] != u && parent[pi] != x) {
121          child[ci] = parent[pi];
122          ci++;
123        }
124        if (parent[pi] == v) {
125          child[ci] = u;
126          ci++;
127
128          child[ci] = x;
129          ci++;
130        }
131
132        pi++;
133      }
134    }
135
136    //inserts u before v in the child
137    private void InsertBefore(int u, int v, PrinsEncoding parent, PrinsEncoding child) {
138      int pi = 0;
139      int ci = 0;
140
141      while (ci != child.Length) {
142        if (parent[pi] == v) {
143          child[ci] = u;
144          ci++;
145        }
146        if (parent[pi] != u) {
147          child[ci] = parent[pi];
148          ci++;
149        }
150
151        pi++;
152      }
153    }
154
155    //inserts (u, x) before v in the child
156    private void InsertBefore(int u, int x, int v, PrinsEncoding parent, PrinsEncoding child) {
157      int pi = 0;
158      int ci = 0;
159
160      while (ci != child.Length) {
161        if (parent[pi] == v) {
162          child[ci] = u;
163          ci++;
164
165          child[ci] = x;
166          ci++;
167        }
168        if (parent[pi] != u && parent[pi] != x) {
169          child[ci] = parent[pi];
170          ci++;
171        }
172
173        pi++;
174      }
175    }
176
177    //swaps u and v
178    private void Swap(int u, int v, PrinsEncoding parent, PrinsEncoding child) {
179      for (int i = 0; i < child.Length; i++) {
180        if (parent[i] == u)
181          child[i] = v;
182        else if (parent[i] == v)
183          child[i] = u;
184        else
185          child[i] = parent[i];
186      }
187    }
188
189    //swaps (u, x) and v
190    private void Swap(int u, int x, int v, PrinsEncoding parent, PrinsEncoding child) {
191      int childIndex = 0;
192      int parentIndex = 0;
193
194      while(childIndex < child.Length) {
195        if (parent[parentIndex] == u) {
196          child[childIndex] = v;
197          parentIndex++;
198        } else if (parent[parentIndex] == v) {
199          child[childIndex] = u;
200          childIndex++;
201          child[childIndex] = x;
202        } else {
203          child[childIndex] = parent[parentIndex];
204        }
205
206        childIndex++;
207        parentIndex++;
208      }
209    }
210
211    //swaps (u, x) and (v, y)
212    private void Swap(int u, int x, int v, int y, PrinsEncoding parent, PrinsEncoding child) {
213      int i = 0;
214
215      while (i < child.Length) {
216        if (child[i] == u) {
217          child[i] = v;
218          i++;
219          child[i] = y;
220        } else if (child[i] == v) {
221          child[i] = u;
222          i++;
223          child[i] = x;
224        } else {
225          child[i] = parent[i];
226        }
227
228        i++;
229      }
230    }
231
232    //swaps (u, x) and (v, y) by (u, y) and (x, v)
233    private void Swap2(int u, int x, int v, int y, PrinsEncoding parent, PrinsEncoding child) {
234      int i = 0;
235
236      while (i < child.Length) {
237        if(parent[i] == x) {
238          child[i] = y;
239        } else if(parent[i] == v) {
240          child[i] = x;
241        } else if(parent[i] == y) {
242          child[i] = v;
243        } else {
244          child[i] = parent[i];
245        }
246
247        i++;
248      }
249    }
250
251    private void M1(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
252      if (u != depot) {
253        if (v == depot) {
254          Tour tour = FindTour(child, u + 1);
255          v = tour.Cities[0] - 1;
256          InsertBefore(u, v, parent, child);
257        } else {
258          InsertAfter(u, v, parent, child);
259        }
260      }
261    }
262
263    private void M2(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
264      if (u != depot) {
265        Tour tour = FindTour(child, u + 1);
266        int iu = tour.Cities.IndexOf(u + 1);
267        if (iu < tour.Cities.Count - 1) {
268          int x = tour.Cities[iu + 1] - 1;
269
270          if (v == depot) {
271            tour = FindTour(child, u + 1);
272            v = tour.Cities[0] - 1;
273            InsertBefore(u, x, v, parent, child);
274          } else {
275            InsertAfter(u, x, v, parent, child);
276          }
277        }
278      }
279    }
280
281    private void M3(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
282      if (u != depot) {
283        Tour tour = FindTour(child, u + 1);
284        int iu = tour.Cities.IndexOf(u + 1);
285        if (iu < tour.Cities.Count - 1) {
286          int x = tour.Cities[iu + 1] - 1;
287
288          if (v == depot) {
289            tour = FindTour(child, u + 1);
290            v = tour.Cities[0] - 1;
291            InsertBefore(x, u, v, parent, child);
292          } else {
293            InsertAfter(x, u, v, parent, child);
294          }
295        }
296      }
297    }
298
299    private void M4(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
300      if (u != depot && v != depot) {
301        Swap(u, v, parent, child);
302      }
303    }
304
305    private void M5(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
306      if (u != depot && v != depot) {
307        Tour tour = FindTour(child, u + 1);
308        int iu = tour.Cities.IndexOf(u + 1);
309        if (iu < tour.Cities.Count - 1) {
310          int x = tour.Cities[iu + 1] - 1;
311
312          if(x != v)
313            Swap(u, x, v, parent, child);
314        }
315      }
316    }
317
318    private void M6(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
319      if (u != depot && v != depot) {
320        Tour tour = FindTour(child, u + 1);
321        int iu = tour.Cities.IndexOf(u + 1);
322        if (iu < tour.Cities.Count - 1) {
323          int x = tour.Cities[iu + 1] - 1;
324
325          tour = FindTour(child, v + 1);
326          int iv = tour.Cities.IndexOf(v + 1);
327          if (iv < tour.Cities.Count - 1) {
328            int y = tour.Cities[iv + 1] - 1;
329
330            if (x != v && y != u)
331              Swap(u, x, v, y, parent, child);
332          }
333        }
334      }
335    }
336
337    private void M7(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
338      if (u != depot && v != depot) {
339        Tour tu = FindTour(child, u + 1);
340        Tour tv = FindTour(child, v + 1);
341
342        if (tu.Cities[0] == tv.Cities[0]) {
343          int iu = tu.Cities.IndexOf(u + 1);
344          if (iu < tu.Cities.Count - 1) {
345            int x = tu.Cities[iu + 1] - 1;
346
347            int iv = tv.Cities.IndexOf(v + 1);
348            if (iv < tv.Cities.Count - 1) {
349              int y = tv.Cities[iv + 1] - 1;
350
351              if (x != v && y != u)
352                Swap(x, v, parent, child);
353             }
354           }
355        }
356      }
357    }
358
359    private void M8(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
360      if (u != depot && v != depot) {
361        Tour tu = FindTour(child, u + 1);
362        Tour tv = FindTour(child, v + 1);
363
364        if (tu.Cities[0] != tv.Cities[0]) {
365          int iu = tu.Cities.IndexOf(u + 1);
366          if (iu < tu.Cities.Count - 1) {
367            int x = tu.Cities[iu + 1] - 1;
368
369            int iv = tv.Cities.IndexOf(v + 1);
370            if (iv < tv.Cities.Count - 1) {
371              int y = tv.Cities[iv + 1] - 1;
372
373              if (x != v && y != u)
374                Swap(x, v, parent, child);
375            }
376          }
377        }
378      }
379    }
380
381    private void M9(PrinsEncoding parent, PrinsEncoding child, int u, int v) {
382      if (u != depot && v != depot) {
383        Tour tu = FindTour(child, u + 1);
384        Tour tv = FindTour(child, v + 1);
385
386        if (tu.Cities[0] != tv.Cities[0]) {
387          int iu = tu.Cities.IndexOf(u + 1);
388          if (iu < tu.Cities.Count - 1) {
389            int x = tu.Cities[iu + 1] - 1;
390
391            int iv = tv.Cities.IndexOf(v + 1);
392            if (iv < tv.Cities.Count - 1) {
393              int y = tv.Cities[iv + 1] - 1;
394
395              if (x != v && y != u)
396                Swap2(u, x, v, y, parent, child);
397            }
398          }
399        }
400      }
401    }
402
403    protected PrinsEncoding Manipulate(PrinsEncoding individual,
404      double originalQuality, int u, int v) {
405      PrinsEncoding child = null;
406      bool improvement = false;
407
408      if (u != v) {
409        child = individual.Clone() as PrinsEncoding;
410        M1(individual, child, u, v);
411        improvement = GetQuality(child) < originalQuality;
412
413        if (!improvement) {
414          child = individual.Clone() as PrinsEncoding;
415          M2(individual, child, u, v);
416          improvement = GetQuality(child) < originalQuality;
417        }
418
419        if (!improvement) {
420          child = individual.Clone() as PrinsEncoding;
421          M3(individual, child, u, v);
422          improvement = GetQuality(child) < originalQuality;
423        }
424
425        if (!improvement) {
426          child = individual.Clone() as PrinsEncoding;
427          M4(individual, child, u, v);
428          improvement = GetQuality(child) < originalQuality;
429        }
430
431        if (!improvement) {
432          child = individual.Clone() as PrinsEncoding;
433          M5(individual, child, u, v);
434          improvement = GetQuality(child) < originalQuality;
435        }
436
437        if (!improvement) {
438          child = individual.Clone() as PrinsEncoding;
439          M6(individual, child, u, v);
440          improvement = GetQuality(child) < originalQuality;
441        }
442
443        if (!improvement) {
444          child = individual.Clone() as PrinsEncoding;
445          M7(individual, child, u, v);
446          improvement = GetQuality(child) < originalQuality;
447        }
448
449        if (!improvement) {
450          child = individual.Clone() as PrinsEncoding;
451          M8(individual, child, u, v);
452          improvement = GetQuality(child) < originalQuality;
453        }
454
455        if (!improvement) {
456          child = individual.Clone() as PrinsEncoding;
457          M9(individual, child, u, v);
458          improvement = GetQuality(child) < originalQuality;
459        }
460      }
461
462      if (improvement)
463        return child;
464      else
465        return null;
466    }
467  }
468}
Note: See TracBrowser for help on using the repository browser.