
简介这份资源面向供应链管理领域的研究人员、政策制定者及循环经济与绿色供应链从业者围绕政府补贴下闭环供应链的定价与回收决策展开基于Stackelberg博弈模型分别构建无补贴、补贴制造商、补贴零售商三种场景探讨产品竞争、回收努力与补贴模式对定价和成员利润的影响。压缩包共1个文件为687KB的PDF文档内含完整论文复现内容包括需求函数、回收量函数、利润函数与Stackelberg博弈求解的Python代码及逐段解释便于读者对照理论推导复现数值模拟。已有72人学习下载。读者可从中获取三种补贴场景的建模思路、均衡求解流程与代码实现方法理解零售商关注产品竞争程度、制造商提高回收努力实现双赢、补贴零售商使双方共同受益等结论并借助文中指出的模型局限与改进建议为政府补贴政策制定、企业定价与回收策略优化及后续学术研究提供可复用的分析工具与实证参考。1. 政府补贴下闭环供应链定价决策一个三主体博弈问题到底难在哪很多做供应链优化的朋友第一次接触“政府补贴下闭环供应链定价决策”时会下意识把它当成一个普通的利润最大化问题把成本、售价、回收率列出来求个导解个方程就完事。真正动手才会发现这里面的坑远比想象中多。政府给补贴制造商和零售商各有各的算盘回收商还要从中分一杯羹三方在一条链上互相牵制任何一方的定价变动都会通过需求函数传导到另外两方的利润表上。Stackelberg博弈模型就是用来刻画这种“有人先出牌、有人后跟进”的决策结构的。谁做领导者、谁做跟随者直接决定了均衡解的形态和补贴政策的实际效果。这篇文章面向的是想用Python把这类模型跑通、拿到可复现数值结果的人——不管你是写论文需要数值仿真还是做企业决策想评估补贴退坡的影响下面的内容都能直接抄作业。2. Stackelberg博弈与闭环供应链建模前必须想清楚的五件事2.1 为什么是Stackelberg而不是Nash闭环供应链里的决策顺序天然不对称。制造商通常先定批发价和回收率零售商看到批发价之后再定零售价回收商根据回收价决定回收努力。这种“先动优势”结构就是典型的Stackelberg博弈。如果硬套Nash博弈等于假设所有决策者同时出牌在现实中几乎不成立解出来的均衡价格也会偏离实际。常见做法是把制造商设为领导者零售商和回收商设为跟随者。政府作为外部参与者通过补贴参数影响制造商的回收激励但不直接参与定价博弈。这个设定在多数闭环供应链文献里是标准配置也是我一般会优先采用的框架。2.2 闭环供应链的三种回收渠道结构回收渠道的选择直接改变博弈的参与者数量和利润分配方式。常见的有三种渠道模式回收主体博弈结构适用场景制造商回收制造商自己二层博弈制造商有回收技术优势零售商回收零售商二层博弈零售商离消费者近第三方回收独立回收商三层博弈专业化分工场景标题里提到的“回收策略分析”通常覆盖这三种模式的对比。我建议先把制造商回收跑通再扩展到第三方回收因为三层博弈的求解复杂度会明显上升。2.3 需求函数与回收函数的参数化需求函数一般设为线性形式D(p) a - bp其中a是市场潜在需求b是价格敏感系数。回收函数设为回收量R(τ) kττ是回收率k是回收规模系数。这两个函数的参数取值直接决定均衡解是否存在、是否唯一。参数设置的经验法则a取100到500之间b取1到5之间k取0.3到0.8之间。如果b太大需求对价格过于敏感均衡价格会被压得很低利润趋近于零如果k太小回收量上不去补贴的激励效果看不出来。2.4 政府补贴的两种介入方式政府补贴可以按回收量补也可以按回收率补。按回收量补时补贴总额 s * R(τ)s是单位回收补贴。按回收率补时补贴总额 s * τ。两种方式对制造商回收激励的边际影响不同前者直接降低回收的边际成本后者相当于给回收率一个固定加成。我一般会先跑按回收量补贴的版本因为它的经济学含义更清晰——每多回收一单位产品政府承担s的成本。按回收率补贴更适合政策评估场景比如“补贴率从10%提高到20%对回收率的影响”。2.5 逆向归纳法的求解逻辑Stackelberg博弈的标准解法是逆向归纳先求跟随者的最优反应函数再代回领导者的利润函数求最优决策。具体到闭环供应链第一步零售商根据制造商给定的批发价w求使自身利润最大化的零售价p。对π_r (p - w) * (a - bp)求导令导数为零得到p (a bw) / (2*b)。第二步回收商根据制造商给定的回收价求最优回收率。如果回收商是跟随者其利润函数为π_c (回收价 - 回收成本) * k*τ对τ求导得到最优反应。第三步把跟随者的反应函数代入制造商的利润函数求w和τ的最优值。制造商的利润 (w - c) * D(p) (回收收益 - 回收成本 补贴) * R(τ)。这个求解过程用手算推导公式很繁琐但用Python的符号计算库SymPy可以自动化完成。3. 用Python跑通三层Stackelberg博弈的最小实现3.1 环境准备与依赖安装先确保Python环境可用。如果你还没装Python去官网下载3.10以上版本安装时勾选“Add Python to PATH”。装好之后打开终端执行pip install sympy numpy matplotlib scipySymPy用于符号推导NumPy用于数值计算Matplotlib用于画图SciPy用于数值求解和优化。这四个库足够覆盖从推导到可视化的全流程。提示如果你用的是Anaconda上述库已经预装跳过这步即可。3.2 用SymPy推导均衡解的符号表达式先定义符号变量和利润函数然后用逆向归纳法逐步求解。以下代码以制造商回收模式为例import sympy as sp # 定义符号变量 p, w, tau, s sp.symbols(p w tau s, positiveTrue) a, b, c, k, c_r sp.symbols(a b c k c_r, positiveTrue) # 需求函数 D a - b * p # 零售商利润函数 pi_r (p - w) * D # 零售商最优反应对p求导令导数为零 p_star sp.solve(sp.diff(pi_r, p), p)[0] print(零售商最优零售价 p* , p_star) # 制造商利润函数含政府补贴s回收成本c_r # 回收量 R k * tau R k * tau pi_m (w - c) * (a - b * p_star) (s - c_r) * R - (1/2) * tau**2 * k # 对w和tau求偏导令导数为零 dw sp.diff(pi_m, w) dtau sp.diff(pi_m, tau) sol sp.solve([dw, dtau], [w, tau]) print(制造商最优批发价 w* , sp.simplify(sol[w])) print(制造商最优回收率 tau* , sp.simplify(sol[tau]))这段代码的核心逻辑是先对零售商利润求导得到p关于w的反应函数再代回制造商利润对w和tau分别求偏导联立求解。注意回收成本项我用了(1/2)tau^2k这是常见的二次回收成本假设表示回收难度随回收率上升而递增。如果你用的是一次成本函数把这一项改成c_r * k * tau即可。参数说明a是市场潜在需求b是价格敏感系数c是制造商单位生产成本k是回收规模系数c_r是单位回收成本s是政府单位补贴。这些符号在后续数值仿真中会被替换成具体数字。3.3 代入数值求解均衡结果符号解拿到之后代入具体参数值算数值import numpy as np # 参数赋值 params {a: 200, b: 2, c: 10, k: 0.5, c_r: 5, s: 8} # 计算均衡解 w_val float(sol[w].subs(params)) tau_val float(sol[tau].subs(params)) p_val float(p_star.subs({w: w_val, **params})) # 计算各方利润 D_val float((a - b * p).subs({p: p_val, **params})) R_val float((k * tau).subs({tau: tau_val, **params})) pi_r_val (p_val - w_val) * D_val pi_m_val (w_val - params[c]) * D_val (params[s] - params[c_r]) * R_val - 0.5 * tau_val**2 * params[k] print(f均衡批发价 w* {w_val:.2f}) print(f均衡零售价 p* {p_val:.2f}) print(f均衡回收率 tau* {tau_val:.4f}) print(f市场需求 D {D_val:.2f}) print(f回收量 R {R_val:.4f}) print(f零售商利润 {pi_r_val:.2f}) print(f制造商利润 {pi_m_val:.2f})跑完这段代码你会得到一组具体的均衡价格和利润值。如果tau_val出现负数说明参数设置有问题——要么补贴s太低要么回收成本c_r太高制造商没有回收动力。这时候需要调整参数重新跑。3.4 补贴系数对均衡结果的敏感性分析单跑一组参数看不出补贴的效果需要做敏感性分析。下面代码扫描s从0到20的变化import matplotlib.pyplot as plt s_range np.linspace(0, 20, 50) w_list, p_list, tau_list, pi_m_list [], [], [], [] for s_val in s_range: params_s {a: 200, b: 2, c: 10, k: 0.5, c_r: 5, s: s_val} w_v float(sol[w].subs(params_s)) tau_v float(sol[tau].subs(params_s)) p_v float(p_star.subs({w: w_v, **params_s})) D_v float((a - b * p).subs({p: p_v, **params_s})) R_v float((k * tau).subs({tau: tau_v, **params_s})) pi_m_v (w_v - 10) * D_v (s_val - 5) * R_v - 0.5 * tau_v**2 * 0.5 w_list.append(w_v) p_list.append(p_v) tau_list.append(tau_v) pi_m_list.append(pi_m_v) fig, axes plt.subplots(2, 2, figsize(12, 8)) axes[0, 0].plot(s_range, w_list); axes[0, 0].set_title(批发价 w* vs 补贴 s) axes[0, 1].plot(s_range, p_list); axes[0, 1].set_title(零售价 p* vs 补贴 s) axes[1, 0].plot(s_range, tau_list); axes[1, 0].set_title(回收率 tau* vs 补贴 s) axes[1, 1].plot(s_range, pi_m_list); axes[1, 1].set_title(制造商利润 vs 补贴 s) plt.tight_layout() plt.savefig(sensitivity.png, dpi150) plt.show()这段代码会生成四张子图分别展示批发价、零售价、回收率和制造商利润随补贴系数的变化趋势。典型结果是随着s增大回收率单调上升批发价可能先降后升因为补贴改变了制造商的回收收益结构零售价变化不大制造商利润先增后减补贴过高时政府支出效率下降。注意如果你的结果里回收率对补贴不敏感检查k值是否太小。k0.5时回收规模有限补贴的边际效果会被稀释。4. 三种回收渠道的对比实现与结果解读4.1 零售商回收模式的代码改动点零售商回收时回收决策由零售商做出制造商只定批发价。零售商利润变为# 零售商利润 销售利润 回收利润 pi_r_retail (p - w) * (a - b * p) (s - c_r) * k * tau - 0.5 * tau**2 * k # 对p和tau分别求导 p_star_r sp.solve(sp.diff(pi_r_retail, p), p)[0] tau_star_r sp.solve(sp.diff(pi_r_retail, tau), tau)[0]零售商同时决策零售价和回收率两个一阶条件联立求解。制造商的利润函数里不再包含回收项只保留销售利润。这种模式下零售商的谈判力更强但回收效率通常低于制造商回收因为零售商的主业是销售回收只是附带业务。4.2 第三方回收模式的求解框架第三方回收商独立决策回收率利润函数为pi_c (回收价 - c_r) * k * tau - 0.5 * tau**2 * k回收价由制造商支付给回收商设为b_r。回收商对tau求导得到最优反应函数代回制造商利润。制造商同时决策w和b_r。这是三层博弈求解步骤比前两种多一层但SymPy的处理方式完全一样——逐层求导、逐层代入。4.3 三种模式的利润对比表跑完三种模式后把结果整理成对比表指标制造商回收零售商回收第三方回收批发价中等最高最低零售价最低最高中等回收率最高中等最低制造商利润最高中等最低零售商利润最低最高中等社会总福利最高中等最低这个结论在多数参数设置下成立但并非绝对。当回收成本c_r很高时制造商回收的优势会被削弱第三方回收可能因为专业化分工而反超。所以每次换参数都要重新跑对比不能直接套结论。5. 避坑与排查跑闭环供应链模型时最容易翻车的五个地方5.1 均衡解出现负值现象tau算出负数或者p小于w*。原因参数设置不合理。最常见的是补贴s太低而回收成本c_r太高制造商回收一单位亏一单位理性选择是不回收。另一个可能是b太大需求对价格极度敏感均衡价格被压到成本线以下。解决先检查s和c_r的大小关系确保s c_r。如果s略大于c_r但tau仍为负把k调大让回收规模效应覆盖固定成本。b的值控制在1到5之间超过5时需求函数需要重新标定。5.2 SymPy求解返回空列表现象sp.solve()返回[]说明方程无解或SymPy没找到解析解。原因利润函数形式太复杂或者一阶条件是非线性方程组SymPy的符号求解器处理不了。解决先用sp.simplify()化简利润函数去掉冗余项。如果仍然无解改用数值求解用scipy.optimize.fsolve对一阶条件做数值求根。数值求解不依赖解析解存在性适用性更广。5.3 敏感性分析曲线不光滑现象画出来的曲线有锯齿或跳变。原因数值求解时初值选取不当fsolve收敛到了局部解而非全局解。或者参数扫描步长太大漏掉了中间的变化。解决把步长从50点增加到200点给fsolve提供上一轮的解作为初值。如果曲线仍然跳变检查利润函数是否在某些参数区间内非凹——非凹利润函数的一阶条件可能有多个根。5.4 补贴效果与直觉相反现象补贴增加回收率反而下降。原因补贴改变了制造商的定价激励。补贴按回收量发放时制造商可能通过提高批发价来攫取补贴收益导致零售价上升、需求下降、回收量随之下降。这种“补贴悖论”在参数不当时确实会出现。解决检查补贴的传导机制。如果补贴直接给制造商制造商不一定把补贴让渡给消费者。可以尝试把补贴改为直接给回收方或者设置补贴上限避免制造商过度攫取。5.5 三种回收模式的代码复制出错现象跑零售商回收模式时结果和制造商回收一模一样。原因复制代码后忘记修改利润函数中的决策变量。零售商回收时tau由零售商决策制造商利润里不应该再出现tau的一阶条件。解决每次切换模式时重新检查三个利润函数的决策变量归属。制造商回收制造商决策w和tau零售商回收制造商决策w零售商决策p和tau第三方回收制造商决策w和b_r零售商决策p回收商决策tau。决策权归属错了结果必然不对。6. 从均衡解到政策建议一个被忽略的验证技巧跑完模型拿到均衡解之后很多人直接开始写结论。但有一个验证步骤经常被跳过检查均衡解是否满足二阶条件。一阶条件只保证导数为零不保证是最大值。如果二阶导大于零你求出来的其实是利润最小点。验证方法很简单对每个决策变量求二阶偏导确认在均衡解处二阶导小于零。以制造商利润对w的二阶导为例# 验证二阶条件 d2w sp.diff(pi_m, w, 2) d2tau sp.diff(pi_m, tau, 2) print(d2pi/dw2 , d2w) print(d2pi/dtau2 , d2tau) # 代入均衡解检查符号 d2w_val float(d2w.subs({**sol, **params})) d2tau_val float(d2tau.subs({**sol, **params})) print(f在均衡解处 d2pi/dw2 {d2w_val:.4f}, d2pi/dtau2 {d2tau_val:.4f})如果两个值都小于零说明均衡解是极大值点结果可信。如果有一个大于零说明利润函数在该点附近非凹需要重新检查模型设定——可能是成本函数形式不对或者需求函数参数超出了合理范围。这个习惯是我踩过坑之后养成的。早期跑模型时只看一阶条件结果有一次论文写到一半发现均衡解是鞍点所有数值结果全部作废只能从头推导。从那以后每次拿到均衡解第一件事就是验证二阶条件花不了两分钟但能省掉几天返工。另一个实用技巧是把均衡解代回原利润函数和数值优化库比如scipy.optimize.minimize的结果做交叉验证。符号推导和数值优化两条路走出来的结果一致基本可以排除推导错误。如果两者不一致优先信数值优化——符号推导容易在化简步骤出错数值优化虽然可能陷入局部解但至少不会犯代数错误。希望这些能帮到你。本文还有配套的精品资源点击获取