A decision intelligence engine for supply chain allocation
Reallocating 300 SKUs across 3 capacity-constrained warehouses using Monte Carlo demand simulation and a PuLP linear program at the P95 service level.
Most inventory decisions in mid-market e-commerce are still made on averages. A planner looks at last quarter's sales, divides by the number of warehouses, adds a buffer, and calls it a day. That works fine until demand does what demand actually does. It spikes in one region, collapses in another, and behaves nothing like the mean.
I wanted to see what happens if you stop pretending demand is a single number and start treating it as a distribution. So I built a decision-intelligence engine around a fairly straightforward premise: simulate what demand could look like next week for every SKU in every region, then let an optimizer figure out where to put the units, subject to the fact that warehouses have finite space and stockouts have real dollar costs.
This is a case study, not a live system. But the entire pipeline is reproducible end-to-end, and the tradeoffs it surfaces (which SKUs are constrained, which regions are structurally volatile, which categories eat penalty costs) are exactly the kind of thing a supply-chain team would want a Monday-morning dashboard to tell them.
The optimized plan cut modeled weekly cost from $142K to $65K.
This section is intentionally visually distinct. It's not marketing. It's the part I'd want to read if I were hiring me.
I initially wrote the LP without warehouse capacity constraints. It happily produced a "solution" that allocated 110%+ of physical capacity to two of the three warehouses. Beautiful cost number, physically impossible plan. Adding the capacity constraint is what turned it from a math exercise into a real decision tool.
After the capacity constraint went in, the LP told me, correctly, that under current warehouse space, 44 SKUs cannot hit their P95 service target. That's not a bug; that's the actual answer. Those 44 SKUs are the business case for either a 4th warehouse, a 3PL contract, or a hard conversation with procurement.
My first pass at "how much should we stock?" used mean demand plus a flat safety-stock percentage. The Monte Carlo output made it obvious that for volatile SKUs, mean + buffer systematically under-stocks and the penalty cost eats the savings. Switching to P95-based targets was the single biggest unlock in the whole project.
No single SKU in East looked scary on its own. It only became clear that East was ~30% more volatile than the other regions once I aggregated up. If I'd trusted the per-SKU view, I would have missed the biggest regional signal in the dataset.
I expected a nice long-tailed volatility distribution. What I got was two clumps: a "boring, predictable" cluster and a "chaotic" cluster, with almost nothing in between. That changed the framing from "tune one policy" to "run two policies."
No orchestration, no scheduler, no live data feed, no UI. Someone taking this into production would need to wire it to actual ERP data, add rolling re-runs, and probably swap PuLP for a commercial solver at scale.
Divide expected weekly demand across the three warehouses roughly in proportion to historical share. No uncertainty modeling. This is the "planner in a spreadsheet" baseline.
Same as baseline but add a fixed % buffer on top of mean demand per SKU. Reduces stockouts on average but over-stocks the stable SKUs and still under-stocks the volatile ones. Improved but structurally flawed for the bimodal volatility profile.
Replace point estimates with simulated distributions. Target the 95th percentile of demand per SKU per warehouse. Let PuLP optimize allocation subject to real warehouse capacity.
The Final plan lands at a 54% reduction vs. baseline. That progression matters more than the final number.
The bimodal CV structure meant no single family (Normal, Log-Normal, Gamma) fit all 300 SKUs cleanly. Monte Carlo on the empirical distribution is more honest and doesn't force a distributional assumption I couldn't defend.
P99 is achievable for most SKUs but pushes total inventory past warehouse capacity and drives holding cost past the savings threshold. P95 is where the marginal dollar of holding cost stops beating the marginal dollar of expected penalty cost. I confirmed this by running the LP at P90, P95, and P99 and comparing objective values.
PuLP is free, readable, deterministic, and the problem is linear with a few hundred variables. It doesn't need a commercial solver. If this went to production over thousands of SKUs and rolling weekly runs, I'd re-evaluate Gurobi.
The problem is fundamentally an allocation problem under known constraints, not a control problem. LP gives an exact, explainable solution. A recruiter or planner can read the constraint report and understand why SKU 217 didn't get its full P95 allocation. An RL policy or an LSTM forecast can't offer that.
Classical EOQ assumes stable demand and doesn't handle multi-warehouse allocation jointly. It's a per-SKU-per-location heuristic. It cannot answer "given a shared capacity constraint across three warehouses, how do I split units globally?" which is the actual business question.
Lead time variability, in-transit inventory, cross-warehouse transfer costs, and supplier-side MOQs. Each is a legitimate extension; leaving them out kept the case study focused on the allocation-under-uncertainty core.
For the planning team, this pipeline replaces the Monday-morning "gut call" with a defensible, quantified allocation plan. Instead of "put more in East because it felt tight last week," the output is: East gets X units of SKU 217 because at P95 demand is Y, capacity headroom is Z, and the marginal penalty cost dominates the marginal holding cost.
For finance, the modeled savings, ~$76.6K/week ≈ ~$4M/year on a 300-SKU, 3-warehouse footprint, are directly attributable to reallocating existing inventory, not to buying more. That's a working-capital story, not a capex story.
For operations, the 44 constrained SKUs are the single most useful output in the whole project. They convert "we should think about more warehouse space" into a specific, ranked list of SKUs with dollar-value justification per line.
For the executive layer, the regional volatility finding (East ~30% more volatile) reframes East from "our best-performing warehouse" to "our highest-variance warehouse," which changes how you staff it, how much buffer capacity it needs, and whether you want a 3PL fallback there.
All charts are generated in-notebook and reproducible from the repo.
Establishes the mix and shows East pulling disproportionate share. The "know your data" chart.
The bimodal shape that killed the single-policy idea. Two clusters, not a smooth tail.
Makes the ~30% East-volatility premium visible in a single bar. The finding that only exists at the aggregated level.
Electronics towering over the rest at ~$83K/week. This is the chart you show finance.
Side-by-side histograms of the 10,000-iteration simulations with P50 / P95 / P99 marked. Shows why point estimates are a lie for the volatile cluster.
$142K to $65K, the headline result. One chart, one number, one story.
The "110% utilization" failure and the fixed version side by side. The Reality Check, visualized.
Turns "we need more space" into a procurement to-do list. The most operationally useful chart in the deck.
Supply-Chain-DI/ ├── notebooks/ │ ├── 01_basic_eda.ipynb │ ├── 02_demand_volatility.ipynb │ ├── 03_regional_volatility.ipynb │ ├── 04_financial_eda.ipynb │ ├── 05_monte_carlo.ipynb │ └── 06_optimization.ipynb ├── data/ # 300 SKUs × 3 warehouses × 2 years weekly (~93,600 rows) ├── outputs/ # charts, allocation plans, constrained-SKU report ├── Supply_Chain_DI_Documentation.pdf └── README.md
Synthetic-but-realistic weekly demand dataset generated to reflect mid-market e-commerce operating conditions: 300 SKUs across Electronics, Apparel, Home, and adjacent categories; 3 warehouses (East / Central / West) serving 3 regions; 2 years of weekly observations; per-unit holding cost, stockout penalty, and per-warehouse capacity attached to each record.
On the same network, with the same warehouse limits and the same demand patterns, the difference was not more inventory. It was better allocation logic. Weekly cost dropped from $142K to $65K in the modeled scenario, a 54% reduction worth roughly $4M annualized. The 44 SKUs the LP can't fully serve aren't a failure. They're the procurement roadmap that was hiding in the data.