Inventory Optimization for Multi-Product Stocking Across Warehouses

Optimization
Warehouses
Python
Authors

Luciana Claure Parada

Mckenna Barton

Yonatan Rubio Lugo

Published

May 10, 2025

Inventory Optimization for Multi-Product Stocking Across Warehouses

We developed a linear programming model in AMPL to optimize multi-product inventory stocking decisions across two warehouses. The objective was to minimize total inventory costs, including both holding and ordering expenses, while satisfying demand and accounting for real-world constraints such as EOQ requirements, product shelf life, lead times, and warehouse capacity limits. By integrating these factors into a single optimization framework, the model provided a realistic decision-making tool for supply chain management.

The model converged to an optimal solution of $8.93M after 586 iterations, demonstrating its ability to handle large datasets and complex constraints efficiently. Sensitivity analyses were conducted to evaluate how cost outcomes changed under different scenarios. When demand was split evenly between warehouses, total costs were minimized, while skewed distributions (such as 70/30 or 80/20) led to higher costs due to underutilization of capacity and longer effective lead times. Similarly, adjusting ordering costs showed that supplier negotiations could have a significant impact on overall expenses.

These results highlight the value of balanced demand allocation, proactive cost management, and iterative use of the model as product mixes and supply conditions evolve. The project not only validated the effectiveness of linear programming for inventory optimization but also demonstrated how data-driven decision-making can improve efficiency and support strategic supply chain planning

Implementation in AMPL

To prepare the data, we ensured only feasible SKUs were considered by removing missing values and excluding products with an EOQ of zero. We then created a baseline demand split between warehouses and filtered out SKUs that could not be consumed within their shelf life.

df['WH1_demand'] = df['Item_Count'] * 0.5
df['WH2_demand'] = df['Item_Count'] * 0.5

df = df[
    (df['EOQ'] <= df['WH1_demand'] * df['Shelf_Life']) &
    (df['EOQ'] <= df['WH2_demand'] * df['Shelf_Life'])
]

The AMPL model declared decision variables for orders, inventory, and order activation. The objective minimized total holding and ordering costs, while constraints enforced demand fulfillment, shelf life limits, warehouse capacity, and EOQ rules.

var x {I, W, T} >= 0;
var inv {I, W, T} >= 0;
var z {I, W, T} binary;

minimize Total_Inventory_Cost:
    sum {i in I, w in W, t in T} (
        holdingCost[i] * inv[i, w, t] +
        orderingCost[i] * z[i, w, t]
    );

After solving with the CBC solver, results were exported as CSV files showing ending inventory levels, optimal order quantities, and order activations. These outputs demonstrated how our model can be used as a data-driven tool to balance costs, evaluate demand allocation strategies, and guide inventory planning decisions.