6.3 Integrated Approach
6.3.3 Forward Propagation
In this section we describe the four steps Wait, Serve, Drive, and Setup of each itera- tion. Both−→dlstepR[i]and−→dsstepR[i],jonly change in step Drive. After the presentation of step Setup, we revise step Wait slightly and show how to remove redundant driver states.
6.3.3.1 Step Wait
In this step of an iteration i≤ |R|, we take account of the time windows of customer ci. The scalar values remain unchanged in this step, that is,
−→ dlwaited R[i] := −→ dlsetupR[i] and −→ dswaited R[i],j := −→
dssetupR[i],j for every j ≤ i. So in the following, it is all about determining
−→
6.3. Integrated Approach 119 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 Planning horizon W aiting time
FIGURE6.3: Forward waiting time function−→W in red and dashed. Backward waiting time function←W in blue. These functions corre-− spond to the time windows in the background (gray). Here, a service
time of 1 is assumed.
We proceed as in step Wait of previous chapters and first define an auxiliary function for every j≤i:
Hshiftj (t):=max{t0 |t =t0+−→WR[i](t0) ∧
−→
TsetupR[i],j(t0) 6= ⊥}
where the maximum over the empty set is supposed to be⊥. Next, we treat the cases j = i and j < i separately and begin with the former. By construction of the algorithm, we know that dssetupR[i],i = 0, that is, the driver is completely rested. In this case, waiting coincides with prolonging the break. So with the help of Hishift(t), we set−→TwaitedR[i],i(t)as follows:
−→
TwaitedR[i],i(t):=−→TsetupR[i],i(Hishift(t)) + (t−Hishift(t))
for all t for which Hishift(t)is defined, and−→TwaitedR[i],i(t):= ⊥for all other t. But what about−→Twaited
R[i],j for a j < i? In this case, we have to be careful if we do
not want to create dominated driver states. For example, we should only allow to wait for less than the minimum break duration break in this case because otherwise the driver state after waiting would be dominated by a state contained in −→Fwaited
R[i],i
already. But there is more, as Figure 6.4 suggests. Here, two schedules are depicted. By construction of the example, both schedules cannot be shifted to the right, and so a driver that follows either of these schedules has to wait until the time window of the fourth customer opens. In the red schedule, there is an early break planned at the second customer, whereas in the blue schedule, there is an early break planned at the third customer. So the driver state at the end of the red schedule is contained in
−→ FsetupR[
4],2, the other in −→
FsetupR[
4],3. In this example, the state of a driver that follows the red
schedule would be dominated by the state of a driver following the blue schedule if both drivers waited for the time window to open.
The rough idea how to further improve this step and not create dominated states is the following: Suppose the tuples are sorted by dssetupR[i],jin increasing order. Whe- never we consider waiting for the beginning of a time window, we store the (best known) travel time for that point in time. We only allow to create a driver state for this point in time if the travel time is less than the previously stored value (initially infinite).
120 Chapter 6. Vehicle Routing and Truck Driver Scheduling 0 1 2 3 4 5 6 7 8 Planning horizon Driving time 1 1 1
FIGURE6.4: Both drivers must wait before the service at the fourth customer. But the driver state of the red driver would be dominated
by the blue driver after waiting for the time window to open.
Now in more detail: Let Qbe a sequence of wi periods of time, that is, one for
every time window of customer ci. For every k from 1 to wi and thus for every
beginning t := α(Wik)of a time window, we initially set Q[k]to
−→
TwaitedR[i],i(t) if this value is defined and to∞ otherwise. For every j < i, in increasing order of dssetupR[i],j, and again every k from 1 to wi (in no particular order), we only allow to wait for
the beginning t := α(Wik) of the k-th time window if the expected travel time
−→
TsetupR[i],j(Hshiftj (t)) + (t−Hshiftj (t)) is less thanQ[k]. If it is, then we set Q[k]to this lower value. Precisely, we set
−→
TwaitedR[i],j(t):= −→TsetupR[i],j(Hjshift(t)) + (t−Hshiftj (t))
for all t for which Hshiftj (t)is defined and, should t equal the beginning of the k-th time window, for which −→TsetupR[i],j(Hjshift(t)) + (t−Hjshift(t))is less than Q[k]. Other- wise we set−→TwaitedR[i],j(t):= ⊥.
6.3.3.2 Step Serve
This step is again the simplest. All we have to do is to shift the pieces to the right and raise them by the service time, that is, for all j≤i:
−→
TservedR[i],j(t):=−→TR[waitedi],j(t−serviceR[i]) +serviceR[i]
for all t within the planning horizon, and−→TservedR[i],j(t):= ⊥for all other points in time. Again, the scalar values remain unchanged in this step.
6.3.3.3 Step Drive
In this step, we consider the driving time driveR[i],R[i+1] from customerR[i]to cus- tomerR[i+1](this step is only called if i < |R|). In this section, we use the short notation driveifor driveR[i],R[i+1]. The driving time rule may enforce a break (or even
6.3. Integrated Approach 121
auxiliary variable hexc
j for every j≤i that states by how much the driving time limit
would be exceeded if the driver did not take a break en route: hexcj :=−→dsR[servedi],j +drivei−limitDshort
If hexcj ≤0, then the driver is able to arrive at the next customer without having to take a break. We increase the scalar value concerning the accumulated driving time since last break by drivei, and we shift (to the right) and raise the pieces of the travel
time function by the same value:
−→
dsdrivenR[i],j := −→dsservedR[i],j +drivei −→
TdrivenR[i],j(t):= −→TservedR[i],j(t−drivei) +drivei
However, if hexcj > 0, then the driver must take a break en route after a dri- ving time of limitDshort−
−→
dsservedR[i],j, otherwise the driving time rule would be violated. Should even hexcj >limitDshorthold, then additional breaks become due. In total, as
many as
h#j :=lhexcj /limitDshortm
breaks must be taken en route. With this variable, we have everything we need to set
−→ Fdriven
R[i],j in case hexcj is greater than zero. The accumulated driving time −→
dsdrivenR[i],j is set to the driving time after the last break en route, which is hexcj − (h#j −1) ·limitDshort. The
travel time function−→TdrivenR[i],j is shifted (to the right) and raised by the same time as time passes between departure from customer ci and arrival at customer ci+1, which
is drivei+h#j ·break. To sum it up, we set: −→
dsdrivenR[i],j := hexcj − (h#j −1) ·limitDshort
−→
TdrivenR[i],j(t):=−→TR[servedi],jt− (drivei+h#j ·break)
+ (drivei+h#j ·break)
To conclude this step, we set−→dldriven
R[i] := −→ dlserved R[i] +drivei. Now, −→ Ldriven R[i] contains all significant states of a driver who has just arrived at the next customer.
6.3.3.4 Step Setup
Like step Drive, this step is only called if i< |R|. For all j≤i we set
−→
FsetupR[i+1],j:=−→FdrivenR[i],j
The pair−→FsetupR[i+
1],i+1 represents the case that an early short break is taken at cu-
stomer R[i+1]. Hence, we set −→dssetupR[i+1],i+1 := 0. To set −→TR[setupi+1],i+1, we need an intermediate step. First, we introduce a function−→T0R[i+1],i+1. It is defined to be the minimum of all the−→TdrivenR[i],j (j≤ i), shifted (to the right) and raised by the minimum break duration. That is, we set it as follows:
−→
T0R[i+1],i+1(t):=min
j≤i −→
122 Chapter 6. Vehicle Routing and Truck Driver Scheduling
for all t∈ Hand−→T0R[i+1],i+1(t):= ⊥otherwise, where we treat⊥like∞.
In order to guarantee that −→TsetupR[i+1],i+1−id is monotonously decreasing (apart from the gaps where it is undefined), we do the following (treat⊥like∞):
−→ TsetupR[i+1],i+1(t):= ( ⊥, ∃t0 <t : −→T0R[i+1],i+1(t0) +t−t0 ≤ −→TR[0 i+1],i+1(t) −→ T0R[i+1],i+1(t), otherwise
As an example where this is necessary, let us have a look at Figure 4.4 on page 63 again. We see a red schedule with an early short break at the second customer, and a blue schedule with an (implicit) early break at the first customer. Hence, the red driver state is contained in−→Fdriven
R[3],2, whereas the blue driver state is contained in −→
Fdriven
R[3],1. The latest time t for which −→
Tdriven
R[3],1(t)is defined is t=10.5. −→
TsetupR[4],4(t)needs to be set to⊥for every t>10.5+break in this example because for every such t it is better to follow the blue schedule and wait than to take the red schedule.
This concludes the last of the four steps. But still there are potentially dominated driver states contained in−→TsetupR[i+1],i+1. To remove them, we need the knowledge of the time windows of the next customer. So this better fits into step Wait. Therefore, we revise this step.
6.3.3.5 Step Wait, Revised
Beginning with the second iteration (i > 1), it is advisable to apply a dominance rule when we create−→Twaited
R[i],i from −→
TsetupR[i],i. This is due to the fact that an early break can only be beneficial if it starts outside of a time window. Let t be a time for which Hishift(t)is defined. By construction, Hishift(t)is only defined within the time win- dows of customerR[i]. If Hishift(t) −break is inside a time window, there is no reason for an early break because that break could be taken later without any downside. Precisely, we set
−→
TwaitedR[i],i(t):=−→TsetupR[i],i(Hishift(t)) + (t−Hishift(t))
only for those t for which Hishift(t) is defined and additionally Hishift(t) −break ∈ −→
WR[i]holds, where−W→R[i] denotes the union of the forward waiting intervals of cus- tomerR[i]. We set−→TR[waitedi],i(t):= ⊥for all other t.
Finally, we conjecture (but do not prove) that no driver state dominates another driver state that is contained in the same label.