← back to workProblemForecasting and warehouse-planning work needed to move from separate analyses into a usable system, while route decisions had to reflect current WMS orders and the active warehouse layout.
ContributionI led the six-person team and played a central role in both the software system and the optimization models. I built the forecasting pipeline, Flask API, PostgreSQL layer, and Next.js dashboard, while also contributing substantially to the design and implementation of the three Pyomo MILP models.
ResultDelivered a working pilot to Unilever covering demand forecasting, replenishment planning, ABC slotting, and picking-route optimization.
SystemA Flask-based system with LightGBM and XGBoost forecasting, three Pyomo/HiGHS optimization models, PostgreSQL, a Next.js dashboard, and WMS integration.
Main challengeProducing reliable forecasts for sparse, volatile, and promotion-driven e-commerce demand while integrating replenishment, slotting, and live order-based route planning into one usable system.
Overview
This was a six-person METU graduation project developed with Unilever as the industry partner. I led the team, took primary responsibility for the software system, and contributed substantially to the design and implementation of the optimization models.
The pilot connects forecast distributions and warehouse state to planning outputs, while current WMS orders and the active layout drive route generation. Forecasting, optimization jobs, persistence, and dashboards were delivered as one system.
Forecasting engine
The forecasting pipeline handles sparse and volatile e-commerce demand using LightGBM and XGBoost models with quantile outputs. Product-level forecasts are reconciled across aggregation levels before downstream planning.
Replenishment
Replenishment planning converts forecast distributions, inventory state, lead times, and service targets into order recommendations using (R, s, S) logic and Pyomo/HiGHS where optimization is required.
Slotting
ABC slotting assigns products to warehouse locations based on forecast demand and operational constraints.
Route optimization
Route optimization uses current WMS orders, picker capacity, and the active warehouse layout. Forecast outputs do not determine the live picking workload.
Deployment
Flask jobs and APIs run on Google Compute Engine, PostgreSQL is hosted on Cloud SQL for PostgreSQL, and the Next.js dashboard reads persisted forecasts and optimization results.
Key decisions & why
01Quantiles reconciled across model levels
SKU models retain item detail while category and subcategory models stabilize trend. Capped reconciliation combines them, and ABC-class quantile selection turns forecast uncertainty into an explicit planning input. Validation metrics choose LightGBM or XGBoost per SKU.
02Closed form first, MILP where it earns it
The analytic (R,s,S) policy sets inventory targets. The replenishment MILP handles only coupled decisions that require a solver: integer cases, shared capacity, and reorder-trigger constraints.
03ABC layout is an input to picking
Slotting is not an isolated report. Its persisted SKU locations define travel costs for route planning, so a demand-driven placement decision changes the routes built from real orders.
04Priority is solved into route numbering
Route 001 is consumed first on the floor. Route-index weights and contiguity constraints make urgency order part of the MILP result instead of a separate sorting step that could disagree with the solve.
05Current WMS orders define picking plans
Each picking workload comes from current WMS order lines and due times. The route model combines those orders with picker capacity and locations from the active warehouse layout; forecast output does not define the live workload.
06Async jobs with a scheduled cadence
Training and MILP solves run outside request-response cycles. Queued jobs, status polling, and scheduled weekly or daily runs let the system produce decisions on the warehouse's cadence.