flowchart LR
N0((0)) -->|"w(1,1)"| N1((1))
N0 -->|"w(1,2)"| N2((2))
N0 -->|"w(1,3)"| N3((3))
N1 -->|"w(2,2)"| N2
N1 -->|"w(2,3)"| N3
N2 -->|"w(3,3)"| N3
A distributor stocks a mower deck belt. It sells almost nowhere in winter, heavily in spring, and again in autumn as dealers build for the following 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 |
Total 1,840 belts, average 153.33 a month. Ordering costs $300, the belt costs $50, carrying charge 2% per month, so \(h = \$1.00\) per belt-month.
\[ Q^{*} = \sqrt{\frac{2(300)(153.33)}{1.00}} = 303.3 \text{ belts} \]
About two months of supply.
The trouble is that the answer means very little.
Two months of supply is nine months of stock in February and less than one month of stock in May.
The quantity was derived from a picture of inventory this item never has: a sawtooth of identical triangles.
The EOQ minimizes cost per unit time over one cycle, and it can do that because every cycle is the same.
Here there is no repeating cycle.
An order placed in month 4 covers a different amount of demand, over a different length of time, at a different carrying cost, than an order placed in month 9.
There is no single cycle whose cost can stand for all of them, so there is nothing for the calculus to minimize.
What replaces it: a finite horizon, and a decision in every period of it.
For each period \(t\) we know
Together, the requirements schedule.
Write \(d[t,u] = \sum_{s=t}^{u} d_s\) for the requirement of periods \(t\) through \(u\). For the belt, \(d[1,3] = 220\) and \(d[5,9] = 840\).
Ten in the text; four carry weight.
Requirements are known for all \(N\) periods. This is the strong one, and the next session is about what to do because it is false.
Demand in a period is met from stock at the start of that period, so a replenishment arriving in a period can cover it.
Carrying cost is charged on the balance at the END of a period. A unit that arrives and is consumed in the same period is charged nothing.
Inventory starts at zero and ends at zero. The plan neither inherits nor bequeaths a position, so the cost we compute is the cost of the horizon.
Lot-for-lot orders exactly what each period needs. Nothing is ever carried. Eleven orders at $300: $3,300, all setup.
An adjusted economic order quantity computes \(Q^{*}\) from the average and covers the whole number of periods coming closest to it. Six orders and 800 belt-months: $2,600.
A periodic order quantity converts \(Q^{*}\) into a time supply, \(303.3/153.33 = 1.98\), rounds to two months, and orders in months 1, 3, 5, 7, 9, 11. Six orders, 960 belt-months: $2,760.
None is optimal. The best plan costs $2,480, and we are about to find it.
A plan is a vector of \(N\) non-negative numbers, so the search space is uncountable.
Two properties cut it down to something a computer, and sometimes a person, can enumerate.
There is always an optimal plan in which no order is placed in a period that begins with stock on hand.
Why: if an order arrived into a shelf that was not empty, the units already covered by existing stock could be moved into a later order without increasing cost.
So an optimal plan never orders into a non-empty shelf.
If every order arrives to an empty shelf, then an order placed in period \(t\) covers exactly periods \(t\) through \(u\) for some \(u\), and the next order starts at \(u+1\).
A plan is therefore nothing but a choice of order periods.
\(N\) periods, each either an order period or not. Finite. Enumerable.
If \(d_t > 0\) and the shelf is empty at the start of period \(t\), then period \(t\) must hold an order.
For the belt, month 5 forces one. That fact will matter next session when we truncate the horizon.
Let \(w(t,u)\) be the cost of a single replenishment placed in period \(t\) that covers requirements through period \(u\):
\[ w(t,u) = k + h\sum_{s=t}^{u} (s-t)\,d_s \]
The order cost, plus carrying on every unit for the number of periods it waits.
\[ w(1,3) = 300 + 1.00\left[0(40) + 1(60) + 2(120)\right] = 300 + 300 = \$600 \]
\(w(t,u)\) depends on the requirements and the cost parameters.
It depends on no decision.
So all the window costs can be computed once, before any search begins.
They are a fixed table, not something recomputed inside a search. That is what turns this into a shortest path over a network whose arc prices are known in advance.
First six months of the belt:
| \(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: a window covering one period carries nothing.
Read across row 1: increments of 60, 240, 900, 1,680, 1,300. They grow until month 6, whose requirement is smaller than month 5’s. The increment is \(h(u+1-t)d_{u+1}\), so it grows with distance and with requirement, and either can dominate.
Nodes are periods. An arc from \(t-1\) to \(u\), priced \(w(t,u)\), means “order in \(t\), covering through \(u\).”
flowchart LR
N0((0)) -->|"w(1,1)"| N1((1))
N0 -->|"w(1,2)"| N2((2))
N0 -->|"w(1,3)"| N3((3))
N1 -->|"w(2,2)"| N2
N1 -->|"w(2,3)"| N3
N2 -->|"w(3,3)"| N3
A path from 0 to \(N\) is a plan. The shortest path is the cheapest plan.
Let \(V(u)\) be the least cost of covering periods 1 through \(u\), and \(S(u)\) the period the last order of that plan falls in.
\[ V(u) = \min_{1 \le t \le u}\left\{V(t-1) + w(t,u)\right\}, \qquad V(0) = 0 \]
Fill one column at a time. Each column has one entry for each period that could hold the last order.
\(O(N^{2})\), and it fits on half a page.
\[ \begin{aligned} \text{order in 1:}&\quad w(1,4) = 1{,}500\\ \text{order in 2:}&\quad V(1) + w(2,4) = 300 + 1{,}020 = 1{,}320\\ \text{order in 3:}&\quad V(2) + w(3,4) = 360 + 600 = 960\\ \text{order in 4:}&\quad V(3) + w(4,4) = 600 + 300 = \mathbf{900} \end{aligned} \]
\[ V(4) = 900, \qquad S(4) = 4 \]
| \(u=1\) | 2 | 3 | 4 | 5 | 6 | |
|---|---|---|---|---|---|---|
| \(V(u)\) | 300 | 360 | 600 | 900 | 1,200 | 1,460 |
| \(S(u)\) | 1 | 1 | 1 | 4 | 5 | 5 |
The optimum is $1,460.
Now trace it back.
Start at \(u = 6\). \(S(6) = 5\), so the last order falls in period 5, covering periods 5 and 6: \(d[5,6] = 680\) belts.
Now \(u = 4\). \(S(4) = 4\), so the next order back falls in period 4, covering period 4 alone: 300 belts.
Now \(u = 3\). \(S(3) = 1\), so the first order falls in period 1, covering periods 1 through 3: 220 belts.
| \(t\) | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|
| \(Q_t\) | 220 | 0 | 0 | 300 | 680 | 0 |
| \(I_t\) | 180 | 120 | 0 | 0 | 260 | 0 |
Three orders cost $900. The ending balances total 560 belt-months, at $1.00 each: $560.
\[ 900 + 560 = \mathbf{\$1{,}460} \]
The traceback and the recursion are two readings of the same numbers.
If the ledger does not reproduce \(V(N)\), one of them was done wrong. Do this every time.
| \(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\) gives orders in months 12, 10, 6, 5, 4 and 1.
| \(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 |
Six orders ($1,800) and 680 belt-months ($680): $2,480.
\[ V(9) = V(8) = 1{,}700 \]
Month 9 has no requirement, so covering through month 9 costs exactly what covering through month 8 costs. The recursion is indifferent to where the next order falls.
And month 5 holds an order, as the forcing property promised.
Against the three naive plans: the optimum saves $820 on lot-for-lot and $120 on the adjusted economic order quantity.
That adjusted EOQ was within 4.84% of optimal.
There is a real question about how much the rest of this chapter buys.
The recursion is the right way to solve this. It is not the only way.
\[ \min \sum_t \left(k y_t + h I_t\right) \]
\[ \text{s.t.}\quad I_{t-1} + Q_t - d_t = I_t, \qquad Q_t \le M y_t, \qquad y_t \in \{0,1\} \]
A mixed integer program. Slower, but it accepts constraints the recursion cannot: a cap on order size, a shared capacity, a minimum buy.
Reach for it when the problem has grown a constraint, not when it has grown large.
The EOQ has nothing to stand on once the rate varies, because there is no repeating cycle to average over.
Zero-inventory ordering makes a plan a choice of order periods, which is what makes the problem finite.
Window costs depend on no decision, so they are computed once and the problem becomes a shortest path.
The recursion is \(O(N^2)\) and the traceback reads the plan back out.
$2,480 against $3,300 for lot-for-lot, and $2,600 for a rule with no theory in it at all.
Read before next session: Three Heuristics and One Shape, What a Heuristic Costs, and The Rolling Horizon.
Next session:
Today’s recursion needs \(d_1\) through \(d_N\) before it can return anything. Those are a forecast. Next session is about what that costs.