Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDPOptimization.cs @ 12897

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

Fixed threading issues (#1955)

File size: 12.1 KB
RevLine 
[8670]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();
[8807]231      running = false;
[8670]232    }
233
234    protected abstract bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation);
235
236    protected object myLock = new object();
237
238    public override bool OptimizationRequired() {
239      lock (myLock) {
240        if (optimizationFinshed) {
241          bool optimize = OptimizationRequired(GetChangeInformation(GetChanges(false)));
242          if(optimize)
243            optimizationFinshed = false;
244         
245          return optimize;
246        } else {
247          return true;
248        }
249      }
250    }
251
252    private void RelocateToDepot(Guid vehicleId, double simulationTime, bool finish) {
253      Vehicle vehicle = GetVehicle(vehicleId);
254      double posX, posY;
255      lock (vehicle) {
256        posX = vehicle.TargetPositionX;
257        posY = vehicle.TargetPositionY;
258      }
259
260      bool moveToDepot = finish;
261      if (!finish) {
262        double length = scenario.DistanceMeasure.GetDistance(posX, posY, vehicle.DepotX, vehicle.DepotY);
263
264        moveToDepot = (simulationTime + length >= vehicle.DueTime);
265      }
266
267      if (moveToDepot) {
268        bool moved = false;
269        PDAction action = GetAction(vehicle);
270        while (action != null && action.Successor != null) {
271          action = action.Successor;
272        }
273
274        moved = action != null && action is MoveVehicleAction &&
275          (action as MoveVehicleAction).TargetX == vehicle.DepotX &&
276          (action as MoveVehicleAction).TargetY == vehicle.DepotY;
277
278        if (!moved)
279          AppendAction(new MoveVehicleAction(vehicleId, vehicle.DepotX, vehicle.DepotY, VehicleAction.Park, null,
280                scenario.AllowDiversion, scenario.DistanceMeasure));
281      }
282    }
283
284    protected virtual void RelocateVehicles(double simulationTime, bool finish) {
285      lock (actionLocker) {
286        for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++) {
287          Guid vehicleId = instance.GetVehicle(i);
288          RelocateToDepot(vehicleId, simulationTime, finish);
289        }
290      }
291    }
292
293    public override void RelocateVehicles() {
294      if (scenario.RelocateBackToDepot) {
295        double simulationTime = GetSimulationTime() + GetTimeStep();
296        RelocateVehicles(simulationTime, false);
297      }
298    }
299
300    int index = 0;
301    protected override void Optimize(CancellationToken token) {
302      bool finish = false;
303      bool optimize = false;
304      bool simulationFinished = false;
305
306      ChangeInformation changeInformation;
307
308      StartOptimization();
309
310      while (!token.IsCancellationRequested && !finish) {
311        WaitForSimulation();
312        lock (myLock) {
313          List<PDChange> changes = GetChanges(true);
314          changeInformation = GetChangeInformation(changes);
315
316          BeginInstanceUpdate(instance);
317          UpdateInstance(changeInformation);         
318          EndInstanceUpdate(instance);
319
320          optimize = OptimizationRequired(changeInformation);
321          optimizationFinshed = !optimize;
322        }
323
324        double simulationTime = GetSimulationTime();
325
326        if (changeInformation.SimulationFinished)
327          simulationFinished = true;
328
329        if (optimize) {
330          optimizationFinshed = PerformOptimization(instance, changeInformation);
331
332          /*VehicleRoutingProblem problem = new VehicleRoutingProblem();
333            problem.ProblemInstance = instance.StaticInstance;
334            index++;
335            HeuristicLab.Persistence.Default.Xml.XmlGenerator.Serialize(problem, @"C:\Users\svonolfen\Desktop\tests\i_" + index + ".hl");*/
336        }
337       
338        finish = simulationFinished && optimizationFinshed;
339
340        if(scenario.RelocateBackToDepot)
341          RelocateVehicles(simulationTime + GetTimeStep(), finish);
342
[8807]343        if (!finish)
[8670]344          SignalWaitHandle();
345      }
346
347      EndOptimization();
348    }
349  }
350}
Note: See TracBrowser for help on using the repository browser.