1. 供应链双零售商模型概述
在供应链管理研究中,一个供应商对应多个零售商的模型是经典的研究场景。这种模型特别适合分析供应链中的竞争与合作关系,以及库存管理、定价策略等核心问题。我最近复现的这篇论文,正是研究一个供应商同时向两个零售商供货时的最优决策问题。
这个模型的价值在于它反映了现实商业中常见的分销模式。比如某品牌制造商(供应商)同时向沃尔玛和家乐福(两个零售商)供货的场景。通过数学建模,我们可以量化分析不同决策对供应链各环节的影响。
提示:这类模型通常需要考虑的因素包括订货批量、库存成本、运输成本、市场需求函数以及各方的利润最大化目标。
2. 模型构建与数学表达
2.1 基础假设与参数定义
在构建模型时,论文做了几个关键假设:
- 供应商具有无限的生产能力
- 两个零售商面临独立但可能相关的市场需求
- 信息在各节点间完全对称
- 采用单一产品、单周期的决策框架
模型涉及的主要参数包括:
- 供应商的生产成本 c
- 批发价格 w
- 零售价格 p₁, p₂
- 市场需求函数 D₁(p₁), D₂(p₂)
- 各节点的固定成本和变动成本
2.2 利润函数构建
供应商的利润函数可以表示为:
π_s = (w - c)(q₁ + q₂) - K_s
其中q₁和q₂分别是向两个零售商的发货量,K_s是供应商的固定成本。
每个零售商的利润函数为:
π_rᵢ = (pᵢ - w)min(Dᵢ(pᵢ), qᵢ) - K_rᵢ, i=1,2
这里用min函数是因为实际销售量不能超过市场需求或库存量。
3. Mathematica求解实现
3.1 环境准备与包加载
首先需要确保Mathematica环境配置正确。我使用的是Mathematica 12.3版本,关键是要加载以下包:
mathematica复制Needs["Optimization`"]
Needs["SymbolicC`"]
这些包提供了优化求解和符号计算的核心功能。
3.2 模型参数初始化
在Mathematica中,我们先定义基础参数:
mathematica复制c = 10; (* 供应商单位生产成本 *)
w = 15; (* 批发价格 *)
Ks = 1000; (* 供应商固定成本 *)
Kr1 = 500; (* 零售商1固定成本 *)
Kr2 = 500; (* 零售商2固定成本 *)
(* 需求函数 - 线性价格敏感型 *)
D1[p1_] := Max[0, 1000 - 50 p1]
D2[p2_] := Max[0, 800 - 40 p2]
3.3 利润函数定义
接着定义各方的利润函数:
mathematica复制(* 供应商利润函数 *)
PiSupplier[q1_, q2_] := (w - c)(q1 + q2) - Ks
(* 零售商利润函数 *)
PiRetailer1[p1_, q1_] := (p1 - w) Min[D1[p1], q1] - Kr1
PiRetailer2[p2_, q2_] := (p2 - w) Min[D2[p2], q2] - Kr2
3.4 均衡求解
论文中求解的是Stackelberg均衡,即供应商先决定批发价和发货量,零售商随后决定零售价。在Mathematica中可以通过嵌套的Maximize函数实现:
mathematica复制(* 零售商最优反应函数 *)
retailer1Opt[p1_, q1_] := Maximize[{PiRetailer1[p1, q1], p1 >= w}, p1]
retailer2Opt[p2_, q2_] := Maximize[{PiRetailer2[p2, q2], p2 >= w}, p2]
(* 供应商优化问题 *)
supplierSolution = Maximize[
{
PiSupplier[q1, q2] /. {
p1 -> retailer1Opt[p1, q1][[2, 1, 2]],
p2 -> retailer2Opt[p2, q2][[2, 1, 2]]
},
q1 >= 0 && q2 >= 0
},
{q1, q2}
]
4. 结果分析与可视化
4.1 均衡解提取
求解完成后,我们可以提取关键结果:
mathematica复制optimalQ1 = q1 /. supplierSolution[[2]]
optimalQ2 = q2 /. supplierSolution[[2]]
optimalP1 = p1 /. retailer1Opt[p1, optimalQ1][[2]]
optimalP2 = p2 /. retailer2Opt[p2, optimalQ2][[2]]
4.2 利润计算
计算各方的均衡利润:
mathematica复制supplierProfit = PiSupplier[optimalQ1, optimalQ2]
retailer1Profit = PiRetailer1[optimalP1, optimalQ1]
retailer2Profit = PiRetailer2[optimalP2, optimalQ2]
4.3 可视化分析
使用Mathematica的绘图功能可以直观展示关系:
mathematica复制Plot3D[PiSupplier[q1, q2], {q1, 0, 1000}, {q2, 0, 1000},
AxesLabel -> {"q1", "q2", "Profit"}]
这个三维图展示了供应商利润随发货量变化的曲面,帮助我们理解最优决策点。
5. 复现过程中的关键问题
5.1 收敛性问题
在最初尝试时,我发现优化过程有时不收敛。这是因为需求函数和利润函数的非线性特性导致的。解决方法包括:
- 提供合理的初始值
- 使用不同的优化方法(如Nelder-Mead)
- 对变量范围进行合理约束
5.2 符号计算与数值计算的平衡
Mathematica的符号计算能力很强,但对于复杂模型可能效率低下。我的经验是:
- 先用符号表示建立通用模型
- 代入具体参数值后再进行数值优化
- 对中间结果进行Simplify操作减少复杂度
5.3 模型敏感性分析
为了验证模型的稳健性,我进行了参数敏感性分析:
mathematica复制sensitivityAnalysis = Table[
cVal = c + delta;
supplierSolution = Maximize[...]; (* 同上但用cVal *)
{delta, q1 /. supplierSolution[[2]], q2 /. supplierSolution[[2]]},
{delta, -2, 2, 0.5}
];
ListPlot[sensitivityAnalysis[[All, {1, 2}]], Joined -> True]
这个分析展示了生产成本变化对最优发货量的影响。
6. 模型扩展与改进
6.1 引入竞争因素
原模型假设两个零售商独立运作,可以扩展为考虑竞争:
mathematica复制D1[p1_, p2_] := Max[0, 1000 - 50 p1 + 20 p2]
D2[p1_, p2_] := Max[0, 800 - 40 p2 + 15 p1]
这种交叉价格弹性更符合实际情况。
6.2 多周期动态模型
将单周期扩展为多周期,需要考虑库存动态:
mathematica复制(* 库存动态方程 *)
inventory1[t_] := inventory1[t-1] + q1[t] - D1[p1[t]]
inventory2[t_] := inventory2[t-1] + q2[t] - D2[p2[t]]
6.3 风险共担契约
可以引入更复杂的契约形式,如收益共享:
mathematica复制PiRetailer1[p1_, q1_] := phi (p1 - w) Min[D1[p1], q1] - Kr1
PiSupplier[q1_, q2_] := (w - c + (1-phi)(p1 + p2 - 2w))(q1 + q2) - Ks
其中phi是收益分享比例。
7. Mathematica使用技巧
7.1 调试技巧
- 使用Print临时输出中间结果
- 用//Timing监控各部分计算时间
- 对复杂表达式使用FullForm查看完整形式
7.2 性能优化
- 对重复计算使用Memoization
- 使用Compile加速数值计算
- 并行化独立计算任务
7.3 结果导出
将结果导出为可读格式:
mathematica复制Export["results.csv",
Flatten[{
{"q1", "q2", "p1", "p2"},
{optimalQ1, optimalQ2, optimalP1, optimalP2}
}], "CSV"]
8. 实际应用建议
基于这个模型的研究,我总结了几点管理启示:
- 供应商应关注两个零售商的相对市场大小,合理分配供货量
- 批发价格设置需要考虑零售端的价格弹性
- 在竞争环境下,协调机制能显著提升供应链整体效率
对于想复现这类研究的人,我的建议是:
- 先从简单模型入手,逐步增加复杂性
- 保持代码模块化,便于调试和扩展
- 多做敏感性分析,理解模型行为的边界条件
