1. 供应链模型基础与问题定义
在供应链管理领域,一个供应商对应多个零售商的模型是经典的分布式库存优化问题。这种结构常见于区域分销场景,比如某食品加工厂(供应商)同时向沃尔玛和家乐福(零售商)供货。模型的核心矛盾在于:供应商需要平衡生产批量与配送频率,而零售商则关注自身库存成本和缺货风险。
这个特定案例研究的是1-supplier-2-retailer系统,主要考虑以下变量:
- 供应商的生产率(P)和准备成本(S)
- 零售商的需求率(D₁, D₂)和持有成本(h₁, h₂)
- 运输批量(Q)和配送周期(T)
典型的目标函数是最小化系统总成本,包括:
- 供应商的生产准备成本
- 库存持有成本(供应商+双零售商)
- 运输/订货成本
2. 数学建模过程详解
2.1 模型假设与符号定义
首先明确模型的边界条件:
- 需求确定且连续(区别于随机需求模型)
- 无限时间范围
- 不允许缺货
- 供应商采用批量生产策略
- 采用共同补货周期策略
关键符号定义表:
| 符号 | 含义 | 单位 |
|---|---|---|
| P | 供应商生产率 | 件/天 |
| Dᵢ | 零售商i的需求率 | 件/天 |
| hₛ | 供应商持有成本 | $/件/天 |
| hᵢ | 零售商i持有成本 | $/件/天 |
| A | 供应商准备成本 | $/次 |
| aᵢ | 零售商i订货成本 | $/次 |
| T | 共同补货周期 | 天 |
| nᵢ | 零售商i的配送频次 | 整数 |
2.2 成本函数推导
供应商的平均库存水平计算:
在周期T内,供应商需要生产足够满足两个零售商需求的量,即Q = (D₁ + D₂)T。由于生产是连续的,最大库存积累为 (P - D₁ - D₂)Q/P。
因此供应商库存成本为:
Cₛ = (A + hₛ(P - D₁ - D₂)T²/2)/T
零售商i的库存成本(考虑配送频次nᵢ):
Cᵢ = (aᵢ + hᵢDᵢT²/(2nᵢ))/T
总成本函数:
TC = Cₛ + C₁ + C₂
3. Mathematica实现过程
3.1 环境准备与参数初始化
首先在Mathematica中定义基础参数(示例值):
mathematica复制params = {
P -> 100, (* 供应商生产率 *)
D1 -> 20, (* 零售商1需求 *)
D2 -> 30, (* 零售商2需求 *)
hs -> 0.02, (* 供应商持有成本 *)
h1 -> 0.05, (* 零售商1持有成本 *)
h2 -> 0.04, (* 零售商2持有成本 *)
A -> 200, (* 供应商准备成本 *)
a1 -> 50, (* 零售商1订货成本 *)
a2 -> 60 (* 零售商2订货成本 *)
};
3.2 成本函数实现
定义总成本函数TC[T_, n1_, n2_]:
mathematica复制TC[T_, n1_, n2_] := Module[{Cs, C1, C2},
Cs = (A + hs*(P - D1 - D2)*T^2/2)/T;
C1 = (a1 + h1*D1*T^2/(2*n1))/T;
C2 = (a2 + h2*D2*T^2/(2*n2))/T;
Cs + C1 + C2 /. params
]
3.3 数值优化求解
使用NMinimize进行优化,注意配送频次n1,n2需为整数:
mathematica复制solution = NMinimize[
{
TC[T, n1, n2],
T > 0 && n1 >= 1 && n2 >= 1 && Element[{n1, n2}, Integers]
},
{T, n1, n2},
Method -> "DifferentialEvolution"
]
3.4 结果可视化分析
绘制成本随周期T变化的曲线(固定最优n1,n2):
mathematica复制optimalN1 = n1 /. solution[[2]];
optimalN2 = n2 /. solution[[2]];
Plot[
TC[T, optimalN1, optimalN2] /. params,
{T, 0.1, 10},
AxesLabel -> {"补货周期T(天)", "总成本"},
PlotLabel -> "总成本 vs 补货周期"
]
4. 关键实现技巧与注意事项
4.1 整数约束处理
在混合整数规划问题中,Mathematica的默认算法可能陷入局部最优。建议采用以下策略:
- 先用连续松弛法(去掉整数约束)求近似解
- 对n1,n2进行整数舍入
- 在整数邻域内执行网格搜索
mathematica复制(* 连续松弛 *)
contSol = NMinimize[TC[T, n1, n2], {T, n1, n2}, Method -> "NelderMead"];
(* 整数邻域搜索 *)
n1Range = Floor[n1 /. contSol[[2]]] - 1 ;; Ceiling[n1 /. contSol[[2]]] + 1;
n2Range = Floor[n2 /. contSol[[2]]] - 1 ;; Ceiling[n2 /. contSol[[2]]] + 1;
gridSearch = Flatten[Table[
{TC[T, n1, n2] /. params, {T, n1, n2}},
{n1, n1Range}, {n2, n2Range}, {T, 0.5, 5, 0.1}
], 2];
optimalGrid = MinimalBy[gridSearch, First][[1]]
4.2 敏感性分析实现
研究关键参数变化对最优解的影响:
mathematica复制sensitivityAnalysis = Table[
newParams = Append[params, D1 -> demand];
sol = NMinimize[
TC[T, n1, n2] /. newParams,
{T, n1, n2},
Method -> "DifferentialEvolution"
];
{demand, T /. sol[[2]], n1 /. sol[[2]], n2 /. sol[[2]], sol[[1]]},
{demand, 10, 30, 2}
];
ListLinePlot[
sensitivityAnalysis[[All, {1, 5}]],
PlotLabel -> "总成本随需求D1的变化"
]
4.3 常见报错处理
- 方程无解:检查参数是否满足P > D1 + D2的生产可行性条件
- 算法不收敛:尝试不同的Method选项("SimulatedAnnealing"/"RandomSearch")
- 整数解质量差:缩小参数搜索范围或手动提供初始值
5. 模型扩展方向
5.1 随机需求扩展
将确定需求改为随机过程,使用WhenEvent模拟需求波动:
mathematica复制demandProcess = RandomFunction[
WienerProcess[0, 0.5], {0, 100}
];
stochasticTC = Integrate[
hs*(P*t - D1*t - D2*t - demandProcess[t]),
{t, 0, T}
] + A + a1 + a2;
5.2 多目标优化
同时考虑成本最小化和服务水平最大化:
mathematica复制ParetoPlot[
{
TC[T, n1, n2],
1/(D1*T/n1 + D2*T/n2) (* 服务水平倒数 *)
},
{T, 0.5, 5}, {n1, 1, 5}, {n2, 1, 5},
PlotTheme -> "Business"
]
5.3 运输容量约束
添加卡车装载量限制条件:
mathematica复制constrainedSol = NMinimize[
{
TC[T, n1, n2],
D1*T/n1 <= truckCapacity && D2*T/n2 <= truckCapacity,
T > 0 && n1 >= 1 && n2 >= 1
},
{T, n1, n2},
Method -> "SimulatedAnnealing"
]
6. 论文复现要点
在复现学术论文时需特别注意:
- 参数一致性:确保所有参数值与原文完全一致,包括单位换算
- 算法选择:有些论文使用特定算法(如遗传算法),需要在Mathematica中实现对应方法
- 结果验证:对关键中间结果进行分步验证,比如单独检查供应商库存计算是否正确
- 图表格式:使用PlotTheme调整图表风格匹配论文要求
典型复现工作流:
- 从论文提取数学模型
- 转换为Mathematica表达式
- 实现优化求解流程
- 生成对比图表
- 进行敏感性测试
- 验证边界条件
对于这个特定模型,我发现在Mathematica中实现时需要注意配送频次n1,n2的整数处理。直接使用NMinimize的整数约束有时会得到次优解,更好的做法是先连续优化再局部枚举。另外,当D1/D2比值过大时,模型可能需要添加最小配送量约束以避免不现实的解。
