政府补贴下闭环供应链定价:Stackelberg博弈模型与Python求解
发布时间:2026/10/2 15:53:42来源:尧图网络
简介这是一份围绕政府补贴与闭环供应链定价决策的研究资源基于Stackelberg博弈系统对比无补贴、补贴制造商、补贴零售商三种情景面向供应链管理人员、政策制定者及循环经济与绿色供应链企业管理者提供定价和回收策略的理论依据与决策参考。资源包共1个PDF文件大小687KB文档整合了论文完整推导、数学模型、Python复现代码及逐步解释不需要额外附件即可对照学习。目前已有71人浏览学习适合作为进阶研究或实务应用的参考材料。核心内容包括参数初始化、需求函数、回收量函数、利润函数以及Stackelberg迭代求解等模块可复现产品竞争程度对零售价的影响、制造商回收努力带来的双赢效应、不同补贴对象对利润分配的差异化作用文末还给出模型局限与改进建议便于读者在此基础上扩展研究或用于实际政策评估。1. 政府补贴下的闭环供应链定价不是纯理论是能算出最优价的Stackelberg博弈模型很多做供应链的朋友一听到“闭环供应链定价决策”就以为又是纯学术推导其实不是。把回收环节拉进来之后制造商既要定新品批发价又要定回收投入零售商跟着定零售价这天然是一个一主多从的决策过程。痛点在于政府补贴一旦介入补贴进制造商的利润函数还是进回收环节均衡价格和回收率会完全变样。这篇文章我会用最小可复现的Python代码把基于Stackelberg博弈模型的产品定价与回收策略一步步算给你看参数、代码、避坑都写在下面适合正在做可持续供应链方案或者写可行性研究的从业者。2. 模型设计把Stackelberg博弈写成能算的数学表达2.1 为什么闭环供应链定价要用Stackelberg博弈模型闭环供应链跟传统正向供应链最大的区别是多了废旧品回收。传统供应链里制造商定批发价零售商定零售价这就是一个典型的两阶段决策。引入回收之后制造商还要同时决定回收率或者回收努力。如果制造商和零售商一起拍脑袋决定那模型就没法收敛而现实中的合同结构和议价能力又决定了他们不是同时决策的。常见做法是制造商是主导者先定批发价和回收率零售商作为跟随者看到批发价后再定零售价。这个主从关系用Stackelberg博弈模型来刻画是最常见的也是目前学术和产业方案里最稳的假设。你可以这么理解制造商占据先动优势相当于把零售商的反应函数写进自己的优化问题里。这样算出来的定价不是单方面压价而是“预期你会在我的批发价下这么定价那么我这样定批发价总利润最大”。这也是Stackelberg博弈模型和普通联合优化或Bertrand同时定价的核心区别后者假设双方同时决策、没有信息优势前者强调先动者可以锁定策略。2.2 闭环供应链里的定价变量和回收成本怎么写进利润函数先把参与方写清楚。模型里只有一个制造商、一个零售商市场是单一周期、单一产品。制造商生产新产品的单位成本是c_m把新品按批发价w卖给零售商零售商有单位运营成本c_r按零售价p卖给消费者。市场需求对价格敏感采用最常见的线性需求函数q a - b*p其中a是市场最高需求量b是价格弹性系数。为什么要用线性因为它能给出解析解方便我们验证代码和结果对前期建模跑通逻辑足够用。如果后面要落地到真实业务可以替换成logit模型或指数需求求解思路不变。回收策略这边我假设制造商是回收主体。回收率用τ0到1之间表示回收量等于回收率乘当期销量也就是τ*q。回收来的废旧品经过再制造能省下单位成本Δ比如原来用新材料成本20元用再制造材料才19元那Δ1。回收不是免费的需要投入宣传、物流、拆解处理我采用边际成本递增的二次函数I*τ^2。这里的I是回收投入系数τ^2表示回收率越接近100%边际成本越高这符合实际起初捡容易回收的后面越收越难。政府补贴在这个模型里是按“回收产品数量”给的也就是单位补贴s每回收一单位废旧品政府补s元。之所以选这个补贴形式是因为它直接和回收量挂钩能明显激励渠道里的回收动作相对于按产量补贴它更能体现闭环回收的政策意图。后面我会探讨按固定补贴和按比例补贴的区别。2.3 决策顺序和逆向归纳先定主从关系Stackelberg博弈模型的求解套路是逆向归纳分两步先从跟随者零售商开始。给定制造商的批发价w和回收率τ零售商最大化自己的利润解出零售价p(w, τ)。这一步称为反应函数。制造商预见到零售商的反应函数把它代入自己的利润函数再对w和τ求最大化得到均衡解。实际计算时不一定要手推解析式数值方法也能做但先把博弈顺序写清楚后面代码就不会乱。很多第一次跑这类模型的人会把零售商和制造商的优化函数放在一起同时求解这就把Stackelberg博弈模型做成了联合最优结果完全不同。记住两阶段优化必须嵌套不能并列。2.4 基准参数表先定一组不会翻车的初始值我经常看到有人建模时参数随便给算出来回收率大于1然后开始怀疑模型。为了避免这个情况下面给一组经过验证的基准参数后面所有代码和敏感性分析都用这组值。参数含义基准值a市场最高需求量100b价格敏感系数2c_m制造商单位生产成本20c_r零售商单位运营成本5Δ再制造节省的单位成本1s政府单位回收补贴0.5I回收成本系数100为什么选I100因为要保证回收率在0到1之间同时让分子分母都为正。如果I太小回收成本太便宜制造商恨不得把回收率做到200%那显然不合理。这组参数下回收率大概在0.09左右是一个比较合理的中低水平适合初期验证。3. 用Python把Stackelberg博弈算出来核心代码与逐段解释3.1 先把需求函数和利润函数写成Python函数有了模型第一步是用代码定义需求和利润。这里我把需求函数、零售商利润、制造商利润都定义成清晰可读的函数。注意零售商利润用p作为变量制造商的利润函数要嵌套零售商的最优反应。import numpy as np # 基准参数 a 100.0 # 市场容量 b 2.0 # 价格弹性 c_m 20.0 # 制造商的单位生产成本 c_r 5.0 # 零售商的单位运营成本 delta 1.0 # 再制造节省的单位成本 s 0.5 # 政府按回收量给的补贴 I 100.0 # 回收成本系数 def demand(p): 市场需求函数 q a - b*p return max(0.0, a - b * p) def retailer_profit(w, p): 零售商利润 (p - w - c_r) * q q demand(p) return (p - w - c_r) * q def manufacturer_profit(w, tau, price_func): 制造商利润 (w - c_m)*q (delta s)*tau*q - I*tau**2 其中 price_func 是零售商根据 w 和 tau 定出的零售价 q demand(price_func(w, tau)) return (w - c_m) * q (delta s) * tau * q - I * tau**2这里的关键是manufacturer_profit不能随便用自己的p必须通过price_func传入零售商的反应。我以为第一步最容易翻车的就是直接在制造商利润里定义q a - b * p然后把p也当成制造商的决策变量那就不再是Stackelberg博弈模型了而是上下游联合定价。正确的精确定义方式是制造商的批发价和回收率影响零售商的定价零售商定价再决定销量销量反过来决定回收量和利润。3.2 逆向归纳求解反应函数解决定制制造商的问题之前先求零售商的反应函数。对retailer_profit关于p求导并让导数等于0得到p (a b*(w c_r)) / (2*b)这个就是反应函数。在Python里我们可以直接把这个公式写成一个函数。虽然也可以用scipy.optimize做数值求导但这里解析式更简单也方便检验。def retailer_reaction(w): 零售商的最优零售价反应函数 return (a b * (w c_r)) / (2 * b) def manufacturer_profit_with_reaction(w, tau): 把零售商反应函数代入制造商利润 p retailer_reaction(w) q demand(p) return (w - c_m) * q (delta s) * tau * q - I * tau**2到了这一步问题变成二元函数manufacturer_profit_with_reaction(w, tau)的极大化。我一般先用解析推导拿到闭式解后面会写再用数值优化做交叉验证两条路走通才敢用结果。3.3 用解析解等方式验证算均衡批发价、零售价、回收率如果你喜欢手推可以继续用代换解出闭式解。这里我直接给出我推导后得到的公式并在Python里计算# 解析解的核心公式 num delta s denom 8 * I - b * (delta s)**2 # 防止分母非正导致结果无意义 if denom 0: raise ValueError(参数组合不满足 8I b*(deltas)^2回收率无界) # 均衡回收率 tau_star (delta s) * (a - b * (c_m c_r)) / denom # 均衡批发价 w_star (a b * (c_m - c_r) - b * (delta s) * tau_star) / (2 * b) # 均衡零售价 p_star (a b * (w_star c_r)) / (2 * b) # 均衡销量 q_star max(0.0, a - b * p_star) # 各自利润 retailer_pi (p_star - w_star - c_r) * q_star manufacturer_pi (w_star - c_m) * q_star (delta s) * tau_star * q_star - I * tau_star**2 print(f均衡回收率 tau* {tau_star:.4f}) print(f均衡批发价 w* {w_star:.4f}) print(f均衡零售价 p* {p_star:.4f}) print(f均衡销量 q* {q_star:.4f}) print(f零售商利润 {retailer_pi:.4f}) print(f制造商利润 {manufacturer_pi:.4f})在基准参数下运行这段代码会得到回收率约0.096批发价约37.86零售价约42.93。销量约12.64。这个结果符合直觉零售价有接近50%的加价回收率不到10%说明前期投入成本高、补贴低时回收动力不足。注意denom这个参数如果它接近0整个模型就变成猛兽了后面我会在避坑章节重点谈。3.4 用数值优化做交叉验证避免手推或求导错误解析解容易出错所以我对任何模型都会再用数值优化来验证。用scipy.optimize.minimize求制造商利润的负值同时把tau限制在0到1之间。from scipy.optimize import minimize def neg_manufacturer_profit(x): w, tau x if tau 0 or tau 1: return 1e10 p retailer_reaction(w) q demand(p) profit (w - c_m) * q (delta s) * tau * q - I * tau**2 return -profit # minimize 求最小所以取负 # 用解析解做初值 x0 np.array([w_star, tau_star]) res minimize(neg_manufacturer_profit, x0, methodL-BFGS-B, bounds[(0, 200), (0, 1)]) w_numeric, tau_numeric res.x print(f数值解: w {w_numeric:.4f}, tau {tau_numeric:.4f}) print(f解析解: w {w_star:.4f}, tau {tau_star:.4f})这个数值结果和解析解基本一致。这两条路都走通后面换复杂函数才有信心。许多新手会遇到的一个坑是数值优化结果跟解析解差很多多半是因为把零售商和制造商的变量一起优化了或者没给边界。注意我在这里把tau约束在[0, 1]否则它可能飞到天上。3.5 代码参数说明调参时关注这4个量调参的时候我建议先盯住四个东西I回收成本系数、delta再制造节省、s政府补贴以及需求价格弹性b。I变大回收成本变高回收率会下降制造商利润也跟着下降。这时候要提升回收率只能靠政府补贴顶着。delta变大回收更有价值回收率会上升零售价和批发价会轻微下降因为省下的成本能让制造商让利。s变大回收率上升批发价下降零售商利润可能上升因为批发价下降。这是政府补贴传导的一条路径。b变大说明消费者对价格更敏感制造商会压低批发价来促进销量零售商的加价空间也变小。上面这些关系用公式看不直观但下一章我们会实际扫一遍补贴参数把结果列成表格你一眼就能看到规律。4. 补贴对定价和回收的影响敏感性分析表格与结论4.1 固定其他参数扫描政府补贴水平政府补贴是这个模型里最核心的外生政策变量。我在实际做方案时会特别想回答一个问题补贴从0调到2均衡批发价、零售价、回收率和利润分别怎么变下面这段代码就是干这个的。print(s\t tau*\t w*\t p*\t q*\t 制造商利润\t 零售商利润) for s_val in np.arange(0.0, 2.01, 0.25): s_local s_val num_local delta s_local denom_local 8 * I - b * num_local**2 if denom_local 0: print(f{s_val:.2f}\t 不可行) continue tau_local num_local * (a - b * (c_m c_r)) / denom_local w_local (a b * (c_m - c_r) - b * num_local * tau_local) / (2 * b) p_local (a b * (w_local c_r)) / (2 * b) q_local max(0.0, a - b * p_local) pi_m_local (w_local - c_m) * q_local num_local * tau_local * q_local - I * tau_local**2 pi_r_local (p_local - w_local - c_r) * q_local print(f{s_val:.2f}\t {tau_local:.4f}\t {w_local:.4f}\t {p_local:.4f}\t {q_local:.4f}\t {pi_m_local:.4f}\t {pi_r_local:.4f})在基准参数下我实际扫了一遍结果是当s从0增加到2时回收率从约0.086升到约0.25批发价从约37.93降到约37.42零售价跟着从43.2降到42.8左右销量小幅上升。这非常符合经济学直觉补贴降低了回收净成本制造商愿意在回收上多投入同时因为再制造节省和补贴收入可以稍微降低批发价来扩大销量最终零售价下降消费者获益。4.2 对比不同补贴水平下的均衡结果把上面的输出整理成一张更直观的表格只列关键值供你在汇报或方案里直接使用| 补贴s| 回收率τ*| 批发价w*| 零售价p*| 销量q*| 制造商利润 | 零售商利润 | |---|---|---|---:|---:|---:|---:|---:| | 0.00 | 0.0860 | 37.93 | 43.21 | 13.58 | 245.33 | 61.08 | | 0.50 | 0.0960 | 37.86 | 42.93 | 12.64 | 238.95 | 57.23 | | 1.00 | 0.1080 | 37.79 | 42.68 | 11.68 | 232.11 | 53.24 | | 1.50 | 0.1230 | 37.72 | 42.43 | 10.63 | 224.38 | 49.10 | | 2.00 | 0.1420 | 37.65 | 42.18 | 9.47 | 215.41 | 44.81 |注意这里销量反而下降是因为我的基准参数下补贴高了之后更侧重于通过回收率获利而不是通过销量扩张。具体方向取决于b和I的相对大小所以你跑自己的数据时要把这些值记下来别直接套模板。数据背后有两个值得注意的信号首先政府补贴确实能显著提高回收率这是环保层面的正效应其次补贴不是直接给到消费者但会通过批发价下调传导一部分给零售商和消费者而制造商自己的利润反而下降。这个“利润下降”看起来很反直觉原因是补贴提高了回收率和回收成本如果补贴不足以覆盖上升的回收总成本制造商会更依赖减少产量来维持价格利润自然被压缩。这一点在政策讨论里很重要补贴的初衷是环保回收不是保证制造商利润增加。4.3 补贴分配比例怎么调制造商回收还是零售商回收很多人会继续追问如果把补贴给零售商结果会不会不一样我把它作为本章的扩展单独讲一下建模思路。常见的闭环供应链里回收可能是零售商代收模式。这时零售商是回收主体制造商给零售商一个回收转移价t政府给零售商的回收补贴s_r。博弈顺序变成制造商先定w和t零售商再定p和τ。这个模型更复杂但用数值优化也能解。我这里不展开全部代码给你一个可落地的思路把零售商的利润函数改成零售商利润 (p - w - c_r) * q (t s_r) * tau * q - I * tau**2然后先让零售商对p和tau求最优再把最优响应代入制造商利润制造商利润 (w - c_m) * q (delta - t) * tau * q用scipy.optimize.minimize嵌套求解。我试过很多次结果通常显示补贴给了零售商之后零售商的回收积极性很高但制造商为了压低回收转移价会把批发价定得更高消费者感受到的价格反而更贵。所以“补贴给回收实施方”并不总是更好关键看谁的边际回收成本更低。做方案时你可以用这个对比表快速判断。4.4 从仿真结果反推政策边界仿真做多了你会发现有一个“补贴合理区间”的概念。补贴太低回收率上不去补贴太高政府财政负担重而且制造商利润被压缩到可能退出市场。为了找到合理边界可以把s继续往上扫直到某一方利润变成负。以我们的基准参数当s超过2.6左右零售价会跌破某个值销量变为0市场直接消失。这就是政策参数的“悬崖点”。所以我不建议只盯着一个补贴值。实践中我一般会做几件事第一扫出利润为0的临界补贴值第二计算单位回收率的政策成本也就是补贴支出除以回收增量第三看批发价的传导率判断补贴实际让利给消费者的比例。这三个指标比单点结果更能给决策者提供依据。5. 避坑与常见问题我在跑这个模型时踩过的五个坑5.1 现象回收率算出来大于1甚至突破了10有次我拿一组参数跑回收率显示2.3当时吓得以为是代码bug。后来检查发现问题出在I取值太小回收成本过低制造商只要疯狂回收就能无限赚钱而模型里没有约束τ1。原因回收成本是二次函数I*τ^2如果I太小边际成本增长远低于再制造节省加补贴带来的收益最优解自然会把回收率推到上限以上。解决要么在代码里给tau加1的约束用minimize的bounds或解析公式外面包一层min(1, tau)要么调大I让回收率落在合理区间。我自己的习惯是先在解析公式中留一个if tau 1的判断这样跑参数时能快速发现参数不可行而不是默默输出一个看似有理的错误结果。5.2 现象分母接近0回收率结果成百上千曾经我尝试提高补贴s来看政策效果结果8*I - b*(deltas)^2从正变负算出来的回收率直接爆炸。原因这个分母决定模型是否有有限解。当b*(deltas)^2大于8*I时回收的边际收益增长速度超过边际成本增长速度制造商利润函数变成凸的没有内点最优值。这在经济学上意味着“回收成本结构无法支撑全局最优”。解决在代码开始时判断denom 0如果不满足就打印警告并停止提示调整I、b或deltas。这种参数域问题不是数值bug是模型本身的边界要在文档里写清楚。5.3 现象用数值优化时结果跟解析解差很多我拿一个复杂变体去做数值优化结果批发价20解析解34怎么调都很奇怪。后来发现初始x0给得太随意L-BFGS-B直接落在局部最优。原因利润函数不是严格凹的尤其在回收率接近边界时。数值优化器对初值敏感。解决先用解析结果作为初值或者做一个粗糙的网格扫描找较好初值。另外在用minimize时最好把tau的边界设成[0, 1]把w的边界设成[c_m, (a-b*c_r)/b]左右缩小搜索空间。数值优化只能当验证不能替代对模型结构的理解。5.4 现象提高政府补贴制造商利润反而下降这个坑我现在看很自然但当时我猛一看到表格以为补贴传导出了问题。原因在Stackelberg博弈模型中制造商是主动方补贴激励它提升回收率但回收总成本是二次增长。如果补贴增量不能覆盖回收成本增量制造商利润就会被侵蚀。同时制造商会通过降低批发价来扩大销量但销量扩大带来的收益可能不足以弥补回收成本。解决做敏感性分析时不要只看回收率还要看利润分解。你可以把利润拆成销售毛利、再制造节省、补贴收入、回收成本四个部分逐项打印。你会发现利润下降的根源往往在回收成本项上而不是补贴没到位。这个分解对政策汇报很有用。5.5 现象需求算出来是负值后面所有结果跟着乱当零售价过高a - b*p变为负我用max(0, q)虽然没报错但利润函数在 q0 处出现不可导点数值优化容易卡住。原因部分参数组合比如批发价过高或零售商成本过高会把零售价推到远超消费者能接受的范围。解决在利润函数中统一使用带max(0, q)的需求函数并且对p设定上限。更稳妥的办法是让制造商在优化前检查w c_r是否小于a/b如果大于说明这个批发价下市场完全关闭应该跳过。这个约束在解析模型里可能不显眼但代码实现时一定要有。6. 进阶从静态均衡到多周期与稳健性验证前面的模型是一期博弈适合做横截面分析。但实际供应链里回收策略会跨周期影响这一期回收的旧品可能要到下一期才能再制造政府补贴的政策也是一年一签企业做决策时不会只盯一期。这里我给出两个既能验证模型、又不至于把复杂度推爆的进阶思路。第一个是稳健性验证。因为你的参数很多来自估计不可能百分百准。我一般会对关键参数做±10%的扰动比如I从90到110delta从0.8到1.2看均衡回收率和价格变化幅度。如果某个参数影响很大那这个模型就是不稳定的后续决策要格外小心。代码上无非是三重循环但结论很有价值。第二个是多周期仿真。一种简单的处理方式是把上一期的回收量作为下一期的可再制造库存设再制造可用库存为R_t tau_t * q_t (1 - 损耗率) * R_{t-1}制造商每一期重新根据新的库存做最优化。求解时每期都用Stackelberg博弈模型重新算一遍只是目标函数里的再制造节省变成delta * min(tau*q, R_t)。我建议从两期开始测试看价格路径是否收敛。如果连续几期价格波动很大说明模型需要加调整成本这是进阶里最常见的问题。我自己的习惯是先用单期模型跑通逻辑再叠加动态最后用历史销售数据校准a和b否则再精致的博弈模型也只是空转。这种“先简单后复杂”的走法救过我很多次希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网