A distributor of turf-equipment parts stocks a mower deck belt. It sells almost nowhere in winter, very heavily in spring, and again in autumn as dealers build up for the next season.
| \(t\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| \(d_t\) | 40 | 60 | 120 | 300 | 420 | 260 | 120 | 40 | 0 | 80 | 180 | 220 |
| Question | Answer |
|---|---|
| What is stocked? | One item, the belt |
| What is the demand process? | Known in advance, but different in every month |
| When is inventory reviewed? | Once a month, at the month boundary |
| What triggers replenishment, and how much? | A plan decided before the year starts |
| What happens to unmet demand? | None occurs; every requirement is met in its month |
| What costs are incurred, and when? | \(k = \$300\) each month an order is placed; \(h\) for every belt carried into the next month |
Recall that \(h = ic\). Then nothing stops us from applying the economic order quantity to the average requirement:
\[ \begin{aligned} h &= ic = 0.02 \times \$50 = \$1.00 \text{ per belt per month} &&\text{the holding rate}\\ \bar{d} &= 1{,}840 / 12 = 153.33 \text{ belts per month} &&\text{the average requirement}\\ Q^{*} &= \sqrt{\frac{2(300)(153.33)}{1.00}} = 303.3 \text{ belts} &&\text{the economic order quantity}\\ Q^{*}/\bar{d} &= 303.3 / 153.33 = 1.98 \text{ months} &&\text{its time supply} \end{aligned} \]
Two months of supply is five months of stock in February and less than one month in May. The quantity was derived from a sawtooth of identical triangles, and this item never has one.
The classical argument minimizes cost per unit time over one cycle, and it can because every cycle is the same. Here there is no repeating cycle, so there is nothing for the calculus to minimize. We are no longer looking for a quantity. We are looking for a schedule.
The horizon runs over \(N\) periods, \(t = 1, \ldots, N\). In each period let
Together these are the requirements schedule. In every example \(k_t = k\), \(c_t = c\) and \(h_t = h\), and the subscript is dropped when that is so.
Let \(d[t,u]\) represent the requirement of periods \(t\) through \(u\):
\[ d[t,u] = \sum_{s=t}^{u} d_s, \qquad d[t,u] = 0 \text{ when } u < t . \]
For example, \(d[1,3] = 40 + 60 + 120 = 220\), and \(d[5,9] = 420 + 260 + 120 + 40 + 0 = 840\).
Ten assumptions place the model. Four of them shape every number today.
Demand within a period is met from stock at its start (4). A unit that arrives in period \(t\) and is consumed in period \(t\) is never held, so it is charged nothing.
No shortages (6). Every requirement is met in the period it falls.
Start and end empty (8). The plan neither inherits nor bequeaths a position, so the cost computed is the cost of the horizon.
Carrying is charged on the ending balance (10). Some treatments charge the average of the beginning and ending balances, and get a different answer to the same problem.
Assumption 2, that the requirements are known for all \(N\) periods, is the strong one. Next session is about what to do because it is false.
A plan is a quantity \(Q_t \ge 0\) for each period. Let \(I_t\) represent the ending inventory, and \(y_t = 1\) if an order is placed in period \(t\) and 0 otherwise:
\[ \begin{aligned} I_t &= I_{t-1} + Q_t - d_t, \qquad I_0 = I_N = 0, \quad I_t \ge 0 &&\text{the balance, with no shortages}\\ TC &= \sum_{t} k_t y_t + \sum_{t} c_t Q_t + \sum_{t} h_t I_t &&\text{ordering, purchase, carrying}\\ \text{purchase} &= c \sum_{t} Q_t = c \sum_{t} d_t &&\text{constant $c$; assumptions 6 and 8 force } \textstyle\sum Q_t = \sum d_t\\ TRC &= \sum_{t} k_t y_t + \sum_{t} h_t I_t &&\text{drop the constant: the relevant cost} \end{aligned} \]
Every figure today is a relevant cost unless it says otherwise.
If the belt costs $50 through June and $54 afterwards, buying in June for a July requirement is worth $4 a belt, and the purchase term becomes part of the decision. This is the one place in the book where it cannot be dropped, and the derivations keep \(c_t\) for that case.
Lot-for-lot orders what each period needs, \(Q_t = d_t\). Nothing is ever carried. It is the plan an MRP system produces by default.
An adjusted economic order quantity computes \(Q^{*} = 303.3\) from the average, then covers the whole number of periods whose total comes closest to \(Q^{*}\). It keeps the quantity roughly steady and lets the timing float.
A periodic order quantity converts \(Q^{*}\) into a time supply, \(T_{EOQ} = Q^{*}/\bar{d} = 1.98\), rounds it to \(T = 2\) months, and orders two months of requirement every time: in months 1, 3, 5, 7, 9 and 11.
The adjustment matters. A stricter rule that orders exactly \(Q^{*}\) every time cannot promise to finish the horizon empty, so it breaks assumption 8 and does not fit this model.
Let’s take \(T = 2\). The order in month 1 covers months 1 and 2, so \(Q_1 = 40 + 60 = 100\).
| \(t\) | \(d_t\) | \(I_{t-1}\) | \(Q_t\) | \(I_t = I_{t-1} + Q_t - d_t\) | Setup | Carrying |
|---|---|---|---|---|---|---|
| 1 | 40 | 0 | 100 | 60 | $300 | $60 |
| 2 | 60 | 60 | 0 | 0 | $0 | |
| 3 | 120 | 0 | 420 | 300 | $300 | $300 |
| 4 | 300 | 300 | 0 | 0 | $0 | |
| 5 | 420 | 0 | 680 | 260 | $300 | $260 |
| 6 | 260 | 260 | 0 | 0 | $0 | |
| 7 | 120 | 0 | 160 | 40 | $300 | $40 |
| 8 | 40 | 40 | 0 | 0 | $0 | |
| 9 | 0 | 0 | 80 | 80 | $300 | $80 |
| 10 | 80 | 80 | 0 | 0 | $0 | |
| 11 | 180 | 0 | 400 | 220 | $300 | $220 |
| 12 | 220 | 220 | 0 | 0 | $0 |
Six orders cost $1,800, and 960 belt-months at $1.00 cost $960: $2,760. The check: \(\sum Q_t = 1{,}840 = \sum d_t\), and the year ends empty.
At each order, compare the running totals with \(Q^{*} = 303.3\) and stop at the closest.
| Order in | Running totals | Closest | Covers | Belt-months carried |
|---|---|---|---|---|
| 1 | 40, 100, 220, 520 | 220 | 1 to 3 | \(180 + 120 = 300\) |
| 4 | 300, 720 | 300 | 4 | 0 |
| 5 | 420, 680 | 420 | 5 | 0 |
| 6 | 260, 380 | 260 | 6 | 0 |
| 7 | 120, 160, 160, 240, 420 | 240 | 7 to 10 | \(120 + 80 + 80 = 280\) |
| 11 | 180, 400 | 400 | 11 to 12 | 220 |
Six orders cost $1,800 and 800 belt-months cost $800: $2,600.
| Plan | Orders | Setup | Carrying | Relevant cost |
|---|---|---|---|---|
| Lot-for-lot | 11 | $3,300 | $0 | $3,300 |
| Adjusted economic order quantity | 6 | $1,800 | $800 | $2,600 |
| Periodic order quantity, \(T = 2\) | 6 | $1,800 | $960 | $2,760 |
An optimal plan never orders in a period that starts with stock on hand: \(I_{t-1} Q_t = 0\) for every \(t\).
The argument is an exchange. Suppose a plan orders \(Q_t > 0\) into \(I_{t-1} > 0\). Let \(\delta = \min(I_{t-1}, Q_t) > 0\); those units were bought in some earlier period \(r < t\). Buy them in \(t\) instead:
\[ \begin{aligned} \text{feasibility} &: \text{unchanged} &&\text{the same units in the same periods}\\ \text{setup in } t &: \text{unchanged} &&\text{period $t$ still orders}\\ \text{carrying} &: -\,\delta \textstyle\sum_{s=r}^{t-1} h_s \le 0 &&\text{the $\delta$ units no longer wait from $r$ to $t$}\\ \text{purchase} &: \delta\,(c_t - c_r) = 0 &&\text{constant unit cost} \end{aligned} \]
Thus, the new plan costs no more, and if it empties period \(r\) a setup is saved as well. Repeating the exchange removes every violation.
If a plan orders only when empty, an order in period \(t\) must cover periods \(t\) through the period before the next order, and no more. That is, the quantity is determined by the timing:
\[ Q_t = d[t,u] \quad \text{where $u + 1$ is the next period with an order.} \]
Thus, a plan is a set of order periods. Period 1 always orders, because inventory starts at zero, and each of periods 2 through \(N\) either orders or does not:
\[ 2^{N-1} = 2^{11} = 2{,}048 \text{ plans for the belt}, \qquad 2^{51} \approx 2 \times 10^{15} \text{ at } N = 52 . \]
Enumeration is not the answer. The fact that the plans can be counted at all is what makes the rest of the chapter possible.
Let the window cost \(w(t,u)\) represent the cost of a replenishment placed in period \(t\) that covers periods \(t\) through \(u\). The units for period \(t\) are never carried; those for \(t+1\) are charged \(h_t\); those for \(t+2\) are charged \(h_t + h_{t+1}\); and so on:
\[ \begin{aligned} w(t,u) &= k_t + \sum_{s=t}^{u} d_s \left( c_t + \sum_{r=t}^{s-1} h_r \right) &&\text{order, buy, and carry each unit until used}\\ \hat{c}(t,s) &= c_t + \sum_{r=t}^{s-1} h_r, \qquad \hat{c}(t,t) = c_t &&\text{one unit bought in $t$, used in $s$}\\ w(t,u) &= k_t + \sum_{s=t}^{u} d_s\, \hat{c}(t,s) &&\text{an inner product of requirements and prices}\\ w(t,u) &= k + h \sum_{s=t}^{u} (s - t)\, d_s &&\text{constant costs, purchase term dropped} \end{aligned} \]
Notice two things. \(w(t,u)\) depends on no decision, so every window cost can be computed once, before any search. And it increases in \(u\) with growing steps, because a unit added at the far end has waited longest.
With \(k = \$300\) and \(h = \$1.00\): \(w(1,3) = 300 + 1.00\left[0(40) + 1(60) + 2(120)\right] = 300 + 300 = \$600\).
| \(w(t,u)\) | \(u = 1\) | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| \(t = 1\) | 300 | 360 | 600 | 1,500 | 3,180 | 4,480 |
| 2 | 300 | 420 | 1,020 | 2,280 | 3,320 | |
| 3 | 300 | 600 | 1,440 | 2,220 | ||
| 4 | 300 | 720 | 1,240 | |||
| 5 | 300 | 560 | ||||
| 6 | 300 |
Every diagonal entry is $300: one period carries nothing. Each step along a row is \(h(u + 1 - t)\,d_{u+1}\). Along row 1 that is \(1(60)\), \(2(120)\), \(3(300)\), \(4(420)\), \(5(260)\), or 60, 240, 900, 1,680 and 1,300, growing until month 6, whose requirement is smaller than month 5’s.
Suppose \(d_t > k_t / h_{t-1}\). Then
\[ \begin{aligned} h_{t-1}\, d_t &> k_t &&\text{multiply through by } h_{t-1}\\ \text{carry $d_t$ in from $t-1$} &> \text{order afresh in $t$} &&\text{read each side as a cost} \end{aligned} \]
Thus, no optimal plan carries anything into period \(t\), and every optimal plan orders in period \(t\).
For the belt, \(k/h = 300/1.00 = 300\) belt-months. Month 5 needs 420 belts, and \(420 > 300\), so every optimal plan orders in month 5. Nothing else in the year is that large.
A forced order splits the horizon. No window spans months 4 and 5, so one problem of 12 periods becomes two, of 4 and 8. Next session shows this is also why a rolling horizon can be cut short without losing anything.
Node \(t\) means the plan reaches period \(t\) holding nothing. The arc from \(t\) to \(u + 1\) is a replenishment in \(t\) covering through \(u\), priced \(w(t,u)\).
A path from node 1 to node \(N + 1\) is a sequence of windows that tile the horizon, which is a plan, and its length is the plan’s cost.
Notice the heavy path for the first four months: order in month 1 to cover months 1 to 3, and again in month 4, for \(600 + 300 = \$900\).
Thus, lot sizing is a shortest path on an acyclic network of \(N + 1\) nodes and \(N(N+1)/2\) arcs, every arc priced before the search begins.
Let \(V(u)\) represent the least cost of covering periods 1 through \(u\) and arriving at \(u + 1\) with nothing on hand, and \(S(u)\) the period in which that plan’s last order is placed. Then \(V(0) = 0\) and
\[ V(u) = \min_{1 \le t \le u} \left\{ V(t-1) + w(t,u) \right\}, \qquad u = 1, \ldots, N . \]
Read it as a question about the last order. Whatever the best plan for periods 1 through \(u\) is, its last order falls in some period \(t\) and covers \(t\) through \(u\). Everything before \(t\) is a plan for periods 1 through \(t - 1\) that arrives at \(t\) empty, and it had better be the cheapest such plan, or we could substitute the cheapest and do better.
\(V(N)\) is the optimal cost. The traceback recovers the plan: the last order starts in \(S(N)\); the one before it starts in \(S(S(N) - 1)\); and so on until an order starts in period 1.
wagnerWhitin(d, k, c, h over periods 1..N):
// the windows, which depend on no decision
for t = 1 to N:
for u = t to N:
w(t,u) <- k(t) + sum over s in t..u of d(s) * chat(t,s)
// the recursion
V(0) <- 0
for u = 1 to N:
V(u) <- infinity
for t = 1 to u:
if V(t-1) + w(t,u) < V(u):
V(u) <- V(t-1) + w(t,u)
S(u) <- t
// the traceback
u <- N
while u >= 1:
t <- S(u)
add (order in period t, quantity d[t,u]) to orders
u <- t - 1
Notice that the three blocks are independent: the windows are data, the recursion is a shortest path, and the traceback reads the plan off the pointers.
Each entry is \(V(t-1)\) from an earlier column plus a window cost. One column per click; the least entry in each column is \(V(u)\).
| \(V(t-1) + w(t,u)\) | \(u = 1\) | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| last order in 1 | 300 | 360 | 600 | 1,500 | 3,180 | 4,480 |
| 2 | 600 | 720 | 1,320 | 2,580 | 3,620 | |
| 3 | 660 | 960 | 1,800 | 2,580 | ||
| 4 | 900 | 1,320 | 1,840 | |||
| 5 | 1,200 | 1,460 | ||||
| 6 | 1,500 | |||||
| \(V(u)\) | 300 | 360 | 600 | 900 | 1,200 | 1,460 |
| \(S(u)\) | 1 | 1 | 1 | 4 | 5 | 5 |
Covering periods 1 through 4, the last order falls in one of four periods:
\[ \begin{aligned} t = 1 &: V(0) + w(1,4) = 0 + 1{,}500 = 1{,}500 &&\text{one order covers all four}\\ t = 2 &: V(1) + w(2,4) = 300 + 1{,}020 = 1{,}320 &&\text{best plan for month 1, then 2 to 4}\\ t = 3 &: V(2) + w(3,4) = 360 + 600 = 960 &&\text{best plan for 1 to 2, then 3 to 4}\\ t = 4 &: V(3) + w(4,4) = 600 + 300 = 900 &&\text{best plan for 1 to 3, then 4 alone} \end{aligned} \]
The least is 900, so \(V(4) = 900\) and \(S(4) = 4\).
Notice that each line reuses a \(V\) already computed. Nothing is ever recomputed, and that is why the whole table is \(N(N+1)/2\) additions and minima: 21 for six months, 78 for twelve, 1,378 for a 52-week horizon.
The traceback starts at \(u = 6\):
\[ \begin{aligned} S(6) = 5 &: \text{order in 5 covers 5 to 6}, \; d[5,6] = 420 + 260 = 680 &&\text{now } u = 4\\ S(4) = 4 &: \text{order in 4 covers 4 alone}, \; d[4,4] = 300 &&\text{now } u = 3\\ S(3) = 1 &: \text{order in 1 covers 1 to 3}, \; d[1,3] = 220 &&\text{period 1 reached: stop} \end{aligned} \]
| \(t\) | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| \(d_t\) | 40 | 60 | 120 | 300 | 420 | 260 |
| \(Q_t\) | 220 | 0 | 0 | 300 | 680 | 0 |
| \(I_t\) | 180 | 120 | 0 | 0 | 260 | 0 |
The check. Three orders cost $900 and \(180 + 120 + 260 = 560\) belt-months cost $560, for $1,460 \(= V(6)\). The recursion and the ledger are two readings of the same numbers. That check is worth performing every time, because if the ledger does not reproduce \(V(N)\) then one of them was done wrong.
| \(u\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| \(V(u)\) | 300 | 360 | 600 | 900 | 1,200 | 1,460 | 1,620 | 1,700 | 1,700 | 2,000 | 2,180 | 2,480 |
| \(S(u)\) | 1 | 1 | 1 | 4 | 5 | 5 | 6 | 6 | 6 | 10 | 10 | 12 |
Tracing back from \(u = 12\): \(S(12) = 12\), \(S(11) = 10\), \(S(9) = 6\), \(S(5) = 5\), \(S(4) = 4\), \(S(3) = 1\). Orders in months 1, 4, 5, 6, 10 and 12:
| \(t\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| \(Q_t\) | 220 | 0 | 0 | 300 | 420 | 420 | 0 | 0 | 0 | 260 | 0 | 220 |
| \(I_t\) | 180 | 120 | 0 | 0 | 0 | 160 | 40 | 0 | 0 | 180 | 0 | 0 |
The check. Six orders cost $1,800 and 680 belt-months cost $680: $2,480 \(= V(12)\).
Notice that \(V(9) = V(8)\): month 9 requires nothing, so covering through it costs what covering through month 8 costs. Notice also that month 5 holds an order, as the forced-order test promised. The optimum saves $820 on lot-for-lot and $120 on the adjusted economic order quantity, which was within 4.84%.
\[ \begin{aligned} \min \quad & \sum_{t} k_t y_t + \sum_{t} c_t Q_t + \sum_{t} h_t I_t \\ \text{subject to} \quad & I_t = I_{t-1} + Q_t - d_t, && t = 1, \ldots, N \\ & Q_t \le M y_t, && t = 1, \ldots, N \\ & I_0 = 0, \quad I_t \ge 0, \quad Q_t \ge 0, \quad y_t \in \{0, 1\}, && t = 1, \ldots, N \end{aligned} \]
The setup is a fixed charge, zero at zero and \(k_t\) the moment anything is ordered, which no linear function of \(Q_t\) alone can write. The device is the binary \(y_t\): if \(y_t = 0\) then \(Q_t\) is forced to zero. \(M = d[1,N] = 1{,}840\) never binds.
Keep \(M\) as small as is safe. A needlessly large \(M\) weakens the linear relaxation, and the solver’s branch and bound takes longer for no benefit.
Two reasons to know it: it accepts constraints the recursion cannot (a limit on the order size, shared capacity, a minimum order), and it is how commercial planning systems solve the problem when those constraints are present.
With no repeating cycle, the economic order quantity has nothing to minimize. We look for a schedule, not a quantity.
The relevant cost is setup plus carrying, because a constant unit cost makes the purchase term the same under every plan.
Zero-inventory ordering makes a plan a set of order periods: 2,048 of them for the belt.
The window cost \(w(t,u)\) depends on no decision, so every window is priced once.
The recursion \(V(u) = \min_t\{V(t-1) + w(t,u)\}\) is a shortest path, and the traceback and the ledger must agree: $2,480 for the belt, against $2,600 to $3,300 for the three plans without theory.
A requirement above \(k/h\) forces an order: month 5.
Read before next session: Three Heuristics and One Shape, What a Heuristic Costs and The Rolling Horizon.
Today’s material was When the Demand Rate Changes, What a Plan Costs, Two Properties That Make the Problem Small and Choosing the Order Periods.
Next session:
Bring the $2,480 and the window cost table. Every heuristic next session reads the same windows.