425. Clark-Scarf

The foundational result for stochastic multi-echelon inventory in serial systems (Clark & Scarf 1960). Shows that the multi-echelon problem decomposes into independent single-echelon problems — one per stage, each solved as a newsvendor-like base-stock problem with an induced penalty cost.

425.1. Setup: serial system

Stages numbered 1 (most upstream) to 𝑁 (most downstream = retailer). Customer demand 𝐷 hits stage 𝑁 only. Each stage:

Holding cost rates: 𝑖 at stage 𝑖 (assume 1<2<<𝑁 — inventory is more expensive downstream where it carries more added value).

425.2. Echelon stock

Define echelon stock at stage 𝑖:

𝐸𝑖=𝐼𝑖+𝑗=𝑖+1𝑁𝐼𝑗+in-transit to𝑗>𝑖

— what’s at stage 𝑖 plus everything below it. Holding cost on echelon stock is incremental:

𝑖𝐸=𝑖𝑖1

(with 0=0). This is the marginal holding cost as inventory moves from stage 𝑖1 to stage 𝑖.

425.3. Optimal policy: echelon base-stock

The optimal policy is echelon base-stock: at each review, stage 𝑖 orders to bring its echelon stock up to a target 𝑆𝑖.

The Clark-Scarf decomposition shows that 𝑆𝑖 at each stage solves a single-stage newsvendor problem with:

425.4. Induced penalty

The recursion (downstream → upstream):

𝑏̂𝑁=𝑏(retailer faces real backorder cost)𝑏̂𝑖1=𝐸[(𝐷𝐿𝑖shortage at stage𝑖)+]𝑏̂𝑖+𝑖𝐸...

Formally: each stage’s penalty depends on the optimal cost-to-go from downstream — a backward DP. The decomposition magic is that, despite this coupling, the form of each stage’s optimal policy is base-stock with parameters depending only on local data + the induced penalty.

425.5. Worked sketch (2-stage)

Stages: warehouse (1) → retailer (2). 𝐿1,𝐿2 lead times. 1,2=1𝐸+2𝐸. Backorder cost 𝑏 at retailer.

Retailer (stage 2): classical newsvendor with critical ratio 𝑏𝑏+2𝐸. Solve for 𝑆2.

Warehouse (stage 1): newsvendor with critical ratio 𝑏̂1𝑏̂1+1𝐸 where 𝑏̂1 is the expected cost the warehouse imposes on the retailer when warehouse stockouts cause retailer delays.

425.6. Penalty-function recursion

For this construction, index stages 1 = downstream (demand-facing) to 𝑛 = upstream (vendor) — the reverse of the setup above.

Consider a serial system with 𝑛 stages, where stage 1 faces stochastic customer demand and each is replenished from stage 𝑗+1 with deterministic lead time 𝐿𝑗:

Solve stages 12𝑛. Each stage 𝑗 does three things:

Base case (stage 1). No stage below it, so 𝐺0=0. Stage 1′s expected cost as a function of its echelon level 𝑦:

𝐶1(𝑦)=1𝔼[(𝑦𝐷𝐿1)+]+𝑝𝔼[(𝐷𝐿1𝑦)+]

where 𝐷𝐿1 is demand over the lead-time window. This is convex; its minimizer is the fractile:

𝑆1=𝐹𝐿11(𝑝𝑝+1)

Inductive step (stage 𝑗). Stage 𝑗 has received 𝐺𝑗1 from below. Its cost combines its own echelon holding with the penalty it inflicts downstream when it can’t fully supply:

𝐶𝑗(𝑦)=𝑗𝔼[(𝑦𝐷𝐿𝑗)+]+𝔼[𝐺𝑗1(𝑦𝐷𝐿𝑗)]

Minimize over 𝑦 to get 𝑆𝑗=argmin𝑦𝐶𝑗(𝑦).

Produce the penalty to pass up. The clamp-and-floor operation:

𝐺𝑗(𝑥)=𝐶𝑗(min(𝑥,𝑆𝑗))𝐶𝑗(𝑆𝑗)

Zero when 𝑥𝑆𝑗 (stage 𝑗 isn’t constrained), positive and rising as 𝑥 drops below 𝑆𝑗. Hand 𝐺𝑗 to stage 𝑗+1.

Example: 3-stage serial system

Stage 1. Window 𝐿1+1=2, fractile 2727+3=0.9, 𝑧=1.282:

𝑆1=10(2)+1.28222=20+2.6323.63

Stage 2. Window 𝐿2+1=2, fractile 2727+3+2=2732=0.844, 𝑧=1.011:

𝑆2=20+1.01122=20+2.8622.86

Stage 3. Window 𝐿3+1=3, fractile 2727+6=2733=0.818, 𝑧=0.908:

𝑆3=10(3)+0.90823=30+3.2533.15

The local stock held at each stage is the echelon-difference: 𝑆3𝑆2 at stage 3, 𝑆2𝑆1 at stage 2, 𝑆1 at stage 1.

The fractile formula 𝑝/(𝑝+𝑖<𝑗𝑖) with window 𝐿𝑗+1 is the exact stage-1 newsvendor and a standard approximation upstream. The exact Clark-Scarf 𝑆2,𝑆3 come from minimizing 𝐶𝑗(𝑦)=𝑗𝔼[(𝑦𝐷𝐿𝑗)+]+𝔼[𝐺𝑗1(𝑦𝐷𝐿𝑗)] numerically, since 𝐺𝑗1 isn’t a clean newsvendor cost.

# pip install stockpyl
from stockpyl.ssm_serial import optimize_base_stock_levels

# Nodes indexed 1=downstream(demand-facing) ... 3=upstream(vendor-facing)
S_star, C_star = optimize_base_stock_levels(
    num_nodes=3,
    echelon_holding_cost=[3, 2, 1],   # h_1, h_2, h_3
    stockout_cost=27,                 # p, charged at downstream node
    lead_time=[1, 1, 2],              # L_1, L_2, L_3 (into each stage)
    demand_mean=10,
    demand_standard_deviation=2,
)
print(S_star)   # exact echelon base-stock levels
print(C_star)   # optimal expected cost

425.7. Why echelon stocks decouple the problem

If stage 𝑖’s order pulls from infinite supply (or upstream is always available), each stage is independent. Real life: upstream isn’t always available. The induced penalty charges upstream for the downstream cost of its stockouts — capturing the coupling exactly.

425.8. Limitations

For general networks, see Graves-Willems guaranteed-service.

425.9. See also