进销存系统智能补货算法与库存优化
智能补货概述
智能补货是进销存系统的核心功能,通过算法预测未来需求,自动生成采购建议,实现库存的最优化管理。本文介绍多种智能补货算法,包括安全库存计算、订货点法、经济订货量、JIT 补货等方案。
补货算法对比
| 算法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 安全库存 | 需求波动大 | 防止缺货 | 占用资金 |
| 订货点法 | 稳定需求 | 自动触发 | 需要准确预测 |
| EOQ 经济订货量 | 批量采购 | 成本最优 | 假设理想化 |
| JIT 补货 | 供应商稳定 | 库存最小化 | 风险较高 |
安全库存计算
基于服务水平和需求波动计算安全库存:
// 安全库存计算器
class SafetyStockCalculator {
constructor(config) {
this.serviceLevel = config.serviceLevel || 0.95; // 服务水平 95%
this.leadTimeDays = config.leadTimeDays || 7; // 采购提前期
}
// 正态分布分位点
getZScore(serviceLevel) {
const zScores = {
0.90: 1.28,
0.95: 1.65,
0.97: 1.88,
0.99: 2.33
};
return zScores[serviceLevel] || 1.65;
}
// 计算安全库存
calculate(dailyDemand, demandStdDev, leadTimeDays = this.leadTimeDays) {
const z = this.getZScore(this.serviceLevel);
// 安全库存 = Z值 * 需求标准差 * sqrt(采购提前期)
const safetyStock = Math.ceil(z * demandStdDev * Math.sqrt(leadTimeDays));
return safetyStock;
}
// 使用历史数据计算
calculateFromHistory(salesData, leadTimeDays = this.leadTimeDays) {
// 计算日均需求
const avgDaily = salesData.reduce((sum, d) => sum + d.quantity, 0) / salesData.length;
// 计算需求标准差
const variance = salesData.reduce((sum, d) =>
sum + Math.pow(d.quantity - avgDaily, 2), 0) / salesData.length;
const stdDev = Math.sqrt(variance);
return this.calculate(avgDaily, stdDev, leadTimeDays);
}
}
// 订货点计算
class ReorderPointCalculator {
constructor() {
this.safetyStock = new SafetyStockCalculator({ serviceLevel: 0.95 });
}
// 订货点 = 日均需求 * 采购提前期 + 安全库存
calculate(avgDailyDemand, leadTimeDays, currentStock = 0) {
// 计算安全库存
const safety = this.safetyStock.calculate(avgDailyDemand, avgDailyDemand * 0.3, leadTimeDays);
// 订货点
const reorderPoint = Math.ceil(avgDailyDemand * leadTimeDays + safety);
return {
reorderPoint,
safetyStock: safety,
currentStock: currentStock,
needReorder: currentStock <= reorderPoint,
suggestedQuantity: Math.max(0, reorderPoint - currentStock + safety * 2)
};
}
}
// 使用示例
const calculator = new ReorderPointCalculator();
// 根据历史销售计算
const salesHistory = [
{ date: '2025-06-01', quantity: 120 },
{ date: '2025-06-02', quantity: 95 },
{ date: '2025-06-03', quantity: 110 },
{ date: '2025-06-04', quantity: 130 },
{ date: '2025-06-05', quantity: 85 },
{ date: '2025-06-06', quantity: 105 },
{ date: '2025-06-07', quantity: 115 }
];
const safetyCalc = new SafetyStockCalculator({ serviceLevel: 0.95, leadTimeDays: 7 });
const safetyStock = safetyCalc.calculateFromHistory(salesHistory, 7);
const avgDaily = salesHistory.reduce((s, d) => s + d.quantity, 0) / salesHistory.length;
const result = calculator.calculate(avgDaily, 7, 50); // 当前库存 50
console.log('安全库存:', safetyStock);
console.log('订货点:', result.reorderPoint);
console.log('建议补货量:', result.suggestedQuantity);
经济订货量(EOQ)模型
平衡采购成本和库存持有成本:
// 经济订货量 (EOQ) 计算
class EOQCalculator {
constructor(annualDemand, unitCost, orderingCost, holdingCostRate) {
this.annualDemand = annualDemand; // 年需求量
this.unitCost = unitCost; // 单位采购成本
this.orderingCost = orderingCost; // 每次订货成本
this.holdingCostRate = holdingCostRate; // 库存持有成本率
}
// EOQ = sqrt(2 * 年需求量 * 订货成本 / 单位持有成本)
calculate() {
const holdingCostPerUnit = this.unitCost * this.holdingCostRate;
const eoq = Math.sqrt(
(2 * this.annualDemand * this.orderingCost) / holdingCostPerUnit
);
return Math.ceil(eoq);
}
// 计算总成本
calculateTotalCost(orderQuantity) {
// 订货次数
const ordersPerYear = this.annualDemand / orderQuantity;
// 订货成本
const totalOrderingCost = ordersPerYear * this.orderingCost;
// 持有成本(平均库存 * 单位持有成本)
const avgInventory = orderQuantity / 2;
const holdingCostPerUnit = this.unitCost * this.holdingCostRate;
const totalHoldingCost = avgInventory * holdingCostPerUnit;
// 采购成本
const purchaseCost = this.annualDemand * this.unitCost;
return {
purchaseCost,
orderingCost: totalOrderingCost,
holdingCost: totalHoldingCost,
totalCost: purchaseCost + totalOrderingCost + totalHoldingCost,
ordersPerYear: Math.ceil(ordersPerYear)
};
}
}
// 批量折扣模型
class QuantityDiscountEOQ {
constructor(annualDemand, orderingCost, discountTiers) {
this.annualDemand = annualDemand;
this.orderingCost = orderingCost;
this.discountTiers = discountTiers.sort((a, b) => b.discount - a.discount);
}
findOptimalOrder() {
const results = [];
// 1. 计算 EOQ
const eoq = Math.sqrt(
(2 * this.annualDemand * this.orderingCost) /
(this.discountTiers[0].price * 0.2) // 假设持有成本率 20%
);
// 2. 检查 EOQ 是否在某个折扣区间
const eoqTier = this.discountTiers.find(t => eoq >= t.minQuantity);
// 3. 计算每个折扣级别的最优订货量
for (const tier of this.discountTiers) {
const holdingRate = 0.2;
const holdingCost = tier.price * holdingRate;
const eoqForTier = Math.sqrt(
(2 * this.annualDemand * this.orderingCost) / holdingCost
);
// 限制在最小数量
const orderQty = Math.max(eoqForTier, tier.minQuantity);
const calc = new EOQCalculator(
this.annualDemand,
tier.price,
this.orderingCost,
holdingRate
);
const costInfo = calc.calculateTotalCost(orderQty);
results.push({
discount: tier.discount,
price: tier.price,
orderQuantity: orderQty,
...costInfo
});
}
// 4. 选择总成本最低的方案
results.sort((a, b) => a.totalCost - b.totalCost);
return results[0];
}
}
// 折扣级别定义
const discountTiers = [
{ minQuantity: 1, discount: 0, price: 100 },
{ minQuantity: 100, discount: 0.05, price: 95 },
{ minQuantity: 500, discount: 0.10, price: 90 },
{ minQuantity: 1000, discount: 0.15, price: 85 }
];
const solver = new QuantityDiscountEOQ(10000, 500, discountTiers);
const optimal = solver.findOptimalOrder();
console.log('最优方案:', optimal);
智能需求预测
结合多种算法预测未来需求:
// 需求预测器
class DemandForecaster {
constructor() {
this.models = {
movingAverage: this.movingAverage.bind(this),
weightedMovingAverage: this.weightedMovingAverage.bind(this),
exponentialSmoothing: this.exponentialSmoothing.bind(this)
};
}
// 移动平均
movingAverage(data, period = 7) {
if (data.length < period) return null;
const recent = data.slice(-period);
return recent.reduce((sum, v) => sum + v, 0) / period;
}
// 加权移动平均(近期权重更大)
weightedMovingAverage(data, weights) {
if (data.length < weights.length) return null;
const recent = data.slice(-weights.length);
const weightedSum = recent.reduce((sum, v, i) => sum + v * weights[i], 0);
return weightedSum / weights.reduce((s, w) => s + w, 0);
}
// 指数平滑
exponentialSmoothing(data, alpha = 0.3) {
if (data.length === 0) return null;
let forecast = data[0];
for (let i = 1; i < data.length; i++) {
forecast = alpha * data[i] + (1 - alpha) * forecast;
}
return forecast;
}
// 综合预测(结合多种方法)
ensembleForecast(data) {
const predictions = [];
// 移动平均
const ma = this.movingAverage(data, 7);
if (ma) predictions.push({ method: 'MA7', value: ma, weight: 0.2 });
// 加权移动平均(4周权重)
const wma = this.weightedMovingAverage(data, [0.1, 0.15, 0.25, 0.5]);
if (wma) predictions.push({ method: 'WMA', value: wma, weight: 0.3 });
// 指数平滑
const es = this.exponentialSmoothing(data, 0.3);
if (es) predictions.push({ method: 'ES', value: es, weight: 0.5 });
// 加权平均
const totalWeight = predictions.reduce((s, p) => s + p.weight, 0);
const forecast = predictions.reduce((s, p) => s + p.value * p.weight, 0) / totalWeight;
return {
forecast: Math.round(forecast),
details: predictions
};
}
}
// 智能补货建议生成
class SmartReplenishment {
constructor(config) {
this.forecaster = new DemandForecaster();
this.safetyStockCalc = new SafetyStockCalculator({
serviceLevel: config.serviceLevel || 0.95,
leadTimeDays: config.leadTimeDays || 7
});
}
generateRecommendation(productId, salesHistory, currentStock, leadTimeDays) {
// 1. 预测未来需求
const demand = salesHistory.map(s => s.quantity);
const forecast = this.forecaster.ensembleForecast(demand);
// 2. 计算安全库存
const demandStdDev = this.calculateStdDev(demand);
const safetyStock = this.safetyStockCalc.calculate(
forecast.forecast,
demandStdDev,
leadTimeDays
);
// 3. 计算订货点
const avgDemand = demand.reduce((s, v) => s + v, 0) / demand.length;
const reorderPoint = Math.ceil(avgDemand * leadTimeDays + safetyStock);
// 4. 计算建议补货量(考虑目标库存)
const targetStock = safetyStock + avgDemand * 14; // 目标库存 = 安全库存 + 14天销量
const suggestedQty = Math.max(0, Math.ceil(targetStock - currentStock));
// 5. 紧急程度判断
const urgency = this.calculateUrgency(currentStock, reorderPoint, avgDemand);
return {
productId,
currentStock,
forecast: forecast.forecast,
safetyStock,
reorderPoint,
suggestedQuantity: suggestedQty,
urgency,
daysUntilStockout: currentStock / avgDemand
};
}
calculateStdDev(data) {
const avg = data.reduce((s, v) => s + v, 0) / data.length;
const variance = data.reduce((s, v) => s + Math.pow(v - avg, 2), 0) / data.length;
return Math.sqrt(variance);
}
calculateUrgency(currentStock, reorderPoint, avgDaily) {
if (currentStock <= 0) return 'CRITICAL';
if (currentStock <= reorderPoint * 0.5) return 'HIGH';
if (currentStock <= reorderPoint) return 'MEDIUM';
return 'LOW';
}
}
总结
智能补货算法是进销存系统的核心功能,合理的补货策略可以:
- 降低库存成本:减少资金占用和仓储费用
- 提高服务水平:降低缺货风险,提升客户满意度
- 优化采购效率:减少紧急采购,降低采购成本
- 数据驱动决策:基于历史数据预测,而非经验判断
建议根据企业实际情况选择合适的算法,并持续优化参数。