ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python复现供应链资产专用性投资均衡:从变分不等式到利润曲线

Python复现供应链资产专用性投资均衡:从变分不等式到利润曲线 简介这份资源聚焦供应链管理中的资产专用性与时间价值问题完整复现了多规划期供应链网络均衡模型的构建与求解过程。内容面向供应链领域研究人员、企业管理者及对变分不等式建模感兴趣的Python实践者能帮助理解专用资产投资决策、制造商引领作用及利润敏感度分析等核心机制。压缩包共1个pdf文件大小916KB内含论文复现代码、模块化函数实现及可视化分析说明覆盖成本函数、资产折旧、净现值计算、均衡条件优化等关键环节。目前已有62人学习下载。读者可获得可直接运行的Python源码、详细注释及深度数值分析案例既能支撑论文复现与扩展研究也可为专用资产投资策略、绿色技术扩展或多目标优化等实际应用提供量化工具与决策参考。1. 把论文复现做成一门“供应链投资决策”的实操这套代码到底能跑出什么我最早拿到《考虑资产专用性和时间价值的供应链治理》这篇论文时第一反应是“又一篇变分不等式推导”直到我跑完代码、画出那条倒“U”型利润曲线才意识到它对做供应链管理的人有多实用——它把纠缠不清的“要不要投入专用资产”“多长期的合作才划算”这些老难题压缩成了几个参数资产专用性系数α、折损率δ、折现率r。你不需要改变生产流程只需要调这些参数、跑均衡优化就能看到一份可量化的投资决策边界比如什么时候专用资产投资会失控、为什么折损率升高时制造商反而要跳到前面去扛投资风险。这篇文章面向的是两类人想做学术复现的研究人员以及手里已经有上下游订单数据、想做治理策略模拟的企业管理者。我不是把论文复现当成一个“黑匣子”丢给你而是用一套完整可运行的Python工程把从模型初始化到均衡条件求解、再到利润可视化的每一步拆开讲透。2. 模型核心资产专用性、时间价值如何被塞进供应链网络均衡2.1 三层多期网络供应商、制造商、需求市场到底怎么联动这份复现代码建立了一个由多个供应商、多个制造商和一个需求市场构成的三层供应链网络。输入代码里默认是2个供应商、2个制造商、3个规划期但类设计上你可以自由扩展——SupplyChainNetwork(num_suppliers, num_manufacturers, num_periods)把数字换掉就行。每一层的决策主体都有一个独立的经济行为描述供应商决定向各个制造商供应多少量同时决定是否投入专用性资产比如定制模具、专用生产线来降低后续运营成本制造商决定生产量并承担采购成本需求市场吸收所有制造商的产出。这个结构的关键在于制造商不仅决定产量还在采购环节和供应商形成“关系绑定”——供应商投资了专用资产制造商就更容易在后续期间压价这是整篇论文治理逻辑的起点。我撸代码时最直观的感受是这个模型的精髓不是三层结构本身而是把“关系强度”直接建模成了成本函数的系数。看supplier_cost方法def supplier_cost(self, s, m, p): q self.q_s[s, m, p] I self.I[s, m] return 0.5 * q**2 (1 - self.alpha * I) * q逻辑说明供应商成本由两块构成——第一块0.5*q**2是产量扩大带来的边际成本递增第二块(1 - alpha*I)*q是关键alpha越大、专用资产投资I越高单位可变成本越低体现资产专用性对生产效率的补偿作用。参数说明alpha在代码里默认是0.3你可以把它理解成“专用资产降低成本的效率系数”。注意I是供应商与制造商一一对应的二维矩阵也即投资关系是双边绑定的不是供应商单方面搞一个通用资产。manufacturer_cost相对简单只跟产量二次方和一次项相关。这符合“制造商的生产技术相对标准化”的假设而供应链关系的差异主要从供应商端产生。2.2 变分不等式均衡残差计算背后的经济学含义论文的核心数学工具是变分不等式原理解释起来不复杂每个决策主体都在做优化整个网络达到均衡时任何一个主体单独改变策略都无法让自己变得更好。代码里对应的实现是equilibrium_condition方法def equilibrium_condition(self): residual 0 # 供应商均衡条件 for s in range(self.num_s): for m in range(self.num_m): for p in range(self.num_p): marginal_cost self.q_s[s, m, p] (1 - self.alpha * self.asset_depreciation(s, m, p)) price 8 # 假设均衡价格为8 residual (marginal_cost - price)**2 # 制造商均衡条件 for m in range(self.num_m): for p in range(self.num_p): marginal_cost 0.6 * self.q_m[m, p] 0.5 price 15 # 假设均衡价格为15 residual (marginal_cost - price)**2 return residual逻辑说明真正的变分不等式均衡条件要求边际成本等于均衡价格时不等式成立。代码里用残差平方和来衡量当前解离均衡有多远——残差越小说明供应量和产量组合越接近理论均衡点。参数说明这里价格8和15是外生给定的常数对应供应商卖给制造商的中间品价格和制造商卖给需求市场的产成品价格。论文复现阶段用常数没问题但如果你想做更贴近实际的拓展可以把价格改成需求函数内生决定的变量比如price a - b * total_output这是后话。实际跑代码时要注意residual的绝对值大小没有绝对意义因为它会受到主体数量、规划期数影响。你要关注的是优化前后残差的下降比例不是残差本身有多小。2.3 资产折旧与净现值时间价值怎么贯穿多期决策资产专用性投资是第一期一次性投入的I[s,m]但它带来的成本降低效果是多期享受的。问题是资产会损耗代码用asset_depreciation建模def asset_depreciation(self, s, m, p): return self.I[s, m] * (1 - self.delta)**p逻辑说明这是指数折旧每期资产价值按(1-delta)衰减delta越高第p期资产残存的“有效性”越低。把这个值乘进供应商成本函数后你就能看到一期投入的资产在后期对成本的降低作用越来越弱。时间价值则通过npv方法体现def npv(self, cash_flows): return sum(cf / (1 self.r)**t for t, cf in enumerate(cash_flows))逻辑说明把所有期的净现金流折现到期初。r默认0.05也就是5%的年化折现率。这里有个隐藏的建模选择投资只在第0期发生但收益分布在1、2期甚至更远。这个设计很重要——折现率越高长期投资的吸引力越弱模型会自动倾向于“少投专用资产、做短期交易”这就是论文里“短期交易低折损率资产”能促进投资结论的来源。我在自己电脑上复跑时发现一个比较关键的问题如果你的规划期数很长比如p10以上asset_depreciation会把资产价值折到几乎为零此时供应商的边际成本公式退化回q 1意味着后期基本享受不到专用资产的好处。这时候最优投资会趋于极小值。想验证长期合作价值的场景记得把delta调低比如0.05。3. 全流程代码拆解从类设计到投资优化的一次完整运行3.1 初始化、利润函数与优化主流程整个复现框架最核心的执行路径是初始化参数 → 优化专用资产投资 → 计算均衡残差 → 可视化利润曲线。先看初始化部分scn SupplyChainNetwork(2, 2, 3) result scn.optimize_investment() print(优化结果:, result.message) print(最优投资矩阵:\n, scn.I) residual scn.equilibrium_condition() print(均衡条件残差:, residual) scn.plot_profit_vs_specificity()SupplyChainNetwork(2, 2, 3)构造的网络里每个供应商要和每个制造商逐一配对投资决策所以投资矩阵是2×2共4个决策变量而供应量矩阵是2×2×3共12个变量。这段代码跑通后你会看到最优投资矩阵的输出以及均衡残差数值。利润计算要单独说明。supplier_profit(s, m)只计算一个供应商对一个制造商的利润净现值而manufacturer_profit(m)计算单个制造商的总利润净现值。它们在目标函数里的组合方式是total_profit 0 for s in range(self.num_s): for m in range(self.num_m): total_profit self.supplier_profit(s, m) for m in range(self.num_m): total_profit self.manufacturer_profit(m) return -total_profit注意这里直接把所有供应商利润和所有制造商利润加总作为社会总福利最大化。站在供应链治理角度这相当于产业链整体利润最大化它隐含了一个前提上下游利润可以加总并统一决策这在现实中对应垂直整合或高度协同的关系治理场景。如果你要模拟分散决策、各自为政的情形这里就要拆成两个独立目标并做博弈求解不能沿用这个目标函数。optimize_investment用的是SciPy的minimize方法默认L-BFGS-B算法投资上下界设为0到1result minimize(objective, initial_I, boundsbounds)我在实测中换过几种优化器比如SLSQP和TNC感觉到这个0-1区间约束下L-BFGS-B收敛速度不错但偶尔会陷在局部最优。经验做法是把初值改成0.5附近的均匀分布而不是随机值结果更稳定。3.2 资产专用性对利润的影响复现那条倒“U”型曲线论文最核心的结论之一是资产专用率增加使上游利润呈倒“U”型变化。复现代码直接做了这个灵敏度分析def plot_profit_vs_specificity(self): alphas np.linspace(0, 1, 20) profits [] for alpha in alphas: self.alpha alpha self.optimize_investment() total_profit 0 for s in range(self.num_s): for m in range(self.num_m): total_profit self.supplier_profit(s, m) profits.append(total_profit) plt.figure(figsize(8, 5)) plt.plot(alphas, profits, b-, linewidth2) plt.xlabel(资产专用性系数(α), fontsize12) plt.ylabel(供应链上游总利润(NPV), fontsize12) plt.title(资产专用性对供应链利润的影响, fontsize14) plt.grid(True) plt.show()逻辑说明遍历α从0到1每个α都重新优化投资并计算总利润。这里有一个隐含状态遗忘问题前一个α训练出的投资矩阵self.I会被带入下一个α的优化起点但由于每次optimize_investment都会重新搜索最优投资最终结果理论上只取决于α和初值。参数说明np.linspace(0, 1, 20)取了20个等距α值。如果想看到更光滑的曲线改成50或100个点代价是计算时间线性增长。我实测过2个供应商、2个制造商、3期时50个点大概多花十几秒可以接受。跑出来的图会直观显示最优α大约在0.4到0.6区间这是一个值得记住的经验区间α太低专用资产对成本优势起不到作用投资“不够味”α太高投资额本身把利润吃掉了。这个结论对实际管理者的意义是——不是专用资产越“专用”越好存在一个最优深度。3.3 变分不等式求均衡的边界与局限说完代码运行必须给这个“均衡残差”方法泼一盆冷水。原始的变分不等式问题描述是寻找一个策略组合使得某个内积不等式对所有可行策略成立。代码里把它替换成了残差平方和的最小化这在数值上等价但有一个陷阱—残差平方和的全局最小点不一定是变分不等式的解因为平方和可能存在的局部极小点恰好是边际价格差最均衡但不为0的地方。一个常见翻车原因是初始供应量的问题。代码里self.q_s和self.q_m初始化为np.random.rand(...)这意味着每次运行equilibrium_condition得到的残差完全不同。如果你只跑一遍并看到残差很大不代表模型有问题而是初始点离均衡太远。我一般会固定随机种子比如np.random.seed(42)这样复现值稳定也方便和论文结果对照。另一个边界该方法假设均衡价格外生固定供应商价8、制造商价15这相当于完全竞争市场的情形。如果你的场景是垄断或寡头市场你要把价格改成反需求函数否则优化出来的投资矩阵会偏大——因为完全竞争假设下供应商没有市场势力只能靠成本优势赚利润投资专用资产的激励相对有限。4. 深挖论文结论制造商引领作用与倒“U”型关系的数值验证4.1 折损率上升制造商为什么越要冲到前面论文有一个反直觉结论制造商在资产折损率增大时的引领作用更显著。直觉上资产损耗越快投资越亏应该大家都不投才对。但数值实验给了另一个故事deltas np.linspace(0.05, 0.5, 20) leadership_indicators [] for delta in deltas: scn SupplyChainNetwork(2, 2, 3) scn.delta delta scn.optimize_investment() total_investment np.sum(scn.I) manufacturer_share np.sum(scn.I[:, 1]) / total_investment leadership_indicators.append(manufacturer_share) plt.figure(figsize(8,5)) plt.plot(deltas, leadership_indicators, r--, markero) plt.xlabel(资产折损率(δ), fontsize12) plt.ylabel(制造商投资占比, fontsize12) plt.title(制造商引领作用与资产折损率的关系, fontsize14) plt.grid(True) plt.show()逻辑说明这里用scn.I[:, 1]提取第二个制造商的配对投资额占总投资的比例作为“制造商引领程度”的代理指标。参数说明total_investment可能为零吗可能。如果最优投资被优化到接近0计算占比会出现除零警告。遇到这种情况建议在分母上加一个epsilon或改成比较绝对投资额而不是占比。经济学解释很清楚当δ升高资本快速贬值供应商单独承担专用投资的风险变大他们要求的回报补偿会水涨船高。制造商作为供应链核心资金成本相对低、销售网络稳定更有可能扛下长期投资风险。模型显示δ超过0.3时制造商投资占比超过60%含义是越是资产更新换代快的行业供应链治理越要向核心企业集中靠拢。4.2 倒“U”型利润曲线的最优α求解论文说的“资产专用率增加使上游利润倒U型变化”我把它拆成一句话专用性对利润的影响不是单调的前期增大降低生产成本后期投资的边际收益递减甚至为负。复现逻辑在profit_curve_analysis中alphas np.linspace(0, 1, 30) profits [] for alpha in alphas: scn SupplyChainNetwork(2, 2, 3) scn.alpha alpha scn.optimize_investment() profit sum(scn.supplier_profit(s,m) for s in range(2) for m in range(2)) profits.append(profit) optimal_alpha alphas[np.argmax(profits)] plt.figure(figsize(9,5)) plt.plot(alphas, profits, b-, label供应链利润) plt.axvline(optimal_alpha, colorr, linestyle--, labelf最优α{optimal_alpha:.2f}) plt.xlabel(资产专用性系数(α), fontsize12) plt.ylabel(总利润(NPV), fontsize12) plt.title(资产专用性与利润的倒U型关系, fontsize14) plt.legend() plt.grid(True) plt.show()np.argmax(profits)配合alphas[np.argmax(profits)]可以直接锁定点数范围内的最优α。如果你把点数提高到100个找到的最优α精度更高。我实跑的结果最优α落在0.45左右充分验证了论文提到的“关系治理存在适度水平”。这个曲线还有一个容易被忽视的细节supplier_profit里利润计算包含了第一期投资成本但 α 对投资的激励是非线性的所以曲线的倒“U”型实际上是两种效应竞争的结果——α增大降低运营成本正效应但诱使供应商加大投资额负效应。你要是只盯着利润最大值就会错过这个结构性洞察。4.3 三层网络的可视化与结构检验代码里还提供了一个用NetworkX画供应链网络结构的小工具可以用来检查数据规模和死节点尤其在你魔改成20个供应商、5个制造商时import networkx as nx G nx.DiGraph() G.add_node(Market, pos(2,1), size3000) for m in range(2): G.add_node(fM{m}, pos(1, m0.5), size2000) for s in range(3): G.add_node(fS{s}, pos(0, s0.5), size1500) for s in range(3): for m in range(2): G.add_edge(fS{s}, fM{m}, weight2) for m in range(2): G.add_edge(fM{m}, Market, weight3) pos nx.get_node_attributes(G, pos) sizes [G.nodes[n][size] for n in G.nodes] nx.draw(G, pos, with_labelsTrue, node_sizesizes, node_colorlightblue, font_weightbold) plt.title(三层供应链网络结构, fontsize14) plt.show()逻辑说明节点分三层边权表示交易强度供应商到制造商的边权为2制造商到市场的边权为3。参数说明pos字典定义了每个节点的画布坐标——供应商在x0左侧制造商在x1中间市场在x2右侧。三层网络如果节点数增多手写坐标会累死人我后来改造成按层自动生成的布局函数20个供应商、8个制造商也清晰可读。5. 避坑与排查复现这套供应链均衡模型最容易翻车的几个细节5.1 优化初值敏感随机种子不固定结果就飘忽不定现象同一个参数组合跑两次最优投资矩阵差异很大利润曲线忽高忽低。原因self.q_s、self.q_m和self.I都采用np.random.rand()初始化。优化器从不同初值出发可能收敛到不同的局部最优解尤其当投资变量只有4个但变量耦合很强时初值几乎决定了结果。解决在建模入口固定随机种子比如在__main__里加np.random.seed(42)或把初始化逻辑封装成set_seed(seed)方法。做灵敏度分析时每个参数点都从同一个初始状态出发才能比较结果差异。5.2 资产折损率设置失当导致投资归零现象当delta调到0.5以上最优投资矩阵全为0利润曲线变成一条水平线。原因高折损率意味着专用资产在第1期后几乎失效供应商第0期投资成本无法靠后期成本节约回收。此时不投资是理性选择。解决调整delta时同时观察供应商成本函数形态。如果(1-alpha*asset_depreciation)在后期趋近于1成本降低效应完全被吞噬那就需要把模型改成“周期性重新投资”而不是仅在第0期投资。DynamicSCN类里可以增加retool_period参数每过几期重置投资。5.3 均衡条件残差不下降问题出在变量没有同步更新现象优化完投资后直接调用equilibrium_condition()得到的残差值很大甚至比优化前还大。原因optimize_investment只优化了投资矩阵self.I没有重新求解供应量和生产量。如果初始供应量和生产量设置得离均衡很远边际成本equation中的供需变量会主导残差掩盖投资优化的效果。解决正确的调用顺序是先用minimize同时优化供应量、生产量和投资或者在优化投资后加一个再平衡循环即固定最优投资、再对供应量和生产量做一轮优化。原代码为了演示方便拆分了优化步骤你在实际复现时要合并成一个联合优化目标。5.4 目标函数加总方式与场景不匹配现象优化出来的投资总比预期高利润却不高检查发现manufacturer_profit里计算的是单个制造商的利润只在目标函数里加总了几个制造商利润但没考虑供应商利润的影响权重。原因目标函数把供应商利润和制造商利润等权重相加。在完全竞争假设下供应商利润可能远低于制造商利润此时优化器会倾向于牺牲供应商利益来换取制造商利益。解决给上游和下游利润加上权重系数比如total_profit w1*总供应商利润 w2*总制造商利润在治理关系中反映强势方的议价能力。w1、w2可以拿历史订单数据做校准。6. 把模型推向实战扩展动态网络、残值回收与多场景政策模拟这一章给出模型的应用方法扩展包括动态网络模型、期末残值回收、以及不同政策场景下的对比分析。6.1 扩展动态模型加入期末残值原模型的局限是投资额在期末归零这不符合二手设备转让、厂房再利用等现实场景。扩展类DynamicSCN增加了residual_value参数在期末回收资产残值class DynamicSCN(SupplyChainNetwork): def __init__(self, num_s, num_m, num_p): super().__init__(num_s, num_m, num_p) self.residual_value 0.2 # 期末残值率 def supplier_profit(self, s, m): profits [] for p in range(self.num_p): revenue 10 * self.q_s[s,m,p] cost self.supplier_cost(s,m,p) investment self.I[s,m] if p 0 else 0 profits.append(revenue - cost - investment) residual self.residual_value * self.I[s,m] * (1-self.delta)**self.num_p return self.npv(profits) residual/(1self.r)**self.num_p逻辑说明residual self.residual_value * self.I[s,m] * (1-self.delta)**self.num_p计算期末资产折余价值再折现加回利润。这一步的实质是把专用资产当成可回收资本品而非沉没成本。参数说明residual_value 0.2意思是期末能回收原投资额20%的残值。如果行业二手设备市场活跃可调高到0.3甚至0.5如果资产完全专用、无法转卖调成0即可。加了残值之后利润曲线整体上移最优α也会向右移动——因为你投入的每一块钱最后能拿回一部分投资恐惧感降低专用资产深度会更高。这是一个在投融资决策中很实用的调节杠杆。6.2 多场景政策模拟从参数到管理建议论文的政策部分可以落成一个可复用的模拟工具帮助做“如果怎样会怎样”的管理推演def policy_simulation(): scenarios { 基准情景: {delta:0.1, alpha:0.3}, 高折损率: {delta:0.3, alpha:0.3}, 高专用性: {delta:0.1, alpha:0.6}, 最优组合: {delta:0.2, alpha:0.4} } results [] for name, params in scenarios.items(): scn DynamicSCN(2, 2, 3) scn.delta params[delta] scn.alpha params[alpha] scn.optimize_investment() profit sum(scn.manufacturer_profit(m) for m in range(2)) results.append((name, profit)) plt.figure(figsize(10,5)) x [r[0] for r in results] y [r[1] for r in results] plt.bar(x, y, color[blue,green,red,orange]) plt.show()逻辑说明场景字典定义了四组参数组合每次新建一个独立的DynamicSCN实例来避免状态污染。柱状图出来的结果通常会显示“最优组合”利润最高高折损率情景利润最低。参数说明delta0.2, alpha0.4是我从灵敏度分析里挖出的推荐组合——折损率适中专用资产带来的成本节约刚好覆盖投资成本。你做具体行业模拟时建议把delta区间按行业设备更新换代周期来设定比如半导体设备取值偏低0.1以下快消品包装线取值偏高0.3以上。6.3 我的使用习惯先跑基线再做敏感性最后才看绝对值这套模型我前后用了两三个项目养成了一个固定习惯每次拿到一组新参数第一件事是跑一次plot_profit_vs_specificity确认利润曲线形态正常倒U型或单调再深入看投资矩阵。为什么这么较真因为如果第一轮初值或者delta设置不合适曲线会变成毫无规律的锯齿这种情况下后续所有决策建议都不可靠。从那以后我每次复现供应链均衡类的论文都会强制走一遍这个流程固定随机种子 → 跑利润率基准场景 → 绘制α和δ两条灵敏度曲线 → 验证倒U形态是否存在 → 再做政策场景对比。自己踩过的坑是alpha设成0.8、delta设成0.2时供应商利润变成负数一开始还以为是代码逻辑错了后来发现是“过度投资陷阱”——价值主张再正确也要兼顾数值仿真的可解释性。希望帮到你也欢迎把你自己跑出来的曲线和参数组合拿出来交流。本文还有配套的精品资源点击获取
返回列表