Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 8779 was 8747, checked in by abeham, 12 years ago

#1955:

  • Added priority dispatching (random strategy)
  • Fixed vehicle's current order
File size: 14.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using HeuristicLab.Common;
4using HeuristicLab.PDPSimulation.DistanceMeasures;
5using HeuristicLab.PDPSimulation.DomainModel;
6using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
7
8namespace HeuristicLab.PDPSimulation {
9  public enum VehicleAction { Wait, Pickup, Deliver, Park, Invalid }
10
11  [StorableClass]
12  public class MoveVehicleAction : PDAction {
13    [Storable]
14    double sourceX;
15
16    public double SourceX {
17      get { return sourceX; }
18    }
19
20    [Storable]
21    double sourceY;
22
23    public double SourceY {
24      get { return sourceY; }
25    }
26
27    [Storable]
28    double targetX;
29
30    public double TargetX {
31      get { return targetX; }
32    }
33
34    [Storable]
35    double targetY;
36
37    public double TargetY {
38      get { return targetY; }
39    }
40
41    [Storable]
42    VehicleAction action;
43
44    [Storable]
45    Order order;
46
47    [Storable]
48    double serviceTime;
49
50    [Storable]
51    bool interruptable;
52
53    [Storable]
54    bool completed;
55
56    [Storable]
57    DistanceMeasure distMeasure;
58
59    [Storable]
60    bool diversionAllowed;
61
62    public MoveVehicleAction(
63      Guid vehicleId,
64      double targetX, double targetY, VehicleAction action, Order order, bool diversionAllowed, DistanceMeasure distMeasure)
65      : base(vehicleId) {
66      this.targetX = targetX;
67      this.targetY = targetY;
68      this.action = action;
69      this.order = order;
70      this.serviceTime = 0;
71      this.completed = false;
72      this.diversionAllowed = diversionAllowed;
73      this.interruptable = diversionAllowed;
74      this.distMeasure = distMeasure;
75
76      this.sourceX = -1;
77      this.sourceY = -1;
78    }
79    [StorableConstructor]
80    protected MoveVehicleAction(bool deserializing)
81      : base(deserializing) {
82    }
83    protected MoveVehicleAction(MoveVehicleAction original, Cloner cloner)
84      : base(original, cloner) {
85      this.targetX = original.targetX;
86      this.sourceX = original.sourceX;
87      this.targetY = original.targetY;
88      this.sourceY = original.sourceY;
89      this.action = original.action;
90      this.order = cloner.Clone<Order>(original.order);
91      this.serviceTime = original.serviceTime;
92      this.completed = original.completed;
93      this.interruptable = original.interruptable;
94      this.distMeasure = cloner.Clone<DistanceMeasure>(original.distMeasure);
95      this.diversionAllowed = original.diversionAllowed;
96    }
97    public override IDeepCloneable Clone(Cloner cloner) {
98      return new MoveVehicleAction(this, cloner);
99    }
100
101    protected override bool ActionInterruptable() {
102      return interruptable;
103    }
104
105    public override bool ActionCompleted() {
106      return completed;
107    }
108
109    protected override double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes) {
110      Vehicle vehicle = baseObject as Vehicle;
111      lock (vehicle) {
112        if ((action == VehicleAction.Pickup && (order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp)) ||
113            (action == VehicleAction.Deliver && ((order.ServiceRequest && order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp) ||
114                                                 (!order.ServiceRequest && ((order.OrderState != OrderState.PickedUp && order.OrderState != OrderState.Delivering) || !vehicle.PickedUpOrders.Contains(order.Id))))) ||
115           (order != null && (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id))) {
116          if (vehicle.VehicleState != VehicleState.InvalidAction) {
117            vehicle.InvalidActions++;
118
119            vehicle.VehicleState = VehicleState.InvalidAction;
120            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
121          }
122
123          if (diversionAllowed)
124            vehicle.ReadyTime = simulationTime;
125          interruptable = diversionAllowed;
126          completed = diversionAllowed;
127
128          if (diversionAllowed)
129            return simulationTime;
130          else {
131            if (order != null) {
132              changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderFailed, BaseObject = order });
133              order = null;
134              action = VehicleAction.Invalid;
135            }
136          }
137        }
138
139        if (sourceX == -1) {
140          sourceX = vehicle.PositionX;
141          sourceY = vehicle.PositionY;
142        }
143
144        vehicle.TargetPositionX = targetX;
145        vehicle.TargetPositionY = targetY;
146        vehicle.CurrentAction = action;
147        if (order == null)
148          vehicle.CurrentOrder = Guid.Empty;
149        else {
150          if (!diversionAllowed)
151            order.Vehicle = vehicle.Id;
152          vehicle.CurrentOrder = order.Id;
153          changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
154        }
155
156        if (action == VehicleAction.Wait || action == VehicleAction.Park)
157          if (diversionAllowed)
158            vehicle.ReadyTime = simulationTime;
159
160        double tx, ty, length;
161        distMeasure.Move(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY, tickTime, vehicle.MoveInfo,
162          out tx, out ty, out length);
163
164        if (!diversionAllowed) {
165          double time = simulationTime;
166          time += distMeasure.GetDistance(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY);
167          if (action == VehicleAction.Pickup) {
168            if (time < order.PickupReadyTime)
169              time = order.PickupReadyTime;
170
171            time += order.PickupServiceTime - serviceTime;
172          } else if (action == VehicleAction.Deliver) {
173            if (time < order.DeliveryReadyTime)
174              time = order.DeliveryReadyTime;
175
176            time += order.DeliveryServiceTime - serviceTime;
177          }
178
179          vehicle.ReadyTime = time;
180        }
181
182        vehicle.PositionX = tx;
183        vehicle.PositionY = ty;
184
185        if (length > 0) {
186          vehicle.Distance += length;
187          tickTime -= length;
188          simulationTime += length;
189
190          if (vehicle.VehicleState != VehicleState.Moving) {
191            vehicle.VehicleState = VehicleState.Moving;
192            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
193          }
194          changes.Add(
195            new PDChange() { ChangeType = SimulationStateChange.VehicleMoved, BaseObject = baseObject });
196        }
197
198        if (vehicle.PositionX == targetX && vehicle.PositionY == targetY) {
199          if (action == VehicleAction.Pickup || (action == VehicleAction.Deliver && order.ServiceRequest)) {
200            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
201              throw new Exception("Order already assigned");
202
203            if (simulationTime < order.PickupReadyTime) {
204              if (vehicle.VehicleState != VehicleState.Waiting) {
205                if (diversionAllowed)
206                  vehicle.ReadyTime = simulationTime;
207
208                vehicle.VehicleState = VehicleState.Waiting;
209                interruptable = diversionAllowed;
210                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
211              }
212
213              double waitTime = Math.Min(tickTime,
214                order.PickupReadyTime - simulationTime);
215
216              simulationTime += waitTime;
217              tickTime -= waitTime;
218            }
219
220            //pickup
221            if (simulationTime >= order.PickupReadyTime &&
222              tickTime > 0) {
223              if (vehicle.VehicleState != VehicleState.Servicing) {
224                if (diversionAllowed) {
225                  vehicle.ReadyTime = simulationTime;
226                  vehicle.ReadyTime += order.PickupServiceTime;
227                }
228
229                vehicle.VehicleState = VehicleState.Servicing;
230                interruptable = false;
231                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
232              }
233
234              if (order.OrderState != OrderState.PickingUp) {
235                order.PickupTime = simulationTime;
236                order.Vehicle = vehicle.Id;
237                order.OrderState = OrderState.PickingUp;
238                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
239
240                if (simulationTime > order.PickupDueTime) {
241                  order.Tardiness += simulationTime - order.PickupDueTime;
242                }
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                if (order.ServiceRequest)
264                  order.OrderState = OrderState.Delivered;
265                else
266                  order.OrderState = OrderState.PickedUp;
267                vehicle.CurrentOrder = Guid.Empty;
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.CurrentOrder = Guid.Empty;
335
336                vehicle.VehicleState = VehicleState.Waiting;
337                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
338                completed = true;
339              }
340            }
341          } else if (action == VehicleAction.Park) {
342            completed = true;
343
344            if (vehicle.VehicleState != VehicleState.Parked) {
345              vehicle.VehicleState = VehicleState.Parked;
346              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
347
348              if (vehicle.PositionX == vehicle.DepotX && vehicle.PositionY == vehicle.DepotY) {
349                if (simulationTime > vehicle.DueTime) {
350                  vehicle.Tardiness = simulationTime - vehicle.DueTime;
351                }
352              }
353            }
354          } else if (action == VehicleAction.Wait) {
355            completed = true;
356
357            if (vehicle.VehicleState != VehicleState.Waiting) {
358              vehicle.VehicleState = VehicleState.Waiting;
359              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
360            }
361          } else if (action == VehicleAction.Invalid) {
362            completed = true;
363
364            if (vehicle.VehicleState != VehicleState.InvalidAction) {
365              vehicle.VehicleState = VehicleState.InvalidAction;
366              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
367            }
368          }
369        }
370
371        return simulationTime;
372      }
373    }
374  }
375}
Note: See TracBrowser for help on using the repository browser.