Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/MoveVehicleAction.cs @ 11813

Last change on this file since 11813 was 8670, checked in by svonolfe, 12 years ago

Added first version of the dynamic vehicle routing addon (#1955)

File size: 13.5 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
6using HeuristicLab.Common;
7using HeuristicLab.PDPSimulation.DomainModel;
8using HeuristicLab.PDPSimulation.DistanceMeasures;
9
10namespace HeuristicLab.PDPSimulation {
11  public enum VehicleAction { Wait, Pickup, Deliver, Park, Invalid } 
12 
13  [StorableClass]
14  public class MoveVehicleAction: PDAction {   
15    [Storable]
16    double sourceX;
17
18    public double SourceX {
19      get { return sourceX; }
20    }
21
22    [Storable]
23    double sourceY;
24
25    public double SourceY {
26      get { return sourceY; }
27    }
28   
29    [Storable]
30    double targetX;
31
32    public double TargetX {
33      get { return targetX; }
34    }
35
36    [Storable]
37    double targetY;
38
39    public double TargetY {
40      get { return targetY; }
41    }
42
43    [Storable]
44    VehicleAction action;
45
46    [Storable]
47    Order order;
48
49    [Storable]
50    double serviceTime;
51
52    [Storable]
53    bool interruptable;
54
55    [Storable]
56    bool completed;
57
58    [Storable]
59    DistanceMeasure distMeasure;
60
61    [Storable]
62    bool diversionAllowed;
63
64    public MoveVehicleAction(
65      Guid vehicleId,
66      double targetX, double targetY, VehicleAction action, Order order, bool diversionAllowed, DistanceMeasure distMeasure)
67      : base(vehicleId) {
68        this.targetX = targetX;
69        this.targetY = targetY;
70        this.action = action;
71        this.order = order;
72        this.serviceTime = 0;
73        this.completed = false;
74        this.diversionAllowed = diversionAllowed;
75        this.interruptable = diversionAllowed;
76        this.distMeasure = distMeasure;
77
78        this.sourceX = -1;
79        this.sourceY = -1;
80    }
81    [StorableConstructor]
82    protected MoveVehicleAction(bool deserializing) : base(deserializing) {
83    }
84    protected MoveVehicleAction(MoveVehicleAction original, Cloner cloner)
85      : base(original, cloner) {
86      this.targetX = original.targetX;
87      this.sourceX = original.sourceX;
88      this.targetY = original.targetY;
89      this.sourceY = original.sourceY;
90      this.action = original.action;
91      this.order = cloner.Clone<Order>(original.order);
92      this.serviceTime = original.serviceTime;
93      this.completed = original.completed;
94      this.interruptable = original.interruptable;
95      this.distMeasure = cloner.Clone<DistanceMeasure>(original.distMeasure);
96      this.diversionAllowed = original.diversionAllowed;
97    }
98    public override IDeepCloneable Clone(Cloner cloner) {
99      return new MoveVehicleAction(this, cloner);
100    }
101
102    protected override bool ActionInterruptable() {
103      return interruptable;
104    }
105
106    public override bool ActionCompleted() {
107      return completed;
108    }
109
110    protected override double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes) {
111      Vehicle vehicle = baseObject as Vehicle;
112      lock (vehicle) {
113        if ((action == VehicleAction.Pickup && (order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp)) ||
114           (action == VehicleAction.Deliver && ((order.OrderState != OrderState.PickedUp && order.OrderState != OrderState.Delivering)
115              || !vehicle.PickedUpOrders.Contains(order.Id))) ||
116           (order != null && (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id))) {
117          if (vehicle.VehicleState != VehicleState.InvalidAction) {
118            vehicle.InvalidActions++;
119
120            vehicle.VehicleState = VehicleState.InvalidAction;
121            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
122          }
123
124          if (diversionAllowed)
125            vehicle.ReadyTime = simulationTime;
126          interruptable = diversionAllowed;
127          completed = diversionAllowed;
128
129          if (diversionAllowed)
130            return simulationTime;
131          else {
132            if (order != null) {
133              changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderFailed, BaseObject = order });
134              order = null;
135              action = VehicleAction.Invalid;
136            }
137          }
138        }
139
140        if (sourceX == -1) {
141          sourceX = vehicle.PositionX;
142          sourceY = vehicle.PositionY;
143        }
144
145        vehicle.TargetPositionX = targetX;
146        vehicle.TargetPositionY = targetY;
147        vehicle.CurrentAction = action;
148        if (order == null)
149          vehicle.CurrentOrder = Guid.Empty;
150        else {
151          if (!diversionAllowed)
152            order.Vehicle = vehicle.Id;
153          vehicle.CurrentOrder = order.Id;
154          changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
155        }
156
157        if (action == VehicleAction.Wait || action == VehicleAction.Park)
158          if (diversionAllowed)
159            vehicle.ReadyTime = simulationTime;
160
161        double tx, ty, length;
162        distMeasure.Move(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY, tickTime, vehicle.MoveInfo,
163          out tx, out ty, out length);
164
165        if (!diversionAllowed) {
166          double time = simulationTime;
167          time += distMeasure.GetDistance(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY);
168          if (action == VehicleAction.Pickup) {
169            if (time < order.PickupReadyTime)
170              time = order.PickupReadyTime;
171
172            time += order.PickupServiceTime - serviceTime;
173          } else if (action == VehicleAction.Deliver) {
174            if (time < order.DeliveryReadyTime)
175              time = order.DeliveryReadyTime;
176
177            time += order.DeliveryServiceTime - serviceTime;
178          }
179
180          vehicle.ReadyTime = time;
181        }
182
183        vehicle.PositionX = tx;
184        vehicle.PositionY = ty;
185
186        if (length > 0) {
187          vehicle.Distance += length;
188          tickTime -= length;
189          simulationTime += length;
190
191          if (vehicle.VehicleState != VehicleState.Moving) {
192            vehicle.VehicleState = VehicleState.Moving;
193            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
194          }
195          changes.Add(
196            new PDChange() { ChangeType = SimulationStateChange.VehicleMoved, BaseObject = baseObject });
197        }
198
199        if (vehicle.PositionX == targetX && vehicle.PositionY == targetY) {
200          if (action == VehicleAction.Pickup) {
201            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
202              throw new Exception("Order already assigned");
203
204            if (simulationTime < order.PickupReadyTime) {
205              if (vehicle.VehicleState != VehicleState.Waiting) {
206                if (diversionAllowed)
207                  vehicle.ReadyTime = simulationTime;
208
209                vehicle.VehicleState = VehicleState.Waiting;
210                interruptable = diversionAllowed;
211                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
212              }
213
214              double waitTime = Math.Min(tickTime,
215                order.PickupReadyTime - simulationTime);
216
217              simulationTime += waitTime;
218              tickTime -= waitTime;
219            }
220
221            //pickup
222            if (simulationTime >= order.PickupReadyTime &&
223              tickTime > 0) {
224              if (vehicle.VehicleState != VehicleState.Servicing) {
225                if (diversionAllowed) {
226                  vehicle.ReadyTime = simulationTime;
227                  vehicle.ReadyTime += order.PickupServiceTime;
228                }
229
230                vehicle.VehicleState = VehicleState.Servicing;
231                interruptable = false;
232                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
233              }
234
235              if (order.OrderState != OrderState.PickingUp) {
236                order.Vehicle = vehicle.Id;
237                order.OrderState = OrderState.PickingUp;
238                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
239              }
240
241              if (serviceTime == 0 && simulationTime > order.PickupDueTime) {
242                order.Tardiness += simulationTime - order.PickupDueTime;
243              }
244
245              double service = Math.Min(tickTime,
246                order.PickupServiceTime - serviceTime);
247
248              serviceTime += service;
249              simulationTime += service;
250              tickTime -= service;
251
252              //load
253              if (serviceTime == order.PickupServiceTime) {
254                vehicle.Capacity -= order.Demand;
255
256                if (vehicle.Capacity < 0) {
257                  vehicle.Overload = -vehicle.Capacity;
258                  vehicle.Capacity = 0;
259                }
260
261                vehicle.PickedUpOrders.Add(order.Id);
262                order.Vehicle = vehicle.Id;
263                order.OrderState = OrderState.PickedUp;
264                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
265
266                vehicle.VehicleState = VehicleState.Waiting;
267                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
268                completed = true;
269              }
270            }
271          } else if (action == VehicleAction.Deliver) {
272            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
273              throw new Exception("Order already assigned");
274
275            if (simulationTime < order.DeliveryReadyTime) {
276              if (vehicle.VehicleState != VehicleState.Waiting) {
277                if (diversionAllowed)
278                  vehicle.ReadyTime = simulationTime;
279
280                vehicle.VehicleState = VehicleState.Waiting;
281                interruptable = diversionAllowed;
282                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
283              }
284
285              double waitTime = Math.Min(tickTime,
286                order.DeliveryReadyTime - simulationTime);
287
288              simulationTime += waitTime;
289              tickTime -= waitTime;
290            }
291
292            //deliver
293            if (simulationTime >= order.DeliveryReadyTime &&
294              tickTime > 0) {
295              if (vehicle.VehicleState != VehicleState.Servicing) {
296                if (diversionAllowed) {
297                  vehicle.ReadyTime = simulationTime;
298                  vehicle.ReadyTime += order.DeliveryServiceTime;
299                }
300
301                vehicle.VehicleState = VehicleState.Servicing;
302                interruptable = false;
303                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
304              }
305
306              if (order.OrderState != OrderState.Delivering) {
307                order.OrderState = OrderState.Delivering;
308                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
309              }
310
311              if (serviceTime == 0 && simulationTime > order.DeliveryDueTime) {
312                order.Tardiness += simulationTime - order.DeliveryDueTime;
313              }
314
315              double service = Math.Min(tickTime,
316                order.DeliveryServiceTime - serviceTime);
317
318              serviceTime += service;
319              simulationTime += service;
320              tickTime -= service;
321
322              //load
323              if (serviceTime == order.DeliveryServiceTime) {
324                vehicle.Capacity += order.Demand;
325                vehicle.PickedUpOrders.Remove(order.Id);
326                order.OrderState = OrderState.Delivered;
327                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
328
329                vehicle.VehicleState = VehicleState.Waiting;
330                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
331                completed = true;
332              }
333            }
334          } else if (action == VehicleAction.Park) {
335            completed = true;
336
337            if (vehicle.VehicleState != VehicleState.Parked) {
338              vehicle.VehicleState = VehicleState.Parked;
339              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
340
341              if (vehicle.PositionX == vehicle.DepotX && vehicle.PositionY == vehicle.DepotY) {
342                if (simulationTime > vehicle.DueTime) {
343                  vehicle.Tardiness = simulationTime - vehicle.DueTime;
344                }
345              }
346            }
347          } else if (action == VehicleAction.Wait) {
348            completed = true;
349
350            if (vehicle.VehicleState != VehicleState.Waiting) {
351              vehicle.VehicleState = VehicleState.Waiting;
352              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
353            }
354          } else if (action == VehicleAction.Invalid) {
355            completed = true;
356
357            if (vehicle.VehicleState != VehicleState.InvalidAction) {
358              vehicle.VehicleState = VehicleState.InvalidAction;
359              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
360            }
361          }
362        }
363
364        return simulationTime;
365      }
366    }
367  }
368}
Note: See TracBrowser for help on using the repository browser.