Multi-Echelon Systems: Serial Chains and Distribution Networks

Manuel D. Rossetti, PhD P.E.

Agenda

  • The third coupling: stock that exists to replenish other stock
  • Echelon stock and echelon holding cost, and why installation accounting double counts
  • A two stage chain costed both ways
  • Serial chains: nestedness, blocks, and the partition algorithm on five stages
  • Distribution networks: the pinned set, built for a warehouse and six regions
  • Why every location ended on one power-of-two interval

The Third Coupling

Items so far sat side by side: they competed for a budget or shared a truck, but none fed another. A multi-echelon system couples locations end to end: stock at one location exists to supply the next.

The decision is still a set of reorder intervals, and the tool is still the power-of-two policy. What changes is the accounting: a unit at a regional warehouse has already been paid for by the central warehouse that shipped it, so charging holding location by location double counts.

Number the stages so that stage \(i\) supplies stage \(i - 1\), with stage 1 facing the customer:

\[ n \longrightarrow n-1 \longrightarrow \cdots \longrightarrow 2 \longrightarrow 1 . \]

Every stage sees the same demand rate \(\lambda\), because a unit consumed at stage 1 passed through every stage above it.

Echelon Stock and the Value-Added Rate

The echelon stock of stage \(i\) is the total on hand at stages 1 through \(i\): everything at stage \(i\) and everything already moved downstream of it.

Stage 1 2 3
On hand 2 3 1
Echelon stock 2 5 6

Stage 3 owns six units in the sense that matters, although one sits there. Echelon stock falls at \(\lambda\) and jumps when the stage orders: the sawtooth the economic order quantity was built for. On-hand stock does not; it drops in steps whenever the stage below orders.

Let \(h_i\) represent the installation holding rate at stage \(i\) and \(h'_i\) the echelon holding rate, which charges only the value stage \(i\) adds:

\[ \begin{aligned} h'_i &= h_i - h_{i+1}, \qquad h'_n = h_n &&\text{the value added at stage } i\\ \sum_{j=i}^{n} h'_j &= (h_i - h_{i+1}) + (h_{i+1} - h_{i+2}) + \cdots + h_n = h_i &&\text{it telescopes: nothing lost, nothing counted twice} \end{aligned} \]

The Same System, Costed Twice

Two stages, \(T_1 = \tfrac{1}{2}T_2\), zero lead times, \(\lambda = 100\) a year, \(T_1 = 1/2\) and \(T_2 = 1\) year, so \(Q_1 = 50\), \(Q_2 = 100\). Rates: \(h_1 = \$2.00\), \(h_2 = \$1.20\), so \(h'_1 = \$0.80\) and \(h'_2 = \$1.20\).

Top: stage 1 on hand, an ordinary sawtooth.

Middle: stage 2 on hand is flat, since stage 2 faces no external demand. It holds 50 for the first half of the cycle and nothing for the second.

Bottom: stage 2 echelon stock, the sum of the two above. The red transfer at \(T_1\) drops the middle panel and lifts the top by the same amount, so the bottom passes through unbroken.

Following Each Stock

On hand. Stage 2 receives \(Q_2\), ships \(Q_1 = \tfrac{1}{2}Q_2\) at once, holds the rest for \(T_1\), then is empty. A rectangle averaged over \(T_2\):

\[ \begin{aligned} \bar{I}_1 &= \frac{Q_1}{2} = \frac{\lambda T_1}{2}, \qquad \bar{I}_2 = \frac{(Q_2 - Q_1)T_1}{T_2} = \frac{(\tfrac{1}{2}\lambda T_2)T_1}{T_2} = \frac{\lambda T_1}{2} &&\text{sawtooth, and rectangle}\\ h_1\bar{I}_1 + h_2\bar{I}_2 &= \tfrac{1}{2}(h_1 + h_2)\lambda T_1 &&\text{installation accounting} \end{aligned} \]

Echelon. Stage 2’s echelon stock is a clean sawtooth over \(T_2\), and stage 1’s is its on-hand stock:

\[ \begin{aligned} \bar{I}^{\,e}_2 &= \frac{Q_2}{2} = \frac{\lambda T_2}{2}, \qquad \bar{I}^{\,e}_1 = \bar{I}_1 = \frac{\lambda T_1}{2} &&\text{two sawtooths}\\ h'_1\bar{I}^{\,e}_1 + h'_2\bar{I}^{\,e}_2 &= \tfrac{1}{2}(h_1 - h_2)\lambda T_1 + \tfrac{1}{2}h_2\lambda(2T_1) &&h'_1 = h_1 - h_2, \; h'_2 = h_2, \; T_2 = 2T_1\\ &= \tfrac{1}{2}(h_1 + h_2)\lambda T_1 &&\text{the same total} \end{aligned} \]

Does It Reconcile?

Accounting Term Average Rate Cost rate
Installation stage 1 \(\bar{I}_1 = 25\) \(h_1 = 2.00\) $50.00
stage 2 \(\bar{I}_2 = 25\) \(h_2 = 1.20\) $30.00
total $80.00
Echelon stage 1 \(\bar{I}^{\,e}_1 = 25\) \(h'_1 = 0.80\) $20.00
stage 2 \(\bar{I}^{\,e}_2 = 50\) \(h'_2 = 1.20\) $60.00
total $80.00

The check: \(\tfrac{1}{2}(h_1 + h_2)\lambda T_1 = \tfrac{1}{2}(3.20)(100)(0.5) = \$80\) a year, both ways. You should perform that check every time echelon rates are introduced, because it catches a sign error in \(h'_i\) immediately.

Installation charges the stages $50 and $30; echelon charges them $20 and $60. Echelon accounting reassigns cost between stages and preserves the total. No money is invented or lost, and one awkward rectangle becomes a sawtooth, so every stage looks like an economic order quantity.

Serial Chains

Let \(k_i\) represent the order cost at stage \(i\), \(g_i = \tfrac{1}{2}\lambda h'_i\) the holding coefficient, and \(T_i\) the reorder interval. Stage \(i\) holding echelon stock on a cycle \(T_i\) costs \(g_iT_i\) a year:

\[ \begin{aligned} \min \; &\sum_{i=1}^{n}\left[\frac{k_i}{T_i} + g_iT_i\right] &&\text{each stage is an EOQ in } T_i\\ T_i &= 2^{\ell_i}T, \quad \ell_i = 0, 1, 2, \ldots &&\text{power of two}\\ T_i &\ge T_{i-1} \ge 0 &&\text{nestedness} \end{aligned} \]

Nestedness: whenever a stage orders, every stage below it orders too, so no stage replenishes more often than the one it supplies. It keeps work in process from piling up between stages, and with power-of-two intervals it comes free.

The relaxation drops the power-of-two restriction and keeps nesting. Without nesting each stage would take \(\sqrt{k_i/g_i}\), so the constraint binds exactly when those fail to increase up the chain. Then stages that would violate it are merged into a block and share one interval.

Blocks

Let \(G_r\) represent the \(r\)th block of consecutive stages, \(T(r)\) its shared interval, and \(k(G_r) = \sum_{i \in G_r} k_i\), \(g(G_r) = \sum_{i \in G_r} g_i\) its totals:

\[ \sum_{i \in G_r}\left[\frac{k_i}{T(r)} + g_iT(r)\right] = \frac{k(G_r)}{T(r)} + g(G_r)T(r) \quad\Longrightarrow\quad T(r) = \sqrt{\frac{k(G_r)}{g(G_r)}} . \]

A set of blocks solves the relaxation when:

  1. each block’s interval is given by that formula;
  2. the intervals increase, \(T(1) \le T(2) \le \cdots\), so the solution is feasible;
  3. no block can be split into a lower and an upper part whose ratios would let the upper part lengthen its interval on its own and save money.

The Partition Algorithm

partition(stages 1 to n):
    r <- 1;  G_1 <- {1}
    for i = 2 to n:
        if k(G_r)/g(G_r) <= k_i/g_i:
            r <- r + 1;  G_r <- {i}       // wants a longer interval: stands alone
        else:
            G_r <- G_r + {i}              // wants a shorter one: absorbed
            r <- merge(r)                 // absorbing lowered the ratio
    return G_1 through G_r

merge(r):
    s <- r
    while s > 1 and k(G_{s-1})/g(G_{s-1}) > k(G_s)/g(G_s):
        G_{s-1} <- G_{s-1} + G_s;  s <- s - 1     // fold down and retest
    return s

Walk up the chain, absorbing a stage when it wants a shorter interval than the current block, and starting a new block when it wants a longer one. Absorbing changes the block’s totals, which can push its ratio below the block beneath; merge walks back down repairing that.

A Five Stage Chain

A component passes \(5 \to 4 \to 3 \to 2 \to 1\) at \(\lambda = 500\) a year; the plant acts weekly, \(T = 1/52\) year.

Stage \(i\) 1 2 3 4 5
\(k_i\) $10 $12 $25 $7 $2
\(h_i\) $0.60 $0.50 $0.35 $0.10 $0.05
\(h'_i = h_i - h_{i+1}\) 0.10 0.15 0.25 0.05 0.05
\(g_i = \tfrac{1}{2}(500)h'_i\) 25 37.5 62.5 12.5 12.5
\(k_i/g_i\) 0.400 0.320 0.400 0.560 0.160
Alone, \(\sqrt{k_i/g_i}\) 0.632 0.566 0.632 0.748 0.400

Why the constraint binds. The intervals alone are not nondecreasing: stage 2 would order less often than stage 1, which it supplies, and stage 5 less often than anything below it.

Running the Algorithm

\(i\) Current block ratio \(k_i/g_i\) Action
2 \(10/25 = .400\) \(12/37.5 = .320\) \(.400 > .320\): absorb, \(G_1 = \{1,2\}\)
3 \(22/62.5 = .352\) \(25/62.5 = .400\) \(.352 \le .400\): start \(G_2 = \{3\}\)
4 \(25/62.5 = .400\) \(7/12.5 = .560\) \(.400 \le .560\): start \(G_3 = \{4\}\)
5 \(7/12.5 = .560\) \(2/12.5 = .160\) \(.560 > .160\): absorb, \(G_3 = \{4,5\}\), then merge
merge \(G_3\): \(9/25 = .360\) \(G_2\): \(.400\) \(.400 > .360\): fold, \(G_2 = \{3,4,5\}\)
merge \(G_2\): \(34/87.5 = .389\) \(G_1\): \(.352\) \(.352 \le .389\): stop

The partition is \(G_1 = \{1, 2\}\) and \(G_2 = \{3, 4, 5\}\). Notice the cascade: absorbing stage 5 lowered block 3’s ratio below block 2’s, and the merge folded them together.

The Relaxed Solution, and Rounding

\[ \begin{aligned} T(1) &= \sqrt{22/62.5} = 0.5933 \text{ yr} = 30.9 \text{ weeks} &&\text{block } \{1, 2\}\\ T(2) &= \sqrt{34/87.5} = 0.6234 \text{ yr} = 32.4 \text{ weeks} &&\text{block } \{3,4,5\}\text{: nondecreasing}\\ \text{cost} &= 2\sqrt{22(62.5)} + 2\sqrt{34(87.5)} = 74.16 + 109.09 = \$183.25 &&\text{each block is an EOQ: } 2\sqrt{kg}\\ \text{alone} &= \textstyle\sum_i 2\sqrt{k_ig_i} = \$181.81 &&\text{infeasible; nesting costs 0.8}\%\\ 2^{\ell} &\ge 30.9/\sqrt{2} = 21.8 \Rightarrow \ell^{*} = 5; \quad 2^{\ell} \ge 32.4/\sqrt{2} = 22.9 \Rightarrow \ell^{*} = 5 &&\text{both blocks: 32 weeks} \end{aligned} \]

Both blocks land on \(2^{5} = 32\) weeks, at $183.31, 0.03% above the relaxed solution.

The relaxation distinguished the blocks and the rounding put them back together: intervals within the same band of the doubling test round to the same power, and 30.9 and 32.4 weeks differ by 5%. The whole chain replenishes on one schedule.

Now Reverse the Geometry

A central warehouse, index 0, supplies regional warehouses \(1, \ldots, n\), and region \(i\) faces \(\lambda_i\), so the center sees \(\lambda_0 = \sum_i \lambda_i\). The center’s echelon stock is everything in the system:

\[ \begin{aligned} h'_0 &= h_0, \qquad h'_i = h_i - h_0 &&\text{each region charged what it adds}\\ g_i &= \tfrac{1}{2}\lambda_ih'_i &&\text{each location's own demand rate}\\ T_0 &\ge T_i \ge 0, \quad i = 1, \ldots, n &&\text{nesting runs the other way} \end{aligned} \]

Nothing downstream may wait longer than the center: a region ordering less often would leave stock sitting at the center with nowhere to go.

The relaxed answer splits the regions in two. Those whose \(\sqrt{k_i/g_i}\) is short enough keep it. Those that would want a longer interval than the center can offer are pinned to the center’s interval. Let \(\tilde{C}^{0}\) represent the pinned set: the center and the regions pinned to it.

Building the Pinned Set

Sort the regions by \(k_i/g_i\), so \((1)\) wants the shortest interval and \((n)\) the longest. Start from \(\tilde{C}^{0} = \{0\}\) and work down from \((n)\): add a region when its ratio exceeds the pooled ratio of the set, since alone it would want a longer interval than the center has; stop at the first that does not. The center’s interval is the pooled \(T_0 = \sqrt{\sum_{\tilde{C}^{0}}k_j \big/ \sum_{\tilde{C}^{0}}g_j}\).

Six regions at \(\lambda_i = 200\), \(\lambda_0 = 1{,}200\), \(T = 1/52\):

\(i\) 0 1 2 3 4 5 6
\(k_i\) $500 $100 $125 $110 $150 $75 $90
\(h_i\) $10 $15 $12 $20 $18 $20 $17
\(h'_i\) 10 5 2 10 8 10 7
\(g_i\) 6,000 500 200 1,000 800 1,000 700
\(k_i/g_i\) .0833 .200 .625 .110 .1875 .075 .1286

Sorted: regions 5, 3, 6, 4, 1, 2 become \((1)\) through \((6)\).

The Scan

Step Candidate Its \(k_i/g_i\) Pooled \(k(\tilde{C}^{0})/g(\tilde{C}^{0})\) Action
1 (6), was 2 .625 \(500/6{,}000 = .0833\) larger: add
2 (5), was 1 .200 \(625/6{,}200 = .1008\) larger: add
3 (4), was 4 .1875 \(725/6{,}700 = .1082\) larger: add
4 (3), was 6 .1286 \(875/7{,}500 = .1167\) larger: add
5 (2), was 3 .110 \(965/8{,}200 = .1177\) smaller: stop

\[ \begin{aligned} T_0 &= \sqrt{965/8{,}200} = 0.3430 \text{ yr} = 17.8 \text{ weeks} &&\text{center and four pinned regions}\\ T_{(2)} &= \sqrt{.110} = 0.3317 \text{ yr} = 17.2 \text{ weeks}, \quad T_{(1)} = \sqrt{.075} = 0.2739 \text{ yr} = 14.2 \text{ weeks} &&\text{left alone} \end{aligned} \]

Rounding, and Why Everything Synchronized

\[ \begin{aligned} \text{center}: 2^{\ell} &\ge 17.8/\sqrt{2} = 12.6 \;\Rightarrow\; \ell \ge 3.66 \;\Rightarrow\; \ell^{*} = 4 &&\text{16 weeks}\\ (2): 2^{\ell} &\ge 12.2, \qquad (1): 2^{\ell} \ge 10.1 &&\text{both } \ell^{*} = 4 \end{aligned} \]

Every location ends on a sixteen-week cycle. The choice \(\ell^{*} = 4\) covers every best interval from \(8\sqrt{2} = 11.3\) to \(16\sqrt{2} = 22.6\) weeks, and 14.2, 17.2 and 17.8 all sit inside that band.

As in the chain, the relaxation distinguished three intervals and the rounding put them back together. The construction of \(\tilde{C}^{0}\) was still what proved the schedule optimal rather than merely convenient.

What We Did Today

Echelon stock at a stage is everything at it and downstream; it is the sawtooth the economic order quantity models.

Echelon holding rates charge the value each stage adds, telescope back to the installation rate, and reassign cost without changing the total: $80 both ways.

A serial chain is a sum of EOQs in intervals under nesting; the partition algorithm merges stages into blocks, \(\{1,2\}\) and \(\{3,4,5\}\), at $183.25.

A distribution network pins to the center every region that would want a longer interval: four of six here, at 17.8 weeks.

Power-of-two rounding put every chain stage on 32 weeks and every network location on 16.

For Next Time

Read before next session: Building These Models in a Worksheet and Designing the Software.

Today’s material was Multi-Echelon Systems.

Next session:

  • The workbook: the constrained problem, the exchange curve, joint replenishment and the distribution scan, each laid out to say something about the model
  • Why there is no worksheet for the serial chain
  • The software: measures, constraints, interval rules and supply networks

Next session asks which of today’s algorithms a worksheet can hold, and the answer turns on whether the number of steps is known in advance.

⌂ Index