The storeroom’s policy needs the hub’s, through the wait. The hub’s needs the storeroom’s, through the orders it passes up. Neither can be computed first.
Each location minimizes chapter 8’s cost, \(C_i(r_i, Q_i) = k_i\lambda_i/Q_i + h\,\bar{I}_i + b_i\,\bar{B}_i\). The hub has no shortage cost of its own, yet the formula needs one. A service target and a penalty are the same thing seen from two sides, so set \(b_0\) from a ready rate target \(\gamma_0\):
\[ \begin{aligned} \frac{b_0}{b_0 + h} &= \gamma_0 &&\text{critical ratio, read backward}\\ b_0 &= \frac{\gamma_0\,h}{1 - \gamma_0} = \frac{0.8\,h}{0.2} = 4h = \$2.2115 \text{ per unit-week} &&\gamma_0 = 0.8 \end{aligned} \]
What the target is and is not
A device for pricing \(b_0\): the ready rate a base-stock hub facing single-unit Poisson demand would run at. Not a service level the hub is held to, and not a fill rate: storeroom orders of \(Q_j\) units are filled at a lower rate than the ready rate.
twoLevel(start):
// Step 0, the guess: the hub never delays
E[W] <- 0, Var[W] <- 0
loop:
// Step 1, the storeroom against the wait
storeroom lead time demand: mean
lambda_j (O_j + E[W]), variance
+ lambda_j^2 Var[W], or conditioned
(r_j, Q_j) <- optimize, chapter 8
// Step 2, the hub against the orders
hub lead time demand: the recipe,
or the exact convolution
(r_0, Q_0) <- optimize, chapter 8, b_0
// Step 3, the wait the hub implies
E[W] <- Bbar_0 / lambda_0, Var[W] ...
or the order's wait by the shift
// Step 4, stop when the integers repeat
Read step 0. It is the only guess. A wait of zero is what a planner assumes modeling a location alone, so pass 1 is the uncoupled planner’s answer and every later pass is a correction.
Read step 4. It is weaker than it looks. The integers stopped moving; no optimality condition holds. It finds a fixed point of a heuristic: each policy optimal given the other. A fixed point of a biased map is a biased answer that has stopped moving.
The moment route uses the recipe and two moments, for any customers. The exact route uses the convolution, the order’s wait and conditioning, for one-unit customers.
The system of last session, both batches now chosen; \(k = \$82.50\) an order at both locations, \(\gamma_0 = 0.8\). By the moment route:
| Pass | Storeroom \((r_j, Q_j)\) | Storeroom cost | Hub \((r_0, Q_0)\) | Hub cost | \(E[W]\), weeks | \(\sigma_W\) |
|---|---|---|---|---|---|---|
| 1 | \((-1, 26)\) | $13.09 | \((2, 47)\) | $20.99 | 0.5634 | 1.5988 |
| 2 | \((0, 29)\) | $14.35 | \((2, 48)\) | $21.71 | 0.6166 | 1.8033 |
| 3 | \((0, 29)\) | $14.65 | \((2, 48)\) | $21.71 | 0.6166 | 1.8033 |
Pass 1 ignores the hub: a reorder point of \(-1\) against a week’s transit. The hub’s answer implies a wait of 0.56 weeks, and pass 2 raises the storeroom’s reorder point by one and its batch by three. Pass 3 confirms.
The storeroom’s policy is the same in passes 2 and 3, yet its cost differs. Why?
Each pass prices the storeroom against the wait the pass before it left: pass 2 against a mean wait of 0.56 weeks, pass 3 against 0.62.
The exact route reaches hub \((2, 48)\) and storeroom \((3, 28)\), also in three passes. Its storeroom holds three more units: its orders of 28 wait for their last unit, 1.75 weeks on average, where the moment route carries the per-unit wait of 0.62.
| Route | Hub | Storeroom | Wait it carries | Priced exactly |
|---|---|---|---|---|
| Moments | \((2, 48)\) | \((0, 29)\) | 0.62 weeks, a customer’s | $34.35 a week |
| Exact | \((2, 48)\) | \((3, 28)\) | 1.75 weeks, an order’s | $33.54 a week |
Notice where the difference comes from. The hub is the same; the storeroom differs because an order waits differently from a unit, which is last session’s result arriving in a policy.
In Axsäter’s setting there is an exact cost, and with one-unit customers the chapter’s route gives one everywhere. So the iteration need not be trusted; it can be checked.
| Setting | Fixed point | Exact optimum | Gap |
|---|---|---|---|
| Part I, \(Q_0 = 8\), one-for-one storerooms | \((r_0, S_j) = (11, 3)\), $7.4337 | \((9, 3)\), $7.0195 | 5.9% |
| One batching storeroom, \(Q_j = 3\) | hub at one batch, \(r_j = 3\), $3.5354 | hub nearly empty, $3.4111 | 3.6% |
| Part II, both batches chosen | exact route | hub \((2, 43)\), storeroom \((4, 26)\), $33.3955 | 0.4% |
| moment route | 2.9% |
Read the gaps in domain terms. In every case the fixed point holds more at the hub than the optimum does. The optima run the hub at a low ready rate, 0.60 in Part I: a unit at the hub protects every storeroom a little, and a unit at a storeroom protects its own crews a lot.
A hub target of 0.8 already asks for more protection than the system wants. The target is the input to choose with care; the route matters less. Repeat this comparison on your own items whenever an exact cost is available.
Lots of 1, 2 or 4 with probabilities 0.40, 0.40, 0.20: \(E[Y] = 2.0\), \(E[Y^{2}] = 5.2\). The storeroom sees 150 lots a year, the hub 250 of its own. Hub lead time two months, transfer one month; \(k = \$82.50\), \(h = \$28.75\), \(b = \$287.50\), \(\gamma_0 = 0.8\) so \(b_0 = \$115\) a year. Nothing exact reaches this.
A lot is at most 4 and the storeroom’s batch will be near 50, so every storeroom order is exactly \(Q_j\): undershoot never changes an order’s size. At the hub, by the recipe with compound Poisson customers,
\[ \begin{aligned} E[D_0] &= 800 \times \tfrac{2}{12} = 133.33 \text{ units} &&400 \text{ lots} \times 2 \text{ units, over two months}\\ \mathit{Var}[D_0] &= (250 + 150)\left(\tfrac{2}{12}\right)(5.2) + \frac{Q_j^{2}}{6} &&\text{compound Poisson, plus the batch term}\\ &= 346.67 + \frac{49^{2}}{6} = 346.67 + 400.17 = 746.83 &&\text{at } Q_j = 49 \end{aligned} \]
| Pass | Storeroom \((r_j, Q_j)\) | Hub \((r_0, Q_0)\) |
|---|---|---|
| 1 | \((22, 48)\) | \((120, 92)\) |
| 2 | \((25, 49)\) | \((120, 92)\) |
| 3 | \((25, 49)\) | \((120, 92)\) |
The storeroom costs $1,371.26 a year and the hub $2,279.69; the hub’s orders wait 0.0054 years, about two days.
The coupling moves the storeroom’s reorder point by three units. The hub does not move at all: the storeroom’s batch barely changes, and the hub’s lead time demand barely changes with it.
Notice what drives the hub’s variance. The storeroom’s batch contributes 400 of the 747, more than all the customers together. A hub serving a storeroom that orders fifty at a time faces a demand its customers never place.
Validation, and its limit
Nothing exact covers this case, and the chapter has said which assumption breaks: customers who take one unit each. What remains is to check the answer by simulation, which the next chapter builds.
Chapter10Models.xlsx follows the three parts; no macros.
Hub reads the measures out of its loss block by position:
B22: =(INDEX(HubLossTwo,B18+1)
-INDEX(HubLossTwo,B18+B19+1))/B19
Delay: a row a day, each the ready rate with a lead time that many days shorter. Exact runs the recursion down a grid.
Storeroom sets the three routes side by side. Notice the four figures: 0.0505, 0.0712, 0.0728 on the day grid, and 0.0726 exact.
Orders: each \(P(N \ge n)\) as an average of \(Q_j\) consecutive tail entries. HubGeneral convolves and prices the exact, the recipe and the shortcut: 13.3333, 13.5, 24, choosing 13, 13, 15.
Iterate is the iteration by hand. A sheet cannot run chapter 8’s search, so you type each pass’s policies; the sheet prices each and its four neighbors and hands the wait on.
Notice the last column, “no” on every pass: no neighbor of a typed policy is cheaper. Passes 2 and 3 agree: the stopping test, read off a sheet.
A price break for ordering twelve at a time instead of eight. Before weighing the price: what does the larger batch do? Type 12 into Hub!B19.
| Cell | What it is | \(Q_0 = 8\) | \(Q_0 = 12\) |
|---|---|---|---|
Hub!B22 |
\(\bar{B}_0\) | 1.0273 | 0.6984 |
Hub!B23 |
\(\overline{\mathit{RR}}_0\) | 0.6030 | 0.7242 |
Hub!B27 |
\(\bar{W}\), weeks | 0.2568 | 0.1746 |
Storeroom!E19 |
backorders per storeroom | 0.0726 | 0.0567 |
Exact!B28 |
system cost per week | $7.0195 | $7.7367 |
The hub holds more, crews wait less, and the system costs $0.72 a week more. Is that the price of the larger batch?
No: the reorder point must move with it. Holding more at the hub is more protection than the system wants, so lower Hub!B18: at 7, Exact!B28 reads $7.5379, the cheapest for a batch of twelve, $0.52 a week more.
\[ \begin{aligned} \$0.52 \text{ a week} \times 52 \text{ weeks} &= \$27 \text{ a year} &&\text{the larger batch's best version}\\ 4 \text{ a week} \times 52 &= 208 \text{ cutouts a year} &&\text{what the hub buys}\\ \$27 / 208 &= \$0.13 \text{ per cutout} &&\text{the discount that breaks even} \end{aligned} \]
Without an ordering cost the larger batch cannot pay for itself; it only adds stock. Thus the price break is worth taking if it saves more than $27 a year: a thirteen-cent discount would do it.
A planner who changed the batch and left the reorder point would have priced the offer at $0.72 a week instead of $0.52. The answer came from two cells typed, and the reorder point had to move with the batch.
The package inventory.multiechelon, extending chapter 9’s. It must evaluate exactly where Axsäter applies, build a hub’s lead time demand exactly and by the recipe, give the wait as a distribution for a customer and for an order, turn a wait into a storeroom’s lead time demand three ways, and run the iteration by either route and price its answer.
| Class | Does |
|---|---|
OneForOneTwoLevel |
Axsäter’s recursion; stock levels by linearity |
AxsaterBatchOrdering |
his equations (1), (2) and (6), and his approximations |
OrderCountLaw |
the order count, at a random moment and from an order |
BatchedHub |
convolution, recipe, shortcut, lead-time mixture, hub measures |
HubDelay |
the wait for a customer or an order, its moments, a grid |
StoreroomWithDelay |
the three routes |
TwoLevelIteration |
the iteration, and the exact price of any policy |
No class is a “storeroom”. A storeroom is a demand stream as the hub sees it, StoreStream, and a lead time demand as it sees itself, StoreroomWithDelay; what it is to itself is chapter 8’s RQModel.
ready rate 0.6030, backorders 1.0273, Little 0.2568 weeks
P(W <= 0) = 0.6030
P(W <= 1) = 0.9117
P(W <= 2) = 0.9985
E[W] 0.2568, Var[W] 0.1825
moments route, 3 passes:
1 hub (2, 47), storeroom (-1, 26) E[W] 0.5634
2 hub (2, 48), storeroom (0, 29) E[W] 0.6166
3 hub (2, 48), storeroom (0, 29) E[W] 0.6166
priced exactly: 34.3462 a week
exact route, 3 passes:
1 hub (2, 48), storeroom (-1, 26) E[W] 1.6250
2 hub (2, 48), storeroom (3, 28) E[W] 1.7500
3 hub (2, 48), storeroom (3, 28) E[W] 1.7500
priced exactly: 33.5370 a week
Notice the wait in the two traces: the moment route carries a customer’s, 0.62 weeks; the exact route an order’s of 28, 1.75 weeks.
A batching location passes up its demand counted in whole batches, lumpier and more regular than its customers’.
Condition on the position, then average, gave the hub’s measures, the wait’s distribution, Axsäter’s equation (1), the order count, and the order’s wait.
Where Axsäter applies, the chapter’s route agrees with him exactly, and it reaches past him to other demand, unlike storerooms and random lead times.
The Poisson-orders shortcut over-stocks; the mean wait alone understates storeroom backorders by about 30%.
The iteration finds a fixed point of a heuristic. Priced exactly it is within a few percent, and the hub’s target is the input to choose with care.
Read before next session: the opening of Simulating Inventory Systems, When the Formulas Stop and The Inventory Processes as Events.
Today’s material was Setting Both Policies through Designing the Software.
Next session:
The job-lot cutout had no exact check. The next chapter builds one.