Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Prins/PrinsEncoding.cs @ 4501

Last change on this file since 4501 was 4352, checked in by svonolfe, 14 years ago

Merged r4351 of the VRP feature branch into trunk (#1039)

File size: 8.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.Common;
23using HeuristicLab.Core;
24using HeuristicLab.Data;
25using HeuristicLab.Encodings.PermutationEncoding;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27using System.Collections.Generic;
28using HeuristicLab.Problems.VehicleRouting.Encodings.General;
29using System;
30
31namespace HeuristicLab.Problems.VehicleRouting.Encodings.Prins {
32  [Item("PrinsEncoding", "Represents an Prins encoding of VRP solutions. 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.")]
33  [StorableClass]
34  public class PrinsEncoding : PermutationEncoding {
35    [Storable]
36    private int cities;
37
38    [Storable]
39    private DoubleMatrix coordinates;
40
41    [Storable]
42    private BoolValue useDistanceMatrix;
43
44    [Storable]
45    DoubleArray dueTimeArray;
46   
47    [Storable]
48    DoubleArray serviceTimeArray;
49
50    [Storable]
51    DoubleArray readyTimeArray;
52   
53    [Storable]
54    DoubleArray demandArray;
55
56    [Storable]
57    DoubleValue capacity;
58
59    [Storable]
60    DoubleValue fleetUsageFactor;
61
62    [Storable]
63    DoubleValue timeFactor;
64
65    [Storable]
66    DoubleValue distanceFactor;
67
68    [Storable]
69    DoubleValue overloadPenalty;
70
71    [Storable]
72    DoubleValue tardinessPenalty;
73
74    #region IVRPEncoding Members
75    public override List<Tour> GetTours(ILookupParameter<DoubleMatrix> distanceMatrix, int maxVehicles = int.MaxValue) {
76      List<Tour> result = new List<Tour>();
77
78      //Split permutation into vector P
79      int[] P = new int[cities + 1];
80      for (int i = 0; i <= cities; i++)
81        P[i] = -1;
82
83      double[] V = new double[cities + 1];
84      V[0] = 0;
85      for (int i = 1; i <= cities; i++) {
86        V[i] = int.MaxValue;
87      }
88
89      for (int i = 1; i <= cities; i++) {
90        int j = i;
91        Tour tour = new Tour();
92        bool feasible = true;
93
94        do {
95          tour.Cities.Add(this[j-1] + 1);
96
97          TourEvaluation eval = VRPEvaluator.EvaluateTour(tour,
98            dueTimeArray,
99            serviceTimeArray,
100            readyTimeArray,
101            demandArray,
102            capacity,
103            fleetUsageFactor,
104            timeFactor,
105            distanceFactor,
106            overloadPenalty,
107            tardinessPenalty,
108            coordinates,
109            distanceMatrix,
110            useDistanceMatrix);
111
112          double cost = eval.Quality;
113          feasible = eval.Overload < double.Epsilon && eval.Tardiness < double.Epsilon;
114
115          if (feasible) {
116            if (V[i - 1] + cost < V[j]) {
117              V[j] = V[i - 1] + cost;
118              P[j] = i - 1;
119            }
120            j++;
121          }
122
123        } while (j <= cities && feasible);
124      }
125
126      //extract VRP solution from vector P
127      int index = 0;
128      int index2 = cities;
129      Tour trip = null;
130      do {
131        index = P[index2];
132        trip = new Tour();
133
134        for (int k = index + 1; k <= index2; k++) {
135          trip.Cities.Add(this[k - 1] + 1);
136        }
137
138        if (trip.Cities.Count > 0)
139          result.Add(trip);
140
141        index2 = index;
142      } while (index != 0);
143
144      //if there are too many vehicles - repair
145      while (result.Count > maxVehicles) {
146        Tour tour = result[result.Count - 1];
147
148        //find predecessor / successor in permutation
149        int predecessorIndex = Array.IndexOf(this.array, tour.Cities[0] - 1) - 1;
150        if (predecessorIndex >= 0) {
151          int predecessor = this[predecessorIndex] + 1;
152
153          foreach (Tour t in result) {
154            int insertPosition = t.Cities.IndexOf(predecessor) + 1;
155            if (insertPosition != -1) {
156              t.Cities.InsertRange(insertPosition, tour.Cities);
157              break;
158            }
159          }
160        } else {
161          int successorIndex = Array.IndexOf(this.array,
162            tour.Cities[tour.Cities.Count - 1] - 1) + 1;
163          int successor = this[successorIndex] + 1;
164
165          foreach (Tour t in result) {
166            int insertPosition = t.Cities.IndexOf(successor);
167            if (insertPosition != -1) {
168              t.Cities.InsertRange(insertPosition, tour.Cities);
169              break;
170            }
171          }
172        }
173
174        result.Remove(tour);
175      }
176
177      return result;
178    }
179    #endregion
180
181    public override IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
182      PrinsEncoding clone = new PrinsEncoding(
183        new Permutation(this.PermutationType, this.array), cities,
184        dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, capacity,
185        fleetUsageFactor, timeFactor, distanceFactor, overloadPenalty, tardinessPenalty,
186        coordinates, useDistanceMatrix);
187
188      cloner.RegisterClonedObject(this, clone);
189      clone.readOnly = readOnly;
190      return clone;
191    }
192
193    public PrinsEncoding(Permutation permutation, int cities,
194      DoubleArray dueTimeArray, DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
195      DoubleValue fleetUsageFactor, DoubleValue timeFactor, DoubleValue distanceFactor, DoubleValue overloadPenalty, DoubleValue tardinessPenalty,
196      DoubleMatrix coordinates, BoolValue useDistanceMatrix)
197      : base(permutation) {
198        this.cities = cities;
199        this.dueTimeArray = dueTimeArray;
200        this.serviceTimeArray = serviceTimeArray;
201        this.readyTimeArray = readyTimeArray;
202        this.demandArray = demandArray;
203        this.capacity = capacity;
204        this.coordinates = coordinates;
205        this.useDistanceMatrix = useDistanceMatrix;
206        this.fleetUsageFactor = fleetUsageFactor;
207        this.timeFactor = timeFactor;
208        this.distanceFactor = distanceFactor;
209        this.overloadPenalty = overloadPenalty;
210        this.tardinessPenalty = tardinessPenalty;
211    }
212
213    [StorableConstructor]
214    private PrinsEncoding(bool serializing)
215      : base(serializing) {
216    }
217
218    public static PrinsEncoding ConvertFrom(IVRPEncoding encoding, int cities,
219      DoubleArray dueTimeArray, DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
220      DoubleValue fleetUsageFactor, DoubleValue timeFactor, DoubleValue distanceFactor, DoubleValue overloadPenalty, DoubleValue tardinessPenalty,
221      DoubleMatrix coordinates, ILookupParameter<DoubleMatrix> distanceMatrix, BoolValue useDistanceMatrix) {
222      List<Tour> tours = encoding.GetTours(distanceMatrix);
223      List<int> route = new List<int>();
224
225      foreach (Tour tour in tours) {
226        foreach (int city in tour.Cities)
227          route.Add(city - 1);
228      }
229
230      return new PrinsEncoding(
231        new Permutation(PermutationTypes.RelativeUndirected, route.ToArray()), cities,
232        dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, capacity,
233        fleetUsageFactor, timeFactor, distanceFactor, overloadPenalty, tardinessPenalty,
234        coordinates, useDistanceMatrix);
235    }
236
237    public static PrinsEncoding ConvertFrom(List<int> routeParam, int cities,
238      DoubleArray dueTimeArray, DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
239      DoubleValue fleetUsageFactor, DoubleValue timeFactor, DoubleValue distanceFactor, DoubleValue overloadPenalty, DoubleValue tardinessPenalty,
240      DoubleMatrix coordinates, BoolValue useDistanceMatrix) {
241      List<int> route = new List<int>(routeParam);
242
243      while (route.Remove(0)) { //remove all delimiters (0)
244      }
245
246      for (int i = 0; i < route.Count; i++)
247        route[i]--;
248
249      return new PrinsEncoding(
250        new Permutation(PermutationTypes.RelativeUndirected, route.ToArray()), cities,
251        dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, capacity,
252        fleetUsageFactor, timeFactor, distanceFactor, overloadPenalty, tardinessPenalty,
253        coordinates, useDistanceMatrix);
254    }
255  }
256}
Note: See TracBrowser for help on using the repository browser.