Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Alba/Creators/AlbaPushForwardInsertionCreator.cs @ 4068

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

Sorted usings and removed unused usings in entire solution (#1094)

File size: 11.6 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;
23using System.Collections.Generic;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Encodings.PermutationEncoding;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Problems.VehicleRouting.Encodings.Alba {
32  [Item("AlbaPushForwardCreator", "An operator which creates a new alba VRP representation using the push forward insertion heuristic.")]
33  [StorableClass]
34  public sealed class AlbaPushForwardCreator : VRPCreator, IStochasticOperator {
35    #region IStochasticOperator Members
36    public ILookupParameter<IRandom> RandomParameter {
37      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
38    }
39    #endregion
40
41    public IValueParameter<DoubleValue> Alpha {
42      get { return (IValueParameter<DoubleValue>)Parameters["Alpha"]; }
43    }
44    public IValueParameter<DoubleValue> AlphaVariance {
45      get { return (IValueParameter<DoubleValue>)Parameters["AlphaVariance"]; }
46    }
47    public IValueParameter<DoubleValue> Beta {
48      get { return (IValueParameter<DoubleValue>)Parameters["Beta"]; }
49    }
50    public IValueParameter<DoubleValue> BetaVariance {
51      get { return (IValueParameter<DoubleValue>)Parameters["BetaVariance"]; }
52    }
53    public IValueParameter<DoubleValue> Gamma {
54      get { return (IValueParameter<DoubleValue>)Parameters["Gamma"]; }
55    }
56    public IValueParameter<DoubleValue> GammaVariance {
57      get { return (IValueParameter<DoubleValue>)Parameters["GammaVariance"]; }
58    }
59
60    public AlbaPushForwardCreator()
61      : base() {
62      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator."));
63      Parameters.Add(new ValueParameter<DoubleValue>("Alpha", "The alpha value.", new DoubleValue(0.7)));
64      Parameters.Add(new ValueParameter<DoubleValue>("AlphaVariance", "The alpha variance.", new DoubleValue(0.5)));
65      Parameters.Add(new ValueParameter<DoubleValue>("Beta", "The beta value.", new DoubleValue(0.1)));
66      Parameters.Add(new ValueParameter<DoubleValue>("BetaVariance", "The beta variance.", new DoubleValue(0.07)));
67      Parameters.Add(new ValueParameter<DoubleValue>("Gamma", "The gamma value.", new DoubleValue(0.2)));
68      Parameters.Add(new ValueParameter<DoubleValue>("GammaVariance", "The gamma variance.", new DoubleValue(0.14)));
69    }
70
71    public override IOperation Apply() {
72      VRPSolutionParameter.ActualValue = new AlbaEncoding(CreateSolution(), CitiesParameter.ActualValue.Value);
73
74      return base.Apply();
75    }
76
77    // use the Box-Mueller transform in the polar form to generate a N(0,1) random variable out of two uniformly distributed random variables
78    private double Gauss(IRandom random) {
79      double u = 0.0, v = 0.0, s = 0.0;
80      do {
81        u = (random.NextDouble() * 2) - 1;
82        v = (random.NextDouble() * 2) - 1;
83        s = Math.Sqrt(u * u + v * v);
84      } while (s < Double.Epsilon || s > 1);
85      return u * Math.Sqrt((-2.0 * Math.Log(s)) / s);
86    }
87
88    private double N(double mu, double sigma, IRandom random) {
89      return mu + (sigma * Gauss(random)); // transform the random variable sampled from N(0,1) to N(mu,sigma)
90    }
91
92    private double CalculateDistance(int start, int end) {
93      double distance = 0.0;
94      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
95
96      distance =
97          Math.Sqrt(
98            Math.Pow(coordinates[start, 0] - coordinates[end, 0], 2) +
99            Math.Pow(coordinates[start, 1] - coordinates[end, 1], 2));
100
101      return distance;
102    }
103
104    private DoubleMatrix CreateDistanceMatrix() {
105      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
106      DoubleMatrix distanceMatrix = new DoubleMatrix(coordinates.Rows, coordinates.Rows);
107
108      for (int i = 0; i < distanceMatrix.Rows; i++) {
109        for (int j = i; j < distanceMatrix.Columns; j++) {
110          double distance = CalculateDistance(i, j);
111
112          distanceMatrix[i, j] = distance;
113          distanceMatrix[j, i] = distance;
114        }
115      }
116
117      return distanceMatrix;
118    }
119
120    private double Distance(int start, int end) {
121      double distance = 0.0;
122
123      if (UseDistanceMatrixParameter.ActualValue.Value) {
124        if (DistanceMatrixParameter.ActualValue == null) {
125          DistanceMatrixParameter.ActualValue = CreateDistanceMatrix();
126        }
127
128        distance = DistanceMatrixParameter.ActualValue[start, end];
129      } else {
130        distance = CalculateDistance(start, end);
131      }
132
133      return distance;
134    }
135
136    private double TravelDistance(List<int> route, int begin) {
137      double distance = 0;
138      for (int i = begin; i < route.Count - 1 && (i == begin || route[i] != 0); i++) {
139        distance += Distance(route[i], route[i + 1]);
140      }
141      return distance;
142    }
143
144    private bool SubrouteConstraintsOK(List<int> route, int begin) {
145      double t = 0.0, o = 0.0;
146      for (int i = begin + 1; i < route.Count; i++) {
147        t += Distance(route[i - 1], route[i]);
148        if (route[i] == 0) return (t < DueTimeParameter.ActualValue[0]); // violation on capacity constraint is handled below
149        else {
150          if (t > DueTimeParameter.ActualValue[route[i]]) return false;
151          t = Math.Max(ReadyTimeParameter.ActualValue[route[i]], t);
152          t += ServiceTimeParameter.ActualValue[route[i]];
153          o += DemandParameter.ActualValue[route[i]];
154          if (o > CapacityParameter.ActualValue.Value) return false; // premature exit on capacity constraint violation
155        }
156      }
157      return true;
158    }
159
160    private bool SubrouteTardinessOK(List<int> route, int begin) {
161      double t = 0.0;
162      for (int i = begin + 1; i < route.Count; i++) {
163        t += Distance(route[i - 1], route[i]);
164        if (route[i] == 0) {
165          if (t < DueTimeParameter.ActualValue[0]) return true;
166          else return false;
167        } else {
168          if (t > DueTimeParameter.ActualValue[route[i]]) return false;
169          t = Math.Max(ReadyTimeParameter.ActualValue[route[i]], t);
170          t += ServiceTimeParameter.ActualValue[route[i]];
171        }
172      }
173      return true;
174    }
175
176    private bool SubrouteLoadOK(List<int> route, int begin) {
177      double o = 0.0;
178      for (int i = begin + 1; i < route.Count; i++) {
179        if (route[i] == 0) return (o < CapacityParameter.ActualValue.Value);
180        else {
181          o += DemandParameter.ActualValue[route[i]];
182        }
183      }
184      return (o < CapacityParameter.ActualValue.Value);
185    }
186
187    private Permutation CreateSolution() {
188      double alpha, beta, gamma;
189      alpha = N(Alpha.Value.Value, Math.Sqrt(AlphaVariance.Value.Value), RandomParameter.ActualValue);
190      beta = N(Beta.Value.Value, Math.Sqrt(BetaVariance.Value.Value), RandomParameter.ActualValue);
191      gamma = N(Gamma.Value.Value, Math.Sqrt(GammaVariance.Value.Value), RandomParameter.ActualValue);
192
193      double x0 = CoordinatesParameter.ActualValue[0, 0];
194      double y0 = CoordinatesParameter.ActualValue[0, 1];
195      double distance = 0;
196      double cost = 0;
197      double minimumCost = double.MaxValue;
198      List<int> unroutedList = new List<int>();
199      List<double> costList = new List<double>();
200      int index;
201      int indexOfMinimumCost = -1;
202      int indexOfCustomer = -1;
203
204      /*-----------------------------------------------------------------------------
205       * generate cost list
206       *-----------------------------------------------------------------------------
207       */
208      for (int i = 1; i <= CitiesParameter.ActualValue.Value; i++) {
209        distance = Distance(i, 0);
210        if (CoordinatesParameter.ActualValue[i, 0] < x0) distance = -distance;
211        cost = -alpha * distance + // distance 0 <-> City[i]
212                 beta * (DueTimeParameter.ActualValue[i]) + // latest arrival time
213                 gamma * (Math.Asin((CoordinatesParameter.ActualValue[i, 1] - y0) / distance) / 360 * distance); // polar angle
214
215        index = 0;
216        while (index < costList.Count && costList[index] < cost) index++;
217        costList.Insert(index, cost);
218        unroutedList.Insert(index, i);
219      }
220
221      /*------------------------------------------------------------------------------
222       * route customers according to cost list
223       *------------------------------------------------------------------------------
224       */
225      int routeIndex = 0;
226      int currentRoute = 0;
227      int c;
228      int customer = -1;
229      int subTourCount = 1;
230      List<int> route = new List<int>(CitiesParameter.ActualValue.Value + VehiclesParameter.ActualValue.Value - 1);
231      minimumCost = double.MaxValue;
232      indexOfMinimumCost = -1;
233      route.Add(0);
234      route.Add(0);
235      route.Insert(1, unroutedList[0]);
236      unroutedList.RemoveAt(0);
237      currentRoute = routeIndex;
238      routeIndex++;
239
240      do {
241        for (c = 0; c < unroutedList.Count; c++) {
242          for (int i = currentRoute + 1; i < route.Count; i++) {
243            route.Insert(i, (int)unroutedList[c]);
244            if (route[currentRoute] != 0) { throw new Exception("currentRoute not depot"); }
245            cost = TravelDistance(route, currentRoute);
246            if (cost < minimumCost && SubrouteConstraintsOK(route, currentRoute)) {
247              minimumCost = cost;
248              indexOfMinimumCost = i;
249              customer = (int)unroutedList[c];
250              indexOfCustomer = c;
251            }
252            route.RemoveAt(i);
253          }
254        }
255        // insert customer if found
256        if (indexOfMinimumCost != -1) {
257          route.Insert(indexOfMinimumCost, customer);
258          routeIndex++;
259          unroutedList.RemoveAt(indexOfCustomer);
260          costList.RemoveAt(indexOfCustomer);
261        } else { // no feasible customer found
262          routeIndex++;
263          route.Insert(routeIndex, 0);
264          currentRoute = routeIndex;
265          route.Insert(route.Count - 1, (int)unroutedList[0]);
266          unroutedList.RemoveAt(0);
267          routeIndex++;
268          subTourCount++;
269        }
270        // reset minimum   
271        minimumCost = double.MaxValue;
272        indexOfMinimumCost = -1;
273        indexOfCustomer = -1;
274        customer = -1;
275      } while (unroutedList.Count > 0);
276      while (route.Count < CitiesParameter.ActualValue.Value + VehiclesParameter.ActualValue.Value - 1)
277        route.Add(0);
278
279      int vehicle = CitiesParameter.ActualValue.Value;
280      for (int i = 0; i < route.Count; i++) {
281        if (route[i] == 0) {
282          route[i] = vehicle;
283          vehicle++;
284        } else {
285          route[i] = route[i] - 1;
286        }
287      }
288
289      return new Permutation(PermutationTypes.RelativeDirected, route.ToArray());
290    }
291  }
292}
Note: See TracBrowser for help on using the repository browser.