| name | inventory-optimization |
| description | Optimize inventory levels using EOQ, multi-echelon models, and cost minimization. Use this skill when calculating economic order quantities, minimizing total inventory costs, optimizing across multiple locations, or balancing ordering and holding costs. |
Inventory Optimization
Optimize inventory levels to minimize costs while meeting service requirements.
Installation
pip install pandas numpy scipy pulp
Quick Start
import numpy as np
# Economic Order Quantity (EOQ)
annual_demand = 10000
ordering_cost = 50
holding_cost_per_unit = 2
eoq = np.sqrt((2 * annual_demand * ordering_cost) / holding_cost_per_unit)
# EOQ = sqrt((2 * 10000 * 50) / 2) = 707 units
EOQ Models
Basic EOQ
def calculate_eoq(annual_demand, ordering_cost, holding_cost):
"""Calculate Economic Order Quantity."""
eoq = np.sqrt((2 * annual_demand * ordering_cost) / holding_cost)
return eoq
def eoq_total_cost(annual_demand, ordering_cost, holding_cost, order_qty):
"""Calculate total annual inventory cost."""
ordering_costs = (annual_demand / order_qty) * ordering_cost
holding_costs = (order_qty / 2) * holding_cost
return ordering_costs + holding_costs
def optimal_order_frequency(annual_demand, eoq):
"""Calculate optimal number of orders per year."""
return annual_demand / eoq
EOQ with Quantity Discounts
def eoq_quantity_discount(annual_demand, ordering_cost, holding_rate, price_breaks):
"""
EOQ with quantity discounts.
price_breaks: list of (min_qty, unit_price) tuples
"""
best_cost = float('inf')
best_qty = 0
for i, (min_qty, price) in enumerate(price_breaks):
holding_cost = holding_rate * price
eoq = np.sqrt((2 * annual_demand * ordering_cost) / holding_cost)
# Adjust EOQ to valid range
if i < len(price_breaks) - 1:
max_qty = price_breaks[i + 1][0] - 1
else:
max_qty = float('inf')
# Check feasible quantities
for qty in [max(min_qty, eoq), min_qty]:
if qty >= min_qty and qty <= max_qty:
total_cost = (
annual_demand * price + # Purchase cost
(annual_demand / qty) * ordering_cost + # Ordering cost
(qty / 2) * holding_cost # Holding cost
)
if total_cost < best_cost:
best_cost = total_cost
best_qty = qty
return best_qty, best_cost
Production EOQ (EPQ)
def calculate_epq(annual_demand, setup_cost, holding_cost, production_rate):
"""Economic Production Quantity for manufacturing."""
demand_rate = annual_demand / 365
factor = 1 - (demand_rate / production_rate)
epq = np.sqrt((2 * annual_demand * setup_cost) / (holding_cost * factor))
return epq
Multi-Item Optimization
from pulp import LpProblem, LpMinimize, LpVariable, lpSum
def optimize_inventory_budget(items, budget):
"""
Optimize inventory levels across multiple items with budget constraint.
items: list of dicts with 'name', 'demand', 'cost', 'holding_rate', 'ordering_cost'
"""
prob = LpProblem("Inventory_Optimization", LpMinimize)
# Decision variables: order quantities
order_qty = {item['name']: LpVariable(f"Q_{item['name']}", lowBound=1)
for item in items}
# Objective: minimize total inventory cost
total_cost = lpSum([
(item['demand'] / order_qty[item['name']]) * item['ordering_cost'] +
(order_qty[item['name']] / 2) * item['cost'] * item['holding_rate']
for item in items
])
prob += total_cost
# Budget constraint on average inventory value
prob += lpSum([
(order_qty[item['name']] / 2) * item['cost'] for item in items
]) <= budget
prob.solve()
return {item['name']: order_qty[item['name']].value() for item in items}
ABC Analysis
def abc_classification(items):
"""
Classify items by value contribution.
items: list of (sku, annual_usage, unit_cost)
"""
# Calculate annual value
valued_items = [(sku, usage * cost, usage, cost)
for sku, usage, cost in items]
valued_items.sort(key=lambda x: x[1], reverse=True)
total_value = sum(v[1] for v in valued_items)
cumulative = 0
classifications = {}
for sku, value, usage, cost in valued_items:
cumulative += value
pct = cumulative / total_value
if pct <= 0.80:
classifications[sku] = 'A'
elif pct <= 0.95:
classifications[sku] = 'B'
else:
classifications[sku] = 'C'
return classifications
Inventory Metrics
def calculate_inventory_metrics(avg_inventory, annual_demand, unit_cost,
annual_sales, carrying_cost_rate):
"""Calculate key inventory performance metrics."""
inventory_value = avg_inventory * unit_cost
return {
'inventory_turnover': annual_demand / avg_inventory,
'days_of_supply': (avg_inventory / annual_demand) * 365,
'inventory_value': inventory_value,
'carrying_cost': inventory_value * carrying_cost_rate,
'gmroi': annual_sales / inventory_value # Gross Margin ROI
}