Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/MoveVehicleAction.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: 14.0 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.ServiceRequest && order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp) ||
115                                                 (!order.ServiceRequest && ((order.OrderState != OrderState.PickedUp && order.OrderState != OrderState.Delivering) || !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 || (action == VehicleAction.Deliver && order.ServiceRequest)) {
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.PickupTime = simulationTime;
237                order.Vehicle = vehicle.Id;
238                order.OrderState = OrderState.PickingUp;
239                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
240
241                if (simulationTime > order.PickupDueTime) {
242                  order.Tardiness += simulationTime - order.PickupDueTime;
243                }
244              }
245
246              double service = Math.Min(tickTime,
247                order.PickupServiceTime - serviceTime);
248
249              serviceTime += service;
250              simulationTime += service;
251              tickTime -= service;
252
253              //load
254              if (serviceTime == order.PickupServiceTime) {
255                vehicle.Capacity -= order.Demand;
256
257                if (vehicle.Capacity < 0) {
258                  vehicle.Overload += -vehicle.Capacity;
259                  vehicle.Capacity = 0;
260                }
261
262                vehicle.PickedUpOrders.Add(order.Id);
263                order.Vehicle = vehicle.Id;
264                if (order.ServiceRequest)
265                  order.OrderState = OrderState.Delivered;
266                else
267                  order.OrderState = OrderState.PickedUp;
268                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
269
270                vehicle.VehicleState = VehicleState.Waiting;
271                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
272                completed = true;
273              }
274            }
275          } else if (action == VehicleAction.Deliver) {
276            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
277              throw new Exception("Order already assigned");
278
279            if (simulationTime < order.DeliveryReadyTime) {
280              if (vehicle.VehicleState != VehicleState.Waiting) {
281                if (diversionAllowed)
282                  vehicle.ReadyTime = simulationTime;
283
284                vehicle.VehicleState = VehicleState.Waiting;
285                interruptable = diversionAllowed;
286                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
287              }
288
289              double waitTime = Math.Min(tickTime,
290                order.DeliveryReadyTime - simulationTime);
291
292              simulationTime += waitTime;
293              tickTime -= waitTime;
294            }
295
296            //deliver
297            if (simulationTime >= order.DeliveryReadyTime &&
298              tickTime > 0) {
299              if (vehicle.VehicleState != VehicleState.Servicing) {
300                if (diversionAllowed) {
301                  vehicle.ReadyTime = simulationTime;
302                  vehicle.ReadyTime += order.DeliveryServiceTime;
303                }
304
305                vehicle.VehicleState = VehicleState.Servicing;
306                interruptable = false;
307                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
308              }
309
310              if (order.OrderState != OrderState.Delivering) {
311                order.DeliveryTime = simulationTime;
312                order.OrderState = OrderState.Delivering;
313                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
314
315                if (simulationTime > order.DeliveryDueTime) {
316                  order.Tardiness += simulationTime - order.DeliveryDueTime;
317                }
318              }
319
320              double service = Math.Min(tickTime,
321                order.DeliveryServiceTime - serviceTime);
322
323              serviceTime += service;
324              simulationTime += service;
325              tickTime -= service;
326
327              //load
328              if (serviceTime == order.DeliveryServiceTime) {
329                vehicle.Capacity += order.Demand;
330                vehicle.PickedUpOrders.Remove(order.Id);
331                order.OrderState = OrderState.Delivered;
332                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
333
334                vehicle.VehicleState = VehicleState.Waiting;
335                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
336                completed = true;
337              }
338            }
339          } else if (action == VehicleAction.Park) {
340            completed = true;
341
342            if (vehicle.VehicleState != VehicleState.Parked) {
343              vehicle.VehicleState = VehicleState.Parked;
344              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
345
346              if (vehicle.PositionX == vehicle.DepotX && vehicle.PositionY == vehicle.DepotY) {
347                if (simulationTime > vehicle.DueTime) {
348                  vehicle.Tardiness = simulationTime - vehicle.DueTime;
349                }
350              }
351            }
352          } else if (action == VehicleAction.Wait) {
353            completed = true;
354
355            if (vehicle.VehicleState != VehicleState.Waiting) {
356              vehicle.VehicleState = VehicleState.Waiting;
357              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
358            }
359          } else if (action == VehicleAction.Invalid) {
360            completed = true;
361
362            if (vehicle.VehicleState != VehicleState.InvalidAction) {
363              vehicle.VehicleState = VehicleState.InvalidAction;
364              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
365            }
366          }
367        }
368
369        return simulationTime;
370      }
371    }
372  }
373}
Note: See TracBrowser for help on using the repository browser.