Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDPOptimization.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: 12.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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 System.Linq;
25using System.Text;
26using HeuristicLab.Core;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28using HeuristicLab.Common;
29using HeuristicLab.PDPSimulation.DomainModel;
30using System.Threading;
31using HeuristicLab.Problems.VehicleRouting.Interfaces;
32using HeuristicLab.Problems.VehicleRouting;
33using HeuristicLab.Problems.VehicleRouting.Variants;
34using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
35using HeuristicLab.PDPSimulation.Operators;
36using HeuristicLab.Parameters;
37using HeuristicLab.Data;
38using System.Threading.Tasks;
39using HeuristicLab.PDPSimulation.DistanceMeasures;
40using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
41
42namespace HeuristicLab.PDPSimulation {
43  [StorableClass]
44  public abstract class DynamicPDPOptimization : PickupDeliveryOptimization {
45    public ValueParameter<BoolValue> OnlyOptimizedIfRequiredParameter {
46      get { return (ValueParameter<BoolValue>)Parameters["OnlyOptimizedIfRequired"]; }
47    }
48
49    public DynamicPDPOptimization(): base() {
50      optimizationFinshed = true;
51      Parameters.Add(new ValueParameter<BoolValue>("OnlyOptimizedIfRequired", "Only optimize if new information is revealed.", new BoolValue(true)));
52    }
53    [StorableConstructor]
54    protected DynamicPDPOptimization(bool deserializing) : base(deserializing) {
55    }
56    protected DynamicPDPOptimization(DynamicPDPOptimization original, Cloner cloner)
57      : base(original, cloner) {
58        instance = cloner.Clone<DynamicPDProblemInstance>(original.instance);
59        lastUpdateTime = original.lastUpdateTime;
60        optimizationFinshed = original.optimizationFinshed;
61    }
62
63    [Storable]
64    private DynamicPDProblemInstance instance;
65
66    protected DynamicPDProblemInstance Instance {
67      get { return instance; }
68    }
69
70    [Storable]
71    private double lastUpdateTime;
72
73    [Storable]
74    private bool optimizationFinshed;
75
76    public override void SetScenario(PickupDeliveryScenario scenario) {
77      base.SetScenario(scenario);
78      instance = new DynamicPDProblemInstance(scenario, GetResults());
79    }
80
81    public override void SetWaitingStrategy(WaitingStrategy waitingStrategy) {
82      base.SetWaitingStrategy(waitingStrategy);
83      if (instance != null) {
84        foreach (IVRPProblemInstance staticInstance in instance.StaticInstances)
85          (staticInstance as DynPDPProblemInstance).WaitingStrategy = waitingStrategy;
86      }
87    }
88
89    public override void Prepare() {
90      lastUpdateTime = 0;
91      optimizationFinshed = true;
92      instance = new DynamicPDProblemInstance(scenario, GetResults());
93      foreach (IVRPProblemInstance staticInstance in instance.StaticInstances)
94        (staticInstance as DynPDPProblemInstance).WaitingStrategy = waitingStrategy;
95      base.Prepare();
96    }
97
98    protected virtual void PrepareInstance(DynamicPDProblemInstance instance, ChangeInformation changeInformation) {
99      instance.InitializeInstance(changeInformation.CreatedVehicles, changeInformation.CreatedOrders);
100    }
101
102    protected virtual void PerformPlan(IVRPEncoding solution) {
103      lock (actionLocker) {
104        instance.SetCurrentPlan(PotvinEncoding.ConvertFrom(solution, instance.StaticInstance));
105        DynPDPEvaluation eval = instance.StaticInstance.Evaluate(solution) as DynPDPEvaluation;
106
107        List<int> vehicles = new List<int>();
108        for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++)
109          vehicles.Add(i);
110
111        int tourIdx = 0;
112        foreach (Tour tour in solution.GetTours()) {
113          List<double> waitingTimes = DynPDPEvaluator.GetWaitingTimes(instance.StaticInstance as DynPDPProblemInstance, tour, solution);
114
115          int vehicleIdx = solution.GetVehicleAssignment(
116            solution.GetTourIndex(tour));
117          vehicles.Remove(vehicleIdx);
118          Guid vehicleId = instance.GetVehicle(vehicleIdx);
119          Vehicle vehicle = GetVehicle(vehicleId);
120
121          int stopIdx = 0;
122          foreach (int stop in tour.Stops) {
123            double coordX = instance.StaticInstance.GetCoordinates(stop)[0];
124            double coordY = instance.StaticInstance.GetCoordinates(stop)[1];
125            VehicleAction vehicleAction;
126
127            Guid orderId = instance.GetOrder(stop);
128            Order order = GetOrder(orderId);
129            order.AssignedVehicle = vehicleId;
130
131            if (instance.StaticInstance.GetDemand(stop) >= 0) {
132              vehicleAction = VehicleAction.Pickup;
133            } else {
134              vehicleAction = VehicleAction.Deliver;
135            }
136
137            if (instance.StaticInstance.GetDemand(stop) != 0) {
138              double waitingTime = waitingTimes[stopIdx];
139
140              PDAction action = new WaitAction(vehicleId, waitingTime);
141              if (stopIdx == 0) {
142                SetAction(action);
143              } else {
144                AppendAction(action);
145              }
146
147              action = new MoveVehicleAction(
148                vehicleId,
149                coordX,
150                coordY,
151                vehicleAction,
152                order,
153                scenario.AllowDiversion,
154                scenario.DistanceMeasure);
155
156              AppendAction(action);                           
157            }
158
159            stopIdx++;
160          }
161
162          tourIdx++;
163        }
164
165        foreach (int vehicleIdx in vehicles) {
166          Guid vehicleId = instance.GetVehicle(vehicleIdx);
167          Vehicle vehicle = GetVehicle(vehicleId);
168
169          double posX, posY;
170          lock (vehicle) {
171            if (!scenario.AllowDiversion) {
172              posX = vehicle.TargetPositionX;
173              posY = vehicle.TargetPositionY;
174            } else {
175              posX = vehicle.PositionX;
176              posY = vehicle.PositionY;
177            }
178          }
179
180          SetAction(new WaitAction(vehicleId, 0));
181        }
182      }
183    }
184
185    private void UpdateInstance(ChangeInformation changeInformation) {
186      if (!instance.Initialized) {
187        PrepareInstance(instance, changeInformation);
188      } else {
189        foreach (Vehicle vehicle in changeInformation.CreatedVehicles) {
190          lock (vehicle) {
191            instance.AddVehicle(vehicle);
192          }
193        }
194
195        foreach (Order order in changeInformation.CreatedOrders)
196          instance.AddOrder(order);
197
198        foreach (Vehicle vehicle in changeInformation.ChangedVehicles) {
199          lock (vehicle) {
200            instance.UpdateVehicle(vehicle, scenario.AllowDiversion);
201          }
202        }
203
204        foreach (Order order in changeInformation.ChangedOrders)
205          instance.UpdateOrder(order, scenario.AllowDiversion);
206      }
207
208      double time = GetSimulationTime();
209      double delta = time - lastUpdateTime;
210      lastUpdateTime = time;
211
212      instance.UpdateTime(delta);
213    }
214
215    protected virtual void BeginInstanceUpdate(DynamicPDProblemInstance instance) {
216    }
217
218    protected virtual void EndInstanceUpdate(DynamicPDProblemInstance instance) {
219    }
220
221    protected virtual bool OptimizationRequired(ChangeInformation changeInformation) {
222      return (!OnlyOptimizedIfRequiredParameter.Value.Value && Instance.StaticInstance != null && Instance.StaticInstance.Cities.Value > 0) ||
223        changeInformation.CreatedOrders.Count > 0 || changeInformation.InvalidActions;
224    }
225
226    protected virtual void StartOptimization() {
227    }
228
229    protected virtual void EndOptimization() {
230      SignalWaitHandle();
231    }
232
233    protected abstract bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation);
234
235    protected object myLock = new object();
236
237    public override bool OptimizationRequired() {
238      lock (myLock) {
239        if (optimizationFinshed) {
240          bool optimize = OptimizationRequired(GetChangeInformation(GetChanges(false)));
241          if(optimize)
242            optimizationFinshed = false;
243         
244          return optimize;
245        } else {
246          return true;
247        }
248      }
249    }
250
251    private void RelocateToDepot(Guid vehicleId, double simulationTime, bool finish) {
252      Vehicle vehicle = GetVehicle(vehicleId);
253      double posX, posY;
254      lock (vehicle) {
255        posX = vehicle.TargetPositionX;
256        posY = vehicle.TargetPositionY;
257      }
258
259      bool moveToDepot = finish;
260      if (!finish) {
261        double length = scenario.DistanceMeasure.GetDistance(posX, posY, vehicle.DepotX, vehicle.DepotY);
262
263        moveToDepot = (simulationTime + length >= vehicle.DueTime);
264      }
265
266      if (moveToDepot) {
267        bool moved = false;
268        PDAction action = GetAction(vehicle);
269        while (action != null && action.Successor != null) {
270          action = action.Successor;
271        }
272
273        moved = action != null && action is MoveVehicleAction &&
274          (action as MoveVehicleAction).TargetX == vehicle.DepotX &&
275          (action as MoveVehicleAction).TargetY == vehicle.DepotY;
276
277        if (!moved)
278          AppendAction(new MoveVehicleAction(vehicleId, vehicle.DepotX, vehicle.DepotY, VehicleAction.Park, null,
279                scenario.AllowDiversion, scenario.DistanceMeasure));
280      }
281    }
282
283    protected virtual void RelocateVehicles(double simulationTime, bool finish) {
284      lock (actionLocker) {
285        for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++) {
286          Guid vehicleId = instance.GetVehicle(i);
287          RelocateToDepot(vehicleId, simulationTime, finish);
288        }
289      }
290    }
291
292    public override void RelocateVehicles() {
293      if (scenario.RelocateBackToDepot) {
294        double simulationTime = GetSimulationTime() + GetTimeStep();
295        RelocateVehicles(simulationTime, false);
296      }
297    }
298
299    int index = 0;
300    protected override void Optimize(CancellationToken token) {
301      bool finish = false;
302      bool optimize = false;
303      bool simulationFinished = false;
304
305      ChangeInformation changeInformation;
306
307      StartOptimization();
308
309      while (!token.IsCancellationRequested && !finish) {
310        WaitForSimulation();
311        lock (myLock) {
312          List<PDChange> changes = GetChanges(true);
313          changeInformation = GetChangeInformation(changes);
314
315          BeginInstanceUpdate(instance);
316          UpdateInstance(changeInformation);         
317          EndInstanceUpdate(instance);
318
319          optimize = OptimizationRequired(changeInformation);
320          optimizationFinshed = !optimize;
321        }
322
323        double simulationTime = GetSimulationTime();
324
325        if (changeInformation.SimulationFinished)
326          simulationFinished = true;
327
328        if (optimize) {
329          optimizationFinshed = PerformOptimization(instance, changeInformation);
330
331          /*VehicleRoutingProblem problem = new VehicleRoutingProblem();
332            problem.ProblemInstance = instance.StaticInstance;
333            index++;
334            HeuristicLab.Persistence.Default.Xml.XmlGenerator.Serialize(problem, @"C:\Users\svonolfen\Desktop\tests\i_" + index + ".hl");*/
335        }
336       
337        finish = simulationFinished && optimizationFinshed;
338
339        if(scenario.RelocateBackToDepot)
340          RelocateVehicles(simulationTime + GetTimeStep(), finish);
341
342        if (finish)
343          running = false;
344        else
345          SignalWaitHandle();
346      }
347
348      EndOptimization();
349    }
350  }
351}
Note: See TracBrowser for help on using the repository browser.