1. 供应链模型基础与问题定义
在供应链管理领域,一个供应商与两个零售商组成的系统是最基础的供应链网络结构之一。这种看似简单的模型却蕴含着丰富的管理决策问题,包括库存控制、定价策略、配送优化等核心议题。我最近在复现一篇经典论文时,发现这个模型在实际应用中远比理论描述要复杂得多。
这个模型通常被称为1S2R(One Supplier Two Retailers)供应链模型,它研究的是单一供应商如何同时为两个相互竞争的零售商提供产品。供应商需要决定生产批量、发货频率和定价策略,而两个零售商则需要各自决定订购量、销售价格和库存水平。当零售商之间存在市场竞争时,他们的决策会相互影响,形成复杂的博弈关系。
提示:在Mathematica中建模时,特别要注意零售商之间的竞争关系如何数学化表达,这是模型能否准确反映现实的关键。
1.1 模型的基本假设与参数
根据我复现论文的经验,一个典型的1S2R模型通常包含以下基本假设:
- 供应商具有无限的生产能力或足够大的初始库存
- 两个零售商面临独立但可能相关的市场需求
- 零售商之间存在价格竞争或服务竞争
- 供应链成员之间信息对称
- 考虑固定的订货成本和库存持有成本
模型中需要定义的关键参数包括:
| 参数符号 | 参数含义 | 典型取值/单位 |
|---|---|---|
| c | 供应商单位生产成本 | 元/件 |
| w | 供应商批发价格 | 元/件 |
| p₁, p₂ | 零售商1和2的销售价格 | 元/件 |
| D₁(p₁,p₂) | 零售商1的需求函数 | 件/周期 |
| D₂(p₁,p₂) | 零售商2的需求函数 | 件/周期 |
| hₛ | 供应商库存持有成本 | 元/(件·周期) |
| hᵣ | 零售商库存持有成本 | 元/(件·周期) |
| Kₛ | 供应商固定订货成本 | 元/次 |
| Kᵣ | 零售商固定订货成本 | 元/次 |
1.2 竞争关系的数学表达
零售商之间的竞争关系通常通过需求函数来体现。在我的复现过程中,发现最常用的有以下几种形式:
-
线性价格竞争模型:
D₁(p₁,p₂) = a - b₁p₁ + θp₂
D₂(p₁,p₂) = a - b₂p₂ + θp₁其中θ衡量了交叉价格弹性,即一个零售商价格变化对另一个零售商需求的影响程度。
-
乘法竞争模型:
D₁(p₁,p₂) = k·p₁^(-α)·p₂^β这种形式更符合经济学中的弹性概念,但非线性特性增加了求解难度。
-
服务水平竞争:
当竞争焦点不是价格而是服务水平(如交货速度)时,需求函数可能表现为:
D₁(s₁,s₂) = a + λs₁ - μs₂其中s代表服务水平指标。
在Mathematica中实现这些需求函数时,我强烈建议先定义通用函数形式,再通过参数替换来比较不同竞争模式下的结果差异。这样可以大大提高代码的复用性和实验效率。
2. 论文模型复现的Mathematica实现
复现供应链模型论文时,Mathematica的强大符号计算能力可以极大简化推导过程。下面我将分享在复现1S2R模型时的具体实现步骤和关键技巧。
2.1 环境准备与基本定义
首先需要在Mathematica中定义模型的基本结构和参数:
mathematica复制(* 定义基本参数 *)
c = 10; (* 生产成本 *)
w = 15; (* 批发价格 *)
hS = 0.5; (* 供应商库存成本 *)
hR = 1; (* 零售商库存成本 *)
KS = 100; (* 供应商固定成本 *)
KR = 50; (* 零售商固定成本 *)
(* 定义需求函数 - 线性价格竞争模型 *)
a = 100; b1 = 2; b2 = 2; theta = 0.8;
D1[p1_, p2_] := a - b1*p1 + theta*p2
D2[p1_, p2_] := a - b2*p2 + theta*p1
(* 零售商利润函数 *)
ProfitR1[p1_, p2_] := (p1 - w)*D1[p1, p2]
ProfitR2[p1_, p2_] := (p2 - w)*D2[p1, p2]
在实际操作中,我发现将参数集中定义在代码开头非常有利于后续的灵敏度分析。当需要调整某个参数观察模型行为变化时,只需修改一处即可。
2.2 零售商均衡求解
两个零售商的定价决策构成一个非合作博弈,我们需要求解纳什均衡。在Mathematica中,这可以通过求解一阶条件方程组来实现:
mathematica复制(* 求解零售商价格竞争的纳什均衡 *)
equilibrium = Solve[{
D[ProfitR1[p1, p2], p1] == 0,
D[ProfitR2[p1, p2], p2] == 0
}, {p1, p2}]
(* 提取均衡解 *)
p1Star = p1 /. equilibrium[[1]]
p2Star = p2 /. equilibrium[[1]]
(* 计算均衡需求 *)
D1Star = D1[p1Star, p2Star]
D2Star = D2[p1Star, p2Star]
这里有一个重要的技术细节:当模型更复杂时(如需求函数非线性),直接使用Solve可能找不到解。这时可以尝试:
- 使用FindRoot进行数值求解
- 使用NMinimize寻找利润最大化点
- 采用迭代响应法模拟博弈过程
我在复现过程中发现,对于强非线性的模型,第三种方法往往最可靠,虽然计算量较大,但能更好地反映动态调整过程。
2.3 供应商决策优化
在零售商均衡确定后,供应商需要优化其批发价格w以最大化自身利润。这可以通过以下步骤实现:
mathematica复制(* 定义供应商利润函数 *)
ProfitS[w_] := Module[{
p1w, p2w, D1w, D2w
},
(* 给定w下求零售商均衡 *)
{p1w, p2w} = {p1, p2} /. FindRoot[{
D[ProfitR1[p1, p2, w], p1] == 0,
D[ProfitR2[p1, p2, w], p2] == 0
}, {{p1, w + 5}, {p2, w + 5}}];
D1w = D1[p1w, p2w];
D2w = D2[p1w, p2w];
(* 供应商利润 *)
(w - c)*(D1w + D2w) - hS*(D1w + D2w)/2 - KS
]
(* 寻找最优批发价格 *)
wOpt = w /. Last[NMaximize[{ProfitS[w], w > c}, w]]
注意:当供应商需要考虑库存策略时,模型会变得更加复杂。这时可能需要引入(Q,r)策略或定期盘点策略,并相应地调整利润函数。
3. 模型扩展与灵敏度分析
基础模型复现后,我们可以进行各种扩展分析来验证模型的稳健性和发现新的管理洞见。Mathematica的交互式可视化功能在这里特别有用。
3.1 竞争强度的影响分析
参数θ衡量了零售商之间的竞争强度。我们可以分析θ变化如何影响均衡结果:
mathematica复制(* 定义θ变化时的响应函数 *)
thetaAnalysis[thetaVal_] := Module[{
p1t, p2t, D1t, D2t, w = wOpt
},
{p1t, p2t} = {p1, p2} /. Solve[{
D[(p1 - w)*(a - b1*p1 + thetaVal*p2), p1] == 0,
D[(p2 - w)*(a - b2*p2 + thetaVal*p1), p2] == 0
}, {p1, p2}][[1]];
D1t = a - b1*p1t + thetaVal*p2t;
D2t = a - b2*p2t + thetaVal*p1t;
{p1t, p2t, D1t, D2t, (p1t - w)*D1t + (p2t - w)*D2t}
]
(* 绘制竞争强度影响图 *)
thetaRange = Range[0, 1, 0.1];
results = thetaAnalysis /@ thetaRange;
ListLinePlot[{
Transpose[{thetaRange, results[[All, 1]]}],
Transpose[{thetaRange, results[[All, 2]]}]
}, PlotLegends -> {"p1", "p2"}]
从我的实验结果来看,随着θ增大(竞争加剧),零售价格会先下降后趋于平稳,而零售商利润则持续下降。这表明适度的竞争有利于消费者,但过度竞争会损害整个零售渠道。
3.2 供应链协调机制设计
基础模型通常假设供应链成员独立决策,这会导致"双重边际化"效应,降低整体效率。我们可以用Mathematica评估不同协调机制的效果:
- 数量折扣契约:
供应商对大批量订单提供价格折扣
mathematica复制(* 数量折扣定价策略 *)
wDiscount[q_] := If[q > q0, w1, w2] (* 阶梯折扣 *)
(* 修改零售商利润函数 *)
ProfitR1Discount[p1_, p2_, q1_] :=
(p1 - wDiscount[q1])*D1[p1,p2] - hR*q1/2 - KR
- 收益共享契约:
零售商将部分销售收入返还给供应商
mathematica复制(* 收益共享契约 *)
ProfitR1RS[p1_, p2_] :=
(phi*p1 - w)*D1[p1,p2] (* phi是零售商保留比例 *)
ProfitSRS = (1-phi)*(p1*D1 + p2*D2) + w*(D1+D2) - c*(D1+D2)
通过比较不同契约下的供应链总利润,可以找到能够实现供应链协调的最优契约参数。在我的复现中,发现收益共享契约在大多数参数设置下都能很好地协调供应链,但需要精确调整phi值。
4. 复现过程中的挑战与解决方案
在复现这篇供应链论文的过程中,我遇到了几个典型的挑战,这里分享我的解决经验,供同行参考。
4.1 非线性方程求解不稳定
当模型包含非线性需求函数时,直接使用Solve可能失败。我的解决方案是:
- 提供良好的初始值
- 使用FindRoot替代Solve
- 实现迭代响应算法模拟实际决策过程
mathematica复制(* 迭代响应算法实现 *)
iterativeResponse[w_, init1_, init2_, n_] := Module[{
p1 = init1, p2 = init2
},
Do[
p1 = p1 /. FindMaximum[ProfitR1[p, p2, w], p][[2]];
p2 = p2 /. FindMaximum[ProfitR2[p1, p, w], p][[2]];
, {n}];
{p1, p2}
]
4.2 高维参数空间探索困难
当模型参数较多时,全面探索参数空间变得困难。我采用的方法是:
- 使用Manipulate创建交互式可视化
- 设计正交实验减少参数组合
- 实现自动参数扫描脚本
mathematica复制(* 交互式参数探索 *)
Manipulate[
Module[{p1, p2},
{p1, p2} = iterativeResponse[w, 20, 20, 10];
BarChart[{p1, p2}, ChartLabels -> {"p1", "p2"}]
],
{{w, 15}, 10, 20}, {{theta, 0.5}, 0, 1}
]
4.3 模型验证与稳健性测试
为确保复现结果的正确性,我采用了以下验证策略:
- 极限测试:将θ设为0,检查是否退化为两个独立垄断市场
- 对称性测试:当b1=b2时,p1和p2应该相等
- 文献对比:与论文中的数值例子进行比对
mathematica复制(* 对称性测试 *)
symmetryTest = Solve[{
D[(p1 - w)*(a - b*p1 + theta*p2), p1] == 0,
D[(p2 - w)*(a - b*p2 + theta*p1), p2] == 0
}, {p1, p2}];
(* 验证p1 == p2 *)
Simplify[p1 - p2 /. symmetryTest[[1]]]
通过这些测试,我发现了原论文中一处不太明显的假设条件,这解释了为什么我的初始结果与论文有微小差异。这种深度验证对于确保模型复现的准确性至关重要。
