如何在scipy linprog中高效获取影子价格?
更快获取linprog不等式约束影子价格的方法
嘿,你完全没必要重复求解100次!scipy.optimize.linprog(method='simplex')本身就直接提供了你需要的影子价格(对偶变量),这能把你的求解时间从1小时压缩到单次求解的时长,效率提升不是一点半点。
直接从求解结果提取影子价格
当你用simplex方法完成求解后,返回的OptimizeResult对象里已经包含了所有约束的对偶变量信息:
- 对于不等式约束(对应
A_ub @ x <= b_ub形式),影子价格存储在res.ineqlin.dual属性中 - 注意符号问题:因为
linprog默认是最小化目标函数,而你是在求解最大化问题(从f_max_original的表述来看),所以需要对dual值取反,才能得到你需要的机会成本(影子价格)。
给你一个简单的代码示例参考:
from scipy.optimize import linprog # 把你的最大化问题转换为linprog要求的最小化形式:max c@x → min -c@x c = -your_objective_coeffs A_ub = your_inequality_constraints_matrix b_ub = your_inequality_constraints_rhs # 执行一次求解即可 res = linprog(c, A_ub=A_ub, b_ub=b_ub, method='simplex') # 提取对应原最大化问题的不等式约束影子价格 shadow_prices = -res.ineqlin.dual
这里shadow_prices的顺序和你输入的b_ub(不等式约束右侧值)顺序完全对应,你直接提取指定位置的100个值就可以了。
为什么这个方法靠谱?
影子价格的本质是:当约束右侧值变动1个单位时,目标函数最优值的变化量。linprog的simplex求解器在计算最优解的同时,已经同步算出了对偶问题的解,而对偶变量正好对应原问题约束的影子价格。取反是因为我们把最大化问题转成了最小化问题,符号需要对应回来。
你可以拿一个小规模测试案例验证:手动修改某个约束右侧值+1后重新求解,计算出的影子价格和直接提取的结果会完全一致,但只需要一次求解。
几点注意事项
- 只有
method='simplex'支持返回完整的对偶变量信息,其他方法(比如interior-point)不会返回ineqlin和eqlin属性。 - 确保你的约束矩阵
A_ub和右侧向量b_ub的顺序对应,影子价格的顺序和约束顺序是一一匹配的。 - 如果求解结果的
status不是0(表示最优解未找到),那对偶变量的值不可靠,需要先确保问题能得到有效最优解。
内容的提问来源于stack exchange,提问作者J63
相关产品推荐
相关产品推荐

