algo-sc-safety-stock

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Safety Stock Calculation

安全库存计算

Overview

概述

Safety stock is buffer inventory held to protect against demand and lead time variability. Formula: SS = z × √(LT × σ²_d + d² × σ²_LT) where z=service factor, LT=lead time, σ_d=demand std dev, d=avg demand, σ_LT=lead time std dev. Directly trades inventory cost against stockout risk.
安全库存是为应对需求和提前期波动而持有的缓冲库存。计算公式:SS = z × √(LT × σ²_d + d² × σ²_LT),其中z=服务系数,LT=提前期,σ_d=需求标准差,d=平均需求,σ_LT=提前期标准差。该公式直接体现了库存成本与缺货风险之间的权衡。

When to Use

使用场景

Trigger conditions:
  • Setting inventory buffers for variable-demand items
  • Choosing target service levels and computing required safety stock
  • Optimizing safety stock across a portfolio of SKUs
When NOT to use:
  • When demand is deterministic (use EOQ without safety stock)
  • For one-time purchase decisions (use newsvendor model)
触发条件:
  • 为需求波动的商品设置库存缓冲
  • 选择目标服务水平并计算所需安全库存
  • 优化全SKU组合的安全库存
不适用场景:
  • 需求确定时(使用不含安全库存的EOQ模型)
  • 一次性采购决策(使用newsvendor model)

Algorithm

算法

IRON LAW: Safety Stock Is a TRADE-OFF, Not a Target
More safety stock = fewer stockouts but higher holding cost.
The relationship is non-linear: going from 95% to 99% service level
roughly DOUBLES safety stock. Going from 99% to 99.9% doubles it
again. Always quantify the cost of each service level increment.
z-values: 90%→1.28, 95%→1.65, 99%→2.33, 99.9%→3.09.
IRON LAW: Safety Stock Is a TRADE-OFF, Not a Target
More safety stock = fewer stockouts but higher holding cost.
The relationship is non-linear: going from 95% to 99% service level
roughly DOUBLES safety stock. Going from 99% to 99.9% doubles it
again. Always quantify the cost of each service level increment.
z-values: 90%→1.28, 95%→1.65, 99%→2.33, 99.9%→3.09.

Phase 1: Input Validation

阶段1:输入验证

Collect: historical demand data (weekly/monthly), lead time data (average and variability), target service level, unit cost and holding rate. Gate: Minimum 12 periods of demand data, lead time estimates available.
收集:历史需求数据(周/月)、提前期数据(平均值及波动值)、目标服务水平、单位成本及持有费率。 准入条件: 至少12个周期的需求数据,且有提前期估算值。

Phase 2: Core Algorithm

阶段2:核心算法

  1. Compute demand statistics: average demand (d), demand standard deviation (σ_d)
  2. Compute lead time statistics: average LT, LT standard deviation (σ_LT)
  3. Compute combined variability: σ_combined = √(LT × σ²_d + d² × σ²_LT)
  4. Look up z for target service level
  5. Safety stock = z × σ_combined
  6. Reorder point = d × LT + SS
  1. 计算需求统计值:平均需求(d)、需求标准差(σ_d)
  2. 计算提前期统计值:平均提前期、提前期标准差(σ_LT)
  3. 计算综合波动值:σ_combined = √(LT × σ²_d + d² × σ²_LT)
  4. 根据目标服务水平查找对应的z值
  5. 安全库存 = z × σ_combined
  6. 再订货点 = d × LT + SS

Phase 3: Verification

阶段3:验证

Simulate: using historical demand, would the computed SS have prevented stockouts at the target service level? Gate: Simulated service level matches target (±2%).
模拟:使用历史需求数据验证计算出的安全库存是否能在目标服务水平下防止缺货。 准入条件: 模拟服务水平与目标值误差在±2%以内。

Phase 4: Output

阶段4:输出

Return safety stock with cost impact and service level analysis.
返回安全库存数值及对应的成本影响和服务水平分析。

Output Format

输出格式

json
{
  "safety_stock": 250,
  "reorder_point": 850,
  "service_level": 0.95,
  "annual_holding_cost": 5000,
  "metadata": {"avg_demand_weekly": 120, "demand_cv": 0.3, "avg_lead_time_weeks": 5}
}
json
{
  "safety_stock": 250,
  "reorder_point": 850,
  "service_level": 0.95,
  "annual_holding_cost": 5000,
  "metadata": {"avg_demand_weekly": 120, "demand_cv": 0.3, "avg_lead_time_weeks": 5}
}

Examples

示例

Sample I/O

输入输出样例

Input: Weekly demand: avg=100, σ=30. Lead time: avg=4 weeks, σ=1 week. Target: 95%. Expected: σ_combined = √(4×900 + 10000×1) = √(3600+10000) = √13600 = 116.6. SS = 1.65 × 116.6 = 192 units.
输入: 周需求:平均值=100,标准差=30。提前期:平均值=4周,标准差=1周。目标服务水平:95%。 预期结果: σ_combined = √(4×900 + 10000×1) = √(3600+10000) = √13600 = 116.6。安全库存 = 1.65 × 116.6 = 192单位。

Edge Cases

边缘情况

InputExpectedWhy
Zero demand variabilitySS from LT variability onlyσ_d = 0, only lead time risk remains
Zero lead time variabilitySS from demand variability onlyσ_LT = 0, standard formula simplifies
Very long lead timeHigh SSMore uncertainty accumulates over longer periods
输入预期结果原因
需求无波动仅考虑提前期波动的安全库存σ_d = 0,仅剩余提前期风险
提前期无波动仅考虑需求波动的安全库存σ_LT = 0,公式简化为标准形式
提前期极长高安全库存更长周期内不确定性累积更多

Gotchas

注意事项

  • Normal distribution assumption: Formula assumes normally distributed demand. Highly intermittent demand (many zeros) needs different approaches (Poisson, negative binomial).
  • Demand forecast error, not demand variability: If you use a forecast, SS should buffer forecast ERROR (σ_error), not raw demand variability.
  • Service level definition: Cycle service level (probability of no stockout per cycle) ≠ fill rate (fraction of demand met from stock). Companies often mean fill rate but calculate cycle SL.
  • Lead time data quality: Lead time variability is often poorly tracked. Underestimating σ_LT leads to insufficient safety stock.
  • ABC segmentation: Don't apply the same service level to all SKUs. A-items (high revenue) deserve 99%; C-items may be fine at 90%.
  • 正态分布假设:公式假设需求服从正态分布。对于高度间歇性需求(大量零值),需采用其他方法(如泊松分布、负二项分布)。
  • 需求预测误差,而非需求波动:若使用预测值,安全库存应缓冲预测误差(σ_error),而非原始需求波动。
  • 服务水平定义:周期服务水平(每个周期不缺货的概率)≠ 订单满足率(从库存发货的需求占比)。企业常实际指订单满足率,但计算的是周期服务水平。
  • 提前期数据质量:提前期波动往往未被妥善追踪。低估σ_LT会导致安全库存不足。
  • ABC分类:不要对所有SKU应用相同的服务水平。A类商品(高营收)应采用99%的服务水平;C类商品采用90%即可。

Scripts

脚本

ScriptDescriptionUsage
scripts/safety_stock.py
Compute safety stock and reorder point with combined demand/lead-time variability
python scripts/safety_stock.py --help
Run
python scripts/safety_stock.py --verify
to execute built-in sanity tests.
脚本描述使用方法
scripts/safety_stock.py
结合需求/提前期波动计算安全库存及再订货点
python scripts/safety_stock.py --help
运行
python scripts/safety_stock.py --verify
可执行内置的完整性测试。

References

参考资料

  • For multi-echelon safety stock optimization, see
    references/multi-echelon.md
  • For intermittent demand methods, see
    references/intermittent-demand.md
  • 关于多级安全库存优化,详见
    references/multi-echelon.md
  • 关于间歇性需求处理方法,详见
    references/intermittent-demand.md