1. 供应链模型基础与论文复现价值
供应链管理中的供应商-零售商模型是运作研究领域的经典课题,特别是在多级库存优化和渠道协调方面具有重要研究价值。这个双零售商单供应商模型(1S2R)常被用来研究需求波动下的库存策略、批发定价机制以及供应链契约设计等问题。我在研究生阶段就接触过Thomas教授2002年发表的经典论文,其中用非线性规划构建的1S2R模型至今仍被广泛引用。
复现这类论文模型具有三重意义:首先是验证原论文结论的可重复性,这在当前强调科研可复现性的环境下尤为重要;其次是通过实操深入理解模型构建的逻辑链条,比单纯阅读论文更能掌握精髓;最后是为后续模型扩展打下基础,比如添加随机需求或引入博弈论要素。Mathematica作为符号计算领域的标杆工具,其强大的方程求解和可视化能力特别适合处理这类包含复杂约束的优化问题。
提示:选择Mathematica而非MATLAB或Python的主要考量是其符号计算能力,这在处理含有分段函数或条件约束的供应链模型时优势明显。例如求解Karush-Kuhn-Tucker条件时能自动处理不等式约束。
2. 模型构建与数学表达
原论文建立的1S2R模型核心由以下要素构成:
- 决策变量:供应商批发价w,零售商i的订货量q_i (i=1,2)
- 目标函数:供应商利润最大化 Π_s = (w-c)(q1+q2)
- 约束条件:
- 零售商利润函数 Π_ri = (p_i-w)q_i - h_i(q_i)
- 市场需求函数 q_i = a_i - b_i p_i + γ p_j (j≠i)
- 非负约束 w,c,p,q ≥ 0
其中h_i(·)表示库存成本函数,通常采用凸函数形式如h_i(q)=η_i q²。交叉价格弹性γ反映零售商间的竞争强度,这是双渠道模型区别于单零售商的本质特征。在Mathematica中我们这样定义核心方程:
mathematica复制demand1 = a1 - b1 p1 + γ p2;
demand2 = a2 - b2 p2 + γ p1;
profitR1 = (p1 - w)*q1 - η1 q1^2;
profitR2 = (p2 - w)*q2 - η2 q2^2;
profitS = (w - c)*(q1 + q2);
3. Mathematica求解全流程
3.1 参数初始化与假设检验
首先需要设置合理的参数值进行数值模拟。根据零售业实证研究,我建议采用以下基准参数:
mathematica复制params = {a1->100, a2->90, b1->1.2, b2->1.0, c->15, γ->0.6, η1->0.2, η2->0.15};
这些数值保证了需求函数向下倾斜(b_i>γ)和利润函数的凹性。通过Manipulate函数可以动态观察参数敏感性:
mathematica复制Manipulate[
Plot3D[profitS /. {w->ww, q1->dd1, q2->dd2} /. params,
{ww, 20, 50}, {dd1, 30, 70}],
{dd2, 30, 70}]
3.2 均衡求解与可视化
Stackelberg博弈下的求解需要分两步:首先求零售商的反应函数,再优化供应商的批发价。使用Solve和Maximize组合:
mathematica复制(* 零售商阶段 *)
react1 = Solve[D[profitR1 /. {q1->demand1, q2->demand2}, p1]==0, p1][[1]];
react2 = Solve[D[profitR2 /. {q1->demand1, q2->demand2}, p2]==0, p2][[1]];
(* 供应商阶段 *)
optW = Maximize[{profitS /. {q1->demand1, q2->demand2} /. Join[react1,react2],
w>c}, w] // Simplify
通过Plot绘制关键变量的关系曲线能直观展示博弈结果:
mathematica复制Plot[Evaluate[{p1,p2}/.Join[react1,react2]/.params/.w->ww],
{ww,c,50}, PlotLegends->{"Retailer 1","Retailer 2"}]
4. 关键问题与解决方案
4.1 多解筛选与验证
非线性方程组常出现多个解,需要经济意义筛选。例如通过二阶条件验证:
mathematica复制HessianMatrix = {
{D[profitR1, {p1,2}], D[profitR1, p1, p2]},
{D[profitR2, p2, p1], D[profitR2, {p2,2}]}
};
PositiveDefiniteMatrixQ[HessianMatrix /. params]
4.2 收敛性问题处理
当γ接近b_i时(替代效应过强),模型可能无解。此时需要:
- 检查参数是否满足b_i > γ的理论条件
- 采用数值方法替代符号计算:
mathematica复制NMaximize[{profitS /. params, constraints}, {w, p1, p2}]
4.3 扩展模型方向
在基础模型上可以尝试:
- 引入随机需求:将a_i改为随机变量
- 添加契约设计:收益共享契约修改利润函数
- 多周期动态模型:使用RecurrenceTable
5. 完整可执行代码框架
以下是整合后的模块化代码结构:
mathematica复制ClearAll["Global`*"];
(* 1. 模型定义 *)
SetupModel[params_]:= Module[{},
demand1 = a1 - b1 p1 + γ p2;
demand2 = a2 - b2 p2 + γ p1;
profitR1 = (p1 - w)*q1 - η1 q1^2;
profitR2 = (p2 - w)*q2 - η2 q2^2;
profitS = (w - c)*(q1 + q2);
Return[params];
];
(* 2. 均衡求解 *)
FindEquilibrium[params_]:= Module[{},
react1 = Solve[D[profitR1 /. {q1->demand1, q2->demand2}, p1]==0, p1][[1]];
react2 = Solve[D[profitR2 /. {q1->demand1, q2->demand2}, p2]==0, p2][[1]];
optW = Maximize[{profitS /. {q1->demand1, q2->demand2} /.
Join[react1,react2] /. params, w>c}, w];
Return[optW];
];
(* 3. 执行示例 *)
params = {a1->100, a2->90, b1->1.2, b2->1.0, c->15, γ->0.6, η1->0.2, η2->0.15};
SetupModel[params];
solution = FindEquilibrium[params];
Print["Optimal wholesale price: ", solution[[1,2]]];
6. 深度优化技巧
- 符号计算加速:对重复使用的中间表达式使用With或Block局部化变量
- 精度控制:当涉及复杂数值积分时设置WorkingPrecision->30
- 并行计算:参数扫描时使用ParallelTable:
mathematica复制ParallelTable[
FindEquilibrium[params /. γ->g],
{g, 0.1, 0.9, 0.1}]
- 结果验证:通过反向代入验证均衡解的正确性
mathematica复制CheckSolution[sol_]:= Module[{},
eq1 = D[profitR1 /. sol, p1] == 0;
eq2 = D[profitR2 /. sol, p2] == 0;
Return[And @@ {eq1, eq2} /. params]
];
在完成基础模型复现后,我通常会进行以下扩展分析:
- 绘制帕累托前沿分析供应链协调空间
- 比较集中决策与分散决策的效率损失
- 引入不对称信息条件下的激励机制设计
通过这样的完整复现流程,不仅能深入理解原论文的建模思想,更能培养独立构建供应链模型的能力。Mathematica的交互式特性允许快速检验各种假设,这是其他编程环境难以比拟的优势。建议初学者从简化模型开始,逐步添加复杂要素,同时善用Wolfram文档中心的Optimization和Game Theory相关案例。
