Free cookie consent management tool by TermsFeed Policy Generator

source: branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOptimization.cs @ 16511

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

Fixed threading issues (#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.PDPSimulation.SimulationCore;
29using HeuristicLab.Parameters;
30using HeuristicLab.Data;
31using System.Threading;
32using HeuristicLab.Common;
33using HeuristicLab.PDPSimulation.DomainModel;
34using HeuristicLab.PDPSimulation.DistanceMeasures;
35using HeuristicLab.Optimization;
36
37namespace HeuristicLab.PDPSimulation {
38  [Item("PickupDeliveryOptimization", "A pickup and delivery optimization.")]
39  [StorableClass]
40  public abstract class PickupDeliveryOptimization: ParameterizedNamedItem {
41    #region constructors
42    public PickupDeliveryOptimization() : base() {
43      objectChanges = new Dictionary<BaseObject, List<PDChange>>();
44      actions = new Dictionary<Guid, PDAction>();
45    }
46    [StorableConstructor]
47    protected PickupDeliveryOptimization(bool deserializing) : base(deserializing) { }
48    protected PickupDeliveryOptimization(PickupDeliveryOptimization original, Cloner cloner)
49      : base(original, cloner) {
50      lock (original.objectChanges) {
51        lock (original.actionLocker) {
52          simulation = cloner.Clone<PickupDeliverySimulation>(original.simulation);
53          if (simulation != null) {
54            simulation.SimulationStateChanged +=
55              new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
56          }
57
58          objectChanges = new Dictionary<BaseObject, List<PDChange>>();
59          foreach (BaseObject obj in original.objectChanges.Keys) {
60            BaseObject objClone = cloner.Clone<BaseObject>(obj);
61
62            objectChanges.Add(objClone, new List<PDChange>());
63            foreach (PDChange change in original.objectChanges[obj])
64              objectChanges[objClone].Add(cloner.Clone<PDChange>(change));
65          }
66
67          actions = new Dictionary<Guid, PDAction>();
68          foreach (Guid objId in original.actions.Keys) {
69            actions.Add(objId, cloner.Clone<PDAction>(original.actions[objId]));
70          }
71        }
72      }
73
74      this.scenario = cloner.Clone<PickupDeliveryScenario>(original.scenario);
75      this.waitingStrategy = cloner.Clone<WaitingStrategy>(original.waitingStrategy);
76    }
77    #endregion
78
79    [StorableHook(HookType.AfterDeserialization)]
80    private void AfterDeserialization() {
81      if (this.simulation != null) {
82        this.simulation.SimulationStateChanged +=
83         new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
84      }
85    }
86
87    [Storable]
88    protected PickupDeliveryScenario scenario;
89
90    [Storable]
91    protected WaitingStrategy waitingStrategy;
92
93    [Storable]
94    private PickupDeliverySimulation simulation;
95
96    protected double GetSimulationTime() {
97      return simulation.SimulationTime;
98    }
99
100    protected double GetTimeStep() {
101      return simulation.TimeStep;
102    }
103
104    protected List<Order> GetOrders() {
105      return simulation.Orders;
106    }
107
108    protected Order GetOrder(Guid orderId) {
109      return simulation.GetOrder(orderId);
110    }
111
112    protected Vehicle GetVehicle(Guid vehicleId) {
113      return simulation.GetVehicle(vehicleId);
114    }
115
116    protected List<Vehicle> GetVehicles() {
117      return simulation.Vehicles;
118    }
119
120    protected ResultCollection GetResults() {
121      return simulation.Results;
122    }
123
124    [Storable]
125    private Dictionary<BaseObject, List<PDChange>> objectChanges;
126
127    private void RemoveObsoleteChanges(PDChange change) {
128      List<PDChange> toBeRemoved = new List<PDChange>();
129
130      foreach (PDChange existingChange in objectChanges[change.BaseObject]) {
131        if (existingChange.ChangeType == change.ChangeType) {
132          toBeRemoved.Add(existingChange);
133        }
134      }
135
136      foreach (PDChange removed in toBeRemoved) {
137        objectChanges[change.BaseObject].Remove(removed);
138      }
139    }
140
141    protected void AddChange(PDChange change) {
142      lock (objectChanges) {
143        if (!objectChanges.ContainsKey(change.BaseObject))
144          objectChanges.Add(change.BaseObject, new List<PDChange>());
145
146        RemoveObsoleteChanges(change);
147
148        objectChanges[change.BaseObject].Add(change);
149      }
150    }
151
152    protected List<PDChange> GetChanges(bool clear) {
153      lock (objectChanges) {
154        List<PDChange> result = new List<PDChange>();
155        foreach (List<PDChange> objChanges in objectChanges.Values)
156          result.AddRange(objChanges);
157
158        if(clear)
159          objectChanges.Clear();
160
161        return result;
162      }
163    }
164
165    protected struct ChangeInformation {
166      public List<Vehicle> CreatedVehicles { get; set; }
167      public List<Order> CreatedOrders { get; set; }
168      public List<Vehicle> ChangedVehicles { get; set; }
169      public List<Order> ChangedOrders { get; set; }
170      public bool InvalidActions { get; set; }
171      public bool SimulationFinished { get; set; }
172    }
173
174    protected ChangeInformation GetChangeInformation(List<PDChange> changes) {
175      ChangeInformation changeInformation = new ChangeInformation();
176
177      changeInformation.CreatedVehicles = new List<Vehicle>();
178      changeInformation.CreatedOrders = new List<Order>();
179      changeInformation.ChangedVehicles = new List<Vehicle>();
180      changeInformation.ChangedOrders = new List<Order>();
181      changeInformation.InvalidActions = false;
182      changeInformation.SimulationFinished = false;
183
184      foreach (PDChange change in changes) {
185        if (change.ChangeType == SimulationStateChange.VehicleCreated) {
186          Vehicle vehicle = change.BaseObject as Vehicle;
187          changeInformation.CreatedVehicles.Add(vehicle);
188        } else if (change.ChangeType == SimulationStateChange.VehicleMoved ||
189           change.ChangeType == SimulationStateChange.VehicleState) {
190          Vehicle vehicle = change.BaseObject as Vehicle;
191          changeInformation.ChangedVehicles.Add(vehicle);
192
193          if (change.ChangeType == SimulationStateChange.VehicleState &&
194            vehicle.VehicleState == VehicleState.InvalidAction)
195            changeInformation.InvalidActions = true;
196        } else if (change.ChangeType == SimulationStateChange.OrderCreated) {
197          Order order = change.BaseObject as Order;
198          changeInformation.CreatedOrders.Add(order);
199        } else if (change.ChangeType == SimulationStateChange.OrderState) {
200          Order order = change.BaseObject as Order;
201          changeInformation.ChangedOrders.Add(order);
202        } else if (change.ChangeType == SimulationStateChange.NoMoreOrders) {
203          changeInformation.SimulationFinished = true;
204        } else if (change.ChangeType == SimulationStateChange.OrderFailed) {
205          changeInformation.InvalidActions = true;
206        }
207      }
208
209      changeInformation.InvalidActions = changeInformation.InvalidActions ||
210        GetVehicles().Where(v => v.VehicleState == VehicleState.InvalidAction).Count() > 0;
211
212      return changeInformation;
213    }
214
215    protected object actionLocker = new object();
216
217    [Storable]
218    private Dictionary<Guid, PDAction> actions;
219
220    public PDAction GetAction(BaseObject obj) {
221      lock (actionLocker) {
222        if (actions.ContainsKey(obj.Id))
223          return actions[obj.Id];
224        else
225          return null;
226      }
227    }
228
229    protected void SetAction(PDAction action) {
230      lock (actionLocker) {
231        if (actions.ContainsKey(action.BaseObjectId)) {
232          lock (actions[action.BaseObjectId]) {
233            if (!actions[action.BaseObjectId].Interruptable())
234              actions[action.BaseObjectId].AppendAction(action, false);
235            else
236              actions[action.BaseObjectId] = action;
237          }
238        } else {
239          actions[action.BaseObjectId] = action;
240        }
241      }
242    }
243
244    protected void AppendAction(PDAction action) {
245      lock (actionLocker) {
246        if (actions.ContainsKey(action.BaseObjectId)) {
247          actions[action.BaseObjectId].AppendAction(action, true);
248        } else {
249          actions[action.BaseObjectId] = action;
250        }
251      }
252    }
253
254    public void RemoveCompletedActions() {
255      lock (actionLocker) {
256        List<Guid> toBeRemoved = new List<Guid>();
257        foreach (Guid objId in actions.Keys) {
258          if (actions[objId].IsCompleted)
259            toBeRemoved.Add(objId);
260        }
261        foreach (Guid objId in toBeRemoved)
262          actions.Remove(objId);
263      }
264    }
265
266    public List<PDAction> GetActions() {
267      lock (actionLocker) {
268        RemoveCompletedActions();
269
270        return actions.Values.ToList();
271      }
272    }
273
274    public virtual void SetScenario(PickupDeliveryScenario scenario) {
275      if (scenario != null) {
276        this.scenario = scenario;
277      }
278    }
279
280    public virtual void SetWaitingStrategy(WaitingStrategy waitingStrategy) {
281      this.waitingStrategy = waitingStrategy;     
282    }
283
284    public virtual void Prepare() {
285      //clear state
286      objectChanges.Clear();
287      actions.Clear();
288    }
289
290    public virtual void SetSimulation(PickupDeliverySimulation simulation) {
291      if (this.simulation != simulation) {
292        if (this.simulation != null) {
293          this.simulation.SimulationStateChanged -=
294            new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
295        }
296
297        this.simulation = simulation;
298
299        this.simulation.SimulationStateChanged +=
300           new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
301      }
302    }
303
304    private EventWaitHandle wh;
305    private void InitWaitHandle(bool synchronized) {
306      if(wh != null)
307        wh.Dispose();
308      wh = null;
309
310      if(synchronized)
311        wh = new EventWaitHandle(false, EventResetMode.AutoReset);
312    }
313    protected void SignalWaitHandle() {
314      if(wh != null)
315        wh.Set();
316    }
317    public void WaitForOptimization() {
318      if (wh != null) {
319        bool signal = false;
320
321        while (!signal && Running())
322          signal = wh.WaitOne(100);
323      }
324    }
325    protected void WaitForSimulation() {
326      simulation.WaitForSimulation();
327    }
328
329    protected abstract void Optimize(CancellationToken token);
330    Thread optThread;
331    CancellationTokenSource cts;
332
333    protected bool running;
334
335    public void Start(bool synchronized) {
336      running = true;
337      InitWaitHandle(synchronized);
338
339      using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.ManualReset)) {
340        cts = new CancellationTokenSource();
341        optThread = new Thread(delegate() {
342          wh.Set();
343          Optimize(cts.Token);
344        });
345        optThread.IsBackground = true;
346        optThread.Start();
347
348        wh.WaitOne();
349      }
350    }
351
352    public abstract bool OptimizationRequired();
353
354    public virtual void RelocateVehicles() {
355
356    }
357
358    public void Stop() {
359      if(cts != null)
360       cts.Cancel();
361    }
362
363    public bool Running() {
364      return optThread != null && optThread.IsAlive && running;
365    }
366
367    public void Exit() {
368      optThread = null;
369    }
370
371    void simulation_SimulationStateChanged(BaseObject obj, SimulationStateChange changeType) {
372      PDChange change = new PDChange() { BaseObject = obj.Clone() as BaseObject, ChangeType = changeType };
373      AddChange(change);
374    }
375  }
376}
Note: See TracBrowser for help on using the repository browser.