kishorkukreja/awesome-supply-chain/lot-sizing-problems

Claude Code and agent skill by kishorkukreja/awesome-supply-chain

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

When the user wants to optimize production or order lot sizes over multiple periods, solve multi-period inventory planning problems, or determine when and how much to order/produce with time-varying demand. Also use when the user mentions "lot sizing," "lot-for-lot," "fixed order quantity," "POQ" (periodic order quantity), "part-period balancing," "Silver-Meal heuristic," "Wagner-Whitin algorithm," "least unit cost," "lot sizing with capacity constraints," or "multi-item lot sizing." For single-period problems, see newsvendor-problem. For time-varying lot sizing, see dynamic-lot-sizing.

Install

npx vskill@latest install kishorkukreja/awesome-supply-chain/lot-sizing-problems

SKILL.md

Lot-Sizing Problems

You are an expert in multi-period lot-sizing models and production/inventory planning optimization. Your goal is to help determine optimal order or production quantities across multiple time periods to minimize total costs including setup, holding, and sometimes shortage costs.

Initial Assessment

Before solving lot-sizing problems, understand:

  1. Planning Context
  • Planning horizon? (weeks, months, quarters)
  • Rolling or fixed horizon?
  • Demand pattern? (deterministic, forecast, actual orders)
  • Lead time considerations?
  1. Cost Structure
  • Setup/ordering cost per order ($)?
  • Holding cost per unit per period ($/unit/period)?
  • Production/purchase cost per unit?
  • Backorder or shortage costs?
  • Cost structure time-varying?
  1. Capacity and Constraints
  • Production capacity limits per period?
  • Storage capacity limits?
  • Minimum lot sizes or batch constraints?
  • Multiple items sharing capacity?
  1. Product Characteristics
  • Single item or multiple items?
  • Bill of materials structure?
  • Product substitutability?
  • Shelf life or obsolescence?
  1. Operational Requirements
  • Can backorders occur?
  • Must demand be satisfied immediately?
  • Multi-level production (BOM)?
  • Supplier constraints (MOQ, lead times)?

Lot-Sizing Problem Fundamentals

Problem Statement

Given:

  • Planning horizon: T periods (t = 1, 2, ..., T)
  • Demand in each period: D_t (known deterministically)
  • Setup cost: S (fixed cost incurred when ordering/producing)
  • Holding cost: h per unit per period
  • Unit cost: c (often ignored if constant)

Decision:

  • When to order/produce?
  • How much to order/produce in each period?

Objective:

  • Minimize total cost = setup costs + holding costs
Key Lot-Sizing Policies

1. Lot-for-Lot (L4L)

  • Order exactly what is needed each period: Q_t = D_t
  • Minimizes holding cost (zero inventory)
  • Maximizes setup costs
  • Use when setup costs are very low

2. Fixed Order Quantity (FOQ)

  • Order the same quantity Q every time
  • Simple to implement
  • May not match demand patterns well

3. Economic Order Quantity (EOQ)

  • Use EOQ formula with average demand
  • Assumes constant demand rate

4. Period Order Quantity (POQ)

  • Order every N periods (N determined by EOQ)
  • Combines multiple periods' demand

5. Least Unit Cost (LUC)

  • Choose lot size that minimizes cost per unit
  • Forward-looking heuristic

6. Least Total Cost (LTC) / Part-Period Balancing

  • Balance setup and holding costs
  • Choose lot when cumulative holding cost ≈ setup cost

7. Silver-Meal Heuristic

  • Minimize average cost per period
  • Popular practical heuristic

8. Wagner-Whitin Algorithm

  • Dynamic programming approach
  • Finds optimal solution for uncapacitated problem
  • Polynomial time complexity O(T²)

Python Implementation: Lot-Sizing Models

Basic Lot-Sizing Heuristics
python
import numpy as np
import pandas as pd
from typing import List, Dict, Tuple
import matplotlib.pyplot as plt
class LotSizingProblem:
"""
Multi-period lot-sizing problem solver
Implements various heuristics and optimal algorithm
"""
def __init__(self, demands: List[float], setup_cost: float,
holding_cost: float, unit_cost: float = 0):
"""
Parameters:
-----------
demands : list
Demand for each period [D1, D2, ..., DT]
setup_cost : float
Fixed cost incurred when placing order/production run
holding_cost : float
Cost per unit held in inventory per period
unit_cost : float
Variable cost per unit (often omitted if constant)
"""
self.demands = np.array(demands)
self.T = len(demands)
self.S = setup_cost
self.h = holding_cost
self.c = unit_cost
def lot_for_lot(self) -> Dict:
"""
Lot-for-Lot (L4L) policy: Order exactly demand each period
Minimizes inventory but incurs setup cost every period
"""
orders = self.demands.copy()
inventory = np.zeros(self.T + 1) # Inventory at end of each period
setup_costs = np.zeros(self.T)
holding_costs = np.zeros(self.T)
for t in range(self.T):
# Order arrives at start of period
inventory[t] += orders[t]
# Satisfy demand
inventory[t] -= self.demands[t]
# Costs
if orders[t] > 0:
setup_costs[t] = self.S
holding_costs[t] = inventory[t] * self.h
# Carry inventory forward
inventory[t + 1] = inventory[t]
total_setup = setup_costs.sum()
total_holding = holding_costs.sum()
total_cost = total_setup + total_holding
return {
'method': 'Lot-for-Lot',
'orders': orders,
'inventory': inventory[:-1],
'setup_cost': total_setup,
'holding_cost': total_holding,
'total_cost': total_cost,
'num_orders': (orders > 0).sum()
}
def fixed_order_quantity(self, Q: float) -> Dict:
"""
Fixed Order Quantity: Order Q units whenever inventory insufficient
Parameters:
-----------
Q : float
Fixed order quantity
"""
orders = np.zeros(self.T)
inventory = np.zeros(self.T + 1)
setup_costs = np.zeros(self.T)
holding_costs = np.zeros(self.T)
for t in range(self.T):
# Check if order needed
if inventory[t] < self.demands[t]:
orders[t] = Q
inventory[t] += Q
# Satisfy demand
inventory[t] -= self.demands[t]
# Handle backorders if negative
if inventory[t] < 0:
# Need more orders
num_orders = int(np.ceil(-inventory[t] / Q))
orders[t] += num_orders * Q
inventory[t] += num_orders * Q
# Costs
if orders[t] > 0:
setup_costs[t] = self.S * (orders[t] / Q) # Proportional setups
holding_costs[t] = max(0, inventory[t]) * self.h
# Carry forward
inventory[t + 1] = inventory[t]
total_setup = setup_costs.sum()
total_holding = holding_costs.sum()
total_cost = total_setup + total_holding
return {
'method': f'FOQ (Q={Q})',
'orders': orders,
'inventory': inventory[:-1],
'setup_cost': total_setup,
'holding_cost': total_holding,
'total_cost': total_cost,
'num_orders': (orders > 0).sum()
}
def silver_meal(self) -> Dict:
"""
Silver-Meal Heuristic
Iteratively add periods to lot, stop when average cost per period increases
"""
orders = np.zeros(self.T)
inventory = np.zeros(self.T + 1)
t = 0
while t < self.T:
# Determine lot size starting at period t
best_periods = 1
min_avg_cost = float('inf')
for k in range(1, self.T - t + 1):
# Consider covering periods t through t+k-1
# Cost = Setup cost + holding cost for carrying inventory
total_demand = sum(self.demands[t:t+k])
holding_cost = sum((j - t) * self.demands[t+j] * self.h
for j in range(k))
total_cost = self.S + holding_cost
avg_cost = total_cost / k
if avg_cost < min_avg_cost:
min_avg_cost = avg_cost
best_periods = k
else:
# Average cost increased, stop
break
# Place order for best_periods worth of demand
order_qty = sum(self.demands[t:t+best_periods])
orders[t] = order_qty
# Update inventory levels
inv = order_qty
for j in range(best_periods):
if t + j < self.T:
inventory[t + j] = inv
inv -= self.demands[t + j]
t += best_periods
# Calculate costs
setup_costs = np.where(orders > 0, self.S, 0)
holding_costs = inventory[:-1] * self.h
return {
'method': 'Silver-Meal',
'orders': orders,
'inventory': inventory[:-1],
'setup_cost': setup_costs.sum(),
'holding_cost': holding_costs.sum(),
'total_cost': setup_costs.sum() + holding_costs.sum(),
'num_orders': (orders > 0).sum()
}
def least_unit_cost(self) -> Dict:
"""
Least Unit Cost (LUC) Heuristic
For each order, add periods until cost per unit increases
"""
orders = np.zeros(self.T)
inventory = np.zeros(self.T + 1)
t = 0
while t < self.T:
min_unit_cost = float('inf')
best_periods = 1
for k in range(1, self.T - t + 1):
# Total demand covered
total_demand = sum(self.demands[t:t+k])
# Holding cost
holding_cost = sum((j - t) * self.demands[t+j] * self.h
for j in range(k))
# Total cost
total_cost = self.S + holding_cost
# Unit cost
unit_cost = total_cost / total_demand
if unit_cost < min_unit_cost:
min_unit_cost = unit_cost
best_periods = k
else:
break
# Place order
order_qty = sum(self.demands[t:t+best_periods])
orders[t] = order_qty
# Update inventory
inv = order_qty
for j in range(best_periods):
if t + j < self.T:
inventory[t + j] = inv
inv -= self.demands[t + j]
t += best_periods
# Calculate costs
setup_costs = np.where(orders > 0, self.S, 0)
holding_costs = inventory[:-1] * self.h
return {
'method': 'Least Unit Cost',
'orders': orders,
'inventory': inventory[:-1],
'setup_cost': setup_costs.sum(),
'holding_cost': holding_costs.sum(),
'total_cost': setup_costs.sum() + holding_costs.sum(),
'num_orders': (orders > 0).sum()
}
def wagner_whitin(self) -> Dict:
"""
Wagner-Whitin Algorithm
Dynamic programming approach - finds optimal solution
for uncapacitated lot-sizing problem
Time complexity: O(T²)
"""
T = self.T
# F[t] = minimum cost for periods 1..t
F = np.full(T + 1, np.inf)
F[0] = 0
# Predecessor: which period did we last order from?
pred = np.zeros(T + 1, dtype=int)
# DP forward pass
for t in range(1, T + 1):
for j in range(t):
# Consider ordering in period j to cover demand through period t
# Cost = F[j] + setup cost + holding cost
# Holding cost for covering periods j+1 through t
holding_cost = 0
for k in range(j + 1, t + 1):
# Hold demand[k-1] for (k - j - 1) periods
holding_cost += (k - j - 1) * self.demands[k - 1] * self.h
cost = F[j] + self.S + holding_cost
if cost < F[t]:
F[t] = cost
pred[t] = j

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
74
Repository forks
18
7-day trend score
22

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/kishorkukreja/awesome-supply-chain/lot-sizing-problems/badge)](https://verified-skill.com/skills/kishorkukreja/awesome-supply-chain/lot-sizing-problems)

Something wrong with this skill or its page? Tell us.