MEIO Collaborative Zones — 2-Pass Optimisation¶
Who this guide is for
This guide is for supply chain planners who want to group stocking locations that can cover the same demand (rescue each other) into a collaborative zone, so MEIO sizes one shared inventory envelope for the group instead of optimising every location in isolation. It assumes familiarity with the base MEIO workflow.
Status: Implemented (inline execution). Source:
files/meio_zone_pass.py, wired intofiles/meio_runner.py::run_scenarios.
The idea — risk pooling¶
When several warehouses can serve the same customers, each one does not need to carry the full safety stock for its own demand slice — the group can share a single, smaller buffer. This is risk pooling: the variance of pooled demand is lower than the sum of individual variances (demand peaks at one location are offset by troughs at another).
Collaborative zones implement this as a 2-pass optimisation:
flowchart LR
subgraph Pass1["Pass 1 — zone envelope"]
M["Member locations<br/>(demand, σ, LT, cost)"] --> AGG["Aggregate into one<br/>virtual zone SKU per item"]
AGG --> OPT1["MEIO optimizer sizes<br/>the zone buffer (ROP)"]
end
subgraph Pass2["Pass 2 — physical locations"]
OPT1 --> CAP["Zone budget cap =<br/>pass-1 ROP × zone unit cost"]
CAP --> OPT2["Standard MEIO on all<br/>physical SKUs, zone members<br/>capped by the zone envelope"]
end
- Pass 1 aggregates each zone's member locations into one virtual zone SKU per item and runs the unchanged MEIO optimizer on it. The result is the group's inventory envelope — how much stock the zone should hold in total for that item to reach the zone's service-level target.
- Pass 2 runs the standard MEIO at physical-location level, with each zone's envelope enforced as a group budget cap on the member SKUs. The greedy optimizer still decides where in the zone to hold the stock (cheapest, fastest-responding locations get more), but the total investment across the zone cannot exceed the pooled envelope.
The savings show up as pooling benefit: the difference between the sum of each member's standalone safety stock and the zone's pooled safety stock.
Enabling the zone pass¶
Open a MEIO scenario → Advanced panel. The distribution and optimisation toggles live in bordered cards, each with its own description:
| Toggle | What it does |
|---|---|
| Empirical distributions | Builds demand-over-lead-time distributions by Monte Carlo bootstrap resampling of historical demand — captures real skewness, intermittency, and spikes that parametric approximations miss. When OFF, falls back to fitted normal/gamma distributions from the forecast pipeline. Reveals the Bootstrap samples, MC iterations, and MC seed fields when ON. |
| LT-distribution convolution | Performs full Monte Carlo convolution of the demand distribution × the supply lead-time distribution, capturing the stochastic interaction between demand variability and lead-time variability (a long lead time means more demand accumulates). Lead-time distributions are sourced from purchase-receipt actual lead times, then PIPE_lead_time_actuals, then a lognormal synthesized from route planned LT + CV. When OFF, lead time is a deterministic scalar with an additive lt_stddev variance term — this underestimates stockout risk when lead times are highly variable. |
| Collaborative zone pass | Enables the 2-pass zone aggregation described above. When ON, the Collaborative Zones panel (below the Advanced panel) becomes active and the zone definitions are executed inline during the MEIO run. When OFF, every location is optimised independently and the run is byte-identical to baseline MEIO. |
Bootstrap samples / MC iterations / MC seed
- Bootstrap samples (default 1000): number of resampled demand paths used to build the empirical demand-over-LT distribution. Higher values (e.g. 5000) give smoother distribution tails at the cost of runtime.
- MC iterations (default 1000): number of Monte Carlo draws for the demand × lead-time convolution. Higher values produce more accurate tail quantiles — critical for 99 % service levels.
- MC seed (default 0 = random): fix a positive integer (e.g. 42) to make runs perfectly reproducible for A/B comparison or debugging.
Defining zones¶
With the toggle ON, open the Collaborative Zones panel and click + Add Zone. Each zone has:
| Field | Meaning |
|---|---|
| Zone Name / Zone ID | Display name and a short code. The code becomes part of the internal group name (__zone__:{zone_id}:{item_id}). |
| Fill Rate Target | The service level the pooled zone inventory must achieve for the item (e.g. 0.95). Pass 1 sizes the envelope to this target. |
| Max Budget ($) | Optional hard dollar cap on the zone envelope. The effective cap is min(pass-1 SL-derived cap, max_budget). Leave blank for uncapped. |
| Lead Time Override | Optional. When blank, the zone lead time is the demand-weighted average of member lead times. |
| Unit Cost Override | Optional. When blank, the zone unit cost is the demand-weighted average of member costs (used to convert the envelope to a dollar cap). |
| Members | At least 2 (item, location) rows per zone. |
The participation column¶
Participation is the fraction of a member location's demand and variability that counts toward the zone aggregate:
total_demand_rate = Σ (member demand × participation)dmd_stddev = sqrt(Σ (member σ × participation)²)
The default 1.0 pools 100 % of that location's demand. Use a lower value
(e.g. 0.5) when a warehouse only partially serves the zone's shared
demand pool — for example when it also fulfils local demand that should not
be pooled.
Membership rules
- A physical
(item, location)pair may sit in at most one zone per scenario — saving an overlapping definition raises a validation error. - The same location may appear in several zones for different items.
- A zone needs ≥ 2 members present in the data, otherwise it is skipped and its members run unconstrained.
Zones auto-save (debounced) as you edit; a green "Saved" indicator confirms persistence. A read-only convex-hull mini-map shows the geographic spread of the member locations when coordinates are available.
Reviewing results — both passes¶
After a MEIO run, expand a zone to see the Run results (both passes) section. Each item in the zone gets its own card:
Pass 1 — virtual zone SKU¶
| Metric | Meaning |
|---|---|
| ROP | Reorder point the optimizer computed for the aggregated virtual zone SKU |
| Safety stock | max(0, ROP − cycle-stock baseline) — the pooled buffer |
| Fill rate (tgt) | Achieved fill rate on the virtual SKU vs the zone target |
| Cap | The budget cap injected into pass 2 = pass-1 ROP × zone unit cost |
| Demand rate / σ | The aggregated demand rate and independent-variance standard deviation |
| Lead time / Unit cost / On-hand | The aggregated inputs used for sizing |
| Pooling | Risk-pooling gain: Σ member-standalone SS − zone SS (in units and $) |
| Status | ok, skipped, or capped_below_baseline (see guardrails below) |
Pass 2 — member results¶
One row per member location: the physical ROP, Safety Stock, Fill Rate, and SS Value the optimizer assigned within the zone cap, plus a frozen badge when a member stopped receiving buffer because the zone budget was exhausted while that member was still below the zone service level.
The zone summary table (collapsed view) additionally shows per item: pass-1 cap, Σ pass-2 member ROP, cap utilisation %, pooling $, frozen member count, and status.
Guardrails¶
| Guardrail | Behaviour |
|---|---|
| capped_below_baseline | If the pass-1 cap falls below the members' combined cycle-stock baseline value, the cap is auto-loosened to baseline + ε — otherwise the zone could never be satisfied. Flagged in the status column. |
| Zero-cost zone | A zone whose aggregated unit cost is 0 is skipped entirely — a $0 cap would freeze all members immediately. |
| Skipped zones | Zones with < 2 present members, zero aggregated demand, or no pass-1 result are marked skipped; members run unconstrained. |
| Frozen members | When the zone budget is exhausted, all its members are frozen — they cannot receive more buffer through any other group. Members below the zone SL at that point are flagged in the member table. |
| Validation | Overlapping (item, location) membership across zones, missing/invalid fill-rate targets, or fewer than 2 members abort the run with a descriptive error so the configuration is fixed rather than silently ignored. |
Notes and limitations¶
- Independent-variance MVP: demand streams are pooled as
sqrt(Σ σᵢ²)— no covariance modelling. This is the theoretically correct pooling for independent demand; correlated demand (shared promotions, weather) reduces the real pooling benefit. - One run, both passes: pass 1 executes inline inside the MEIO run of the
scenario — no separate zone scenario or pipeline configuration is required.
Results are written to
PIPE_meio_zone_resultstagged with the scenario being run. - Parameter sets still apply: segment-level MEIO parameter sets (fill-rate targets, budgets, per-SKU caps) govern the physical SKUs in pass 2 as usual. The zone cap is an additional group constraint on top of the segment groups.
- Zones are scenario-scoped: each scenario carries its own zone definitions, so you can A/B test different pooling strategies by cloning a scenario and editing its zones.
Key files¶
| File | Role |
|---|---|
files/meio_zone_pass.py |
Zone definition parsing, virtual-SKU aggregation, pass-1 runner, cap injection, result persistence |
files/meio_runner.py |
Inline zone-pass wiring in run_scenarios (per-scenario, gated on enable_zone_pass) |
files/api/main.py |
GET /api/meio/scenarios/{id}/zones — definitions + pass-1/pass-2 results + per-member detail |
files/frontend/src/components/MeioScenarios.jsx |
Advanced-panel toggle + Collaborative Zones panel (editor, pass-1 card, pass-2 member table) |
files/DDL/ch_schema.sql |
PIPE_meio_zone_results table definition |