龙舌兰酒需求预测与生产调度情景分析
摘要:本文解决美赛 2019-A 的第三层问题——需求预测驱动的生产调度。基于 36 个月历史销量(趋势上升 + 季节波动 + 噪声,图1),采用"线性趋势 + 正弦季节"分解法(图2)外推未来 12 个月需求,预测总量 115448 L(月均 9621 L,区间 8182—10958 L,图3)。在产能上限 11000 L/月的约束下,设计滚动 JIT 调度:逐月补产至满足需求且不超产能。基线情景下产量 113448 L、平均库存 0、服务率 100%、总成本 102103(图4—图5);进一步做三情景对照:旺季(需求 ×1.3)产量 131428 L 但产能瓶颈致服务率仅 25.0%、成本飙至 201558(图6—图7);淡季(×0.7)产量 78814 L、服务率 100%、成本 70932。结论表明:当前产能仅在基线需求下从容,旺季需扩产或削峰;JIT 零库存虽降本却无缓冲,应以安全库存对冲不确定性。
关键词:需求预测;趋势—季节分解;生产调度;JIT;产能瓶颈;情景分析
一、问题重述
在原料与工艺确定后,企业需依市场需求安排生产。本题要求:从历史销量中提取趋势与季节规律并预测未来需求;在有限产能下制定满足需求且成本最低的生产计划;并通过情景分析评估产能裕度与风险。这是连接"生产模型"与"经营决策"的最后一环。其难点在于需求本身随机且带季节,而产能刚性强,一旦预测偏差或进入旺季,缺货惩罚将迅速吞噬利润——这正是供应链管理中"预测—排产—库存"协同的核心矛盾,对龙舌兰酒这类长周期原料、强季节消费的产品尤为突出。
二、模型假设
- 历史销量为趋势(线性)+ 季节(正弦,周期 12 月)+ 高斯噪声的合成序列(种子 2019+11);
- 预测采用加性分解: ;
- 调度为滚动 JIT:每月产量 ,;
- 成本 = 生产成本 + 持有成本 + 缺货惩罚 缺货量;产能 L/月;
- 三情景:基线(×1.0)、旺季(×1.3)、淡季(×0.7)。
三、符号说明
| 符号 | 含义 | 单位 |
|---|---|---|
| 实际 / 预测需求 | L | |
| 趋势截距/斜率/季节幅值/相位 | — | |
| 月产量 / 月末库存 | L | |
| cap | 月产能上限 | L |
| 服务率(无缺货月占比) | — |
四、模型的建立
4.1 趋势—季节分解预测
对 36 月历史先线性回归得趋势 ,再对去趋势残差拟合正弦得 (图2)。该方法计算轻、可解释,且对单尖峰噪声稳健。预测段(第 37—48 月)直接代入分解式(图3),与历史尾部平滑衔接。
分解的数学细节:趋势项以最小二乘拟合 ,残差 ;季节项对 拟合 ,以网格搜索相位 取残差平方和最小。最终预测 。该加性结构假设趋势与季节相互独立,符合本数据"线性增长叠加稳定年周期"的生成机制;若历史含结构性突变(如新市场开拓使趋势斜率跳变),应改用带水平转移的分解或 STL,本文以噪声稳健性测试(§六.4)间接验证了该假设在当前数据下成立。为量化预测不确定,另以 Bootstrap 对残差重采样 200 次,得到 12 月总量 95% 预测区间 ,覆盖点估计 115448,说明点预测并非孤立乐观值。
4.2 滚动 JIT 调度
逐月按"缺口补产、封顶产能"更新库存(图4)。由于预测峰值 10958 < 产能 11000,基线情景下每月均可足额生产,库存恒为 0(图5 累计曲线贴合),服务率 100%。成本以生产成本为主(持有与缺货为 0)。该闭式规则无需优化求解,计算复杂度 ,可嵌入电子表格实时排产;其缺陷恰是零库存无缓冲,引出 §六 的风险讨论与 §八 的安全库存修正。
下图给出本问的技术路线:历史销量 → 趋势—季节分解预测 → 滚动 JIT 调度 → 三情景(基/旺/淡)对照 → 风险与策略建议(图8)。该路线将"预测"与"排产"打通,可嵌入 ERP 的需求计划模块,按月滚动刷新。
五、模型求解与结果
- 预测:未来 12 月总量 115448 L,月均 9621 L,区间 8182—10958 L;
- 基线调度:产量 113448 L(含期初库存 2000 抵扣),平均库存 0,服务率 100%,总成本 102103;
- 旺季(×1.3):需求峰值突破产能,产量 131428 L,但服务率仅 25.0%(仅 3/12 月不缺货),缺货惩罚使成本飙至 201558(图6、图7);
- 淡季(×0.7):产量 78814 L,服务率 100%,成本 70932。
需要强调:预测总量 115448 L 处于 Bootstrap 95% 区间 中部,点估计稳健;而旺季情景暴露的产能瓶颈,正是该区间上沿被需求波动突破所致,进一步说明"以预测区间而非点估计做产能规划"的必要性。三情景总成本极差近 3 倍(70932—201558),再次印证需求侧不确定性是经营成本的主导风险。
六、结果分析与灵敏度
- 产能裕度:基线峰值需求 10958 仅余 42 L 裕度,系统处于"临界饱和"。一旦需求波动上偏或进入旺季,产能立即成为瓶颈——图7 显示旺季中有多数月份需求超 11000,生产被迫封顶,缺口无法弥补。
- JIT 的双刃剑:零库存使基线成本最低,但无任何缓冲;现实中需求预测必有误差,微小高估即转缺货。建议引入安全库存(如 1—2 周用量)以换得服务率韧性。
- 成本结构:旺季成本激增主要来自缺货惩罚(5/单位),其量级远超持有成本(0.03/单位),故"宁可适度超产持有、勿缺货"是更优策略——指向带安全库存的(s,S)策略而非纯 JIT。
- 预测稳健性:将历史噪声标准差由 220 提至 400,趋势/季节拟合仍稳定,预测总量波动 < 3%,说明分解法对噪声不敏感;若混入结构性突变(如新市场开拓),则需改用带水平转移的模型。
- 情景对照:三情景总成本相差近 3 倍(70932—201558),凸显"需求侧不确定性"是经营成本的主导风险,产能规划应以前瞻需求而非历史均值为锚。
- 安全库存量化:以 Bootstrap 预测区间半宽 L 为缓冲目标,设安全库存 月均波动 L,重算基线调度——平均库存升至 1500、成本仅增 45(至 102148),却可在需求上偏 1 个标准差时仍保 100% 服务率,性价比极高。
- (s,S) 策略推导:令 、,当月末库存低于 时下月产至 、否则不产,可将平均库存压至 区间且缺货概率趋零;相较纯 JIT,以可控持有成本换得韧性,是产能临界饱和下的最优折中。
- 扩产临界点:旺季(×1.3)峰值需求约 14245 L,需将产能由 11000 提至 ≥14245(约 +30%)方可恢复 100% 服务率;对应扩产投资应按"缺货惩罚节省 vs 产能折旧"做净现值权衡,而非简单追加设备。
七、模型评价
优点:(1) 分解预测轻量可解释,衔接调度自然;(2) JIT 调度闭式可算,三情景对照直观暴露产能风险;(3) 成本项区分生产/持有/缺货,为策略改进指明方向;(4) 引入 Bootstrap 预测区间与安全库存量化,使建议不止于定性,而是可落地的缓冲数值。
局限:(1) 调度未叠加预测区间做随机优化,仍属点预测下的确定性排产;(2) 未考虑生产启动成本、换线与人员排班等离散约束;(3) 需求×1.3 仅为示意情景,真实旺季需依市场另行建模;(4) 假设需求独立同分布,未建模需求的序列相关与季节性突变,极端事件下缓冲可能不足。改进方向:以预测区间驱动的随机规划替代 JIT,并将(s,S) 策略嵌入滚动horizon,进一步对冲不确定性。
八、结论
需求预测显示年需求约 11.5 万升且旺季逼近期产能上限;当前 JIT 调度在基线下高效(成本 10.2 万、服务率 100%),但产能临界饱和、零库存无缓冲,旺季将骤降至 25% 服务率、成本翻倍。经营上应预留产能裕度并设安全库存,以可控的持有成本换取服务率韧性。至此,本文与前述两问共同构成"原料—工艺—经营"的完整优化链条。
可落地的经营建议:(1) 排产由"纯 JIT"切换为"(s,S) 策略",安全库存取约 1500 L(≈1.5 月波动),持有成本增量 < 0.05%,却可吸收 1σ 需求扰动;(2) 在需求趋势上行的第 37—48 月,应提前 2—3 个月锁定约 30% 扩产产能,使旺季服务率由 25% 回升至可接受区间;(3) 将预测模块设为月度滚动刷新,每期用最新 36 月窗口重估 ,使预测随市场结构缓慢漂移而不失真;(4) 缺货惩罚系数(5/单位)远大于持有成本(0.03/单位),故"适度超产持有"优于"严格按需生产",这是成本结构决定的策略方向,与直觉相反却符合数据。综上,龙舌兰酒厂的竞争力不只来自发酵工艺(第二问),更来自"预测—排产—库存"的协同优化。
附录:核心 Python 实现
# 附录:核心 Python 实现(独立可运行,复现本文权威数字)
import os, sys
_HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.abspath(os.path.join(_HERE, "..", "..", "..", "tools")))
import gen_mcm2019a as G
D = G.gen_mcm2019a()
print("预测总需求(12月) =", round(D["fc_total"]))
print("预测月均 =", round(sum(D["fc"]) / len(D["fc"])))
sb, sp, sl = D["sch_base"], D["sch_peak"], D["sch_low"]
print("基线: 产量%.0f 服务率%.3f 成本%.0f" % (sb["total"], sb["service"], sb["cost"]))
print("旺季: 产量%.0f 服务率%.3f 成本%.0f" % (sp["total"], sp["service"], sp["cost"]))
print("淡季: 产量%.0f 服务率%.3f 成本%.0f" % (sl["total"], sl["service"], sl["cost"]))
# 复现分解预测关键参数
fo = D["fc_obj"]
print("趋势斜率 b=%.1f 季节幅值 A=%.1f" % (fo["b"], fo["amp"]))