如何在Python pulp中实现基于决策变量的条件约束(if开关)
问题解答
问题1:pulp是否支持该类条件约束?
pulp完全可以实现这类基于决策变量的条件约束,这类约束可以通过整数规划经典的大M线性化方法转化为线性约束,不属于非线性问题,pulp的整数规划求解器完全支持求解。
问题2:报错原因
报错确实是代码编写逻辑错误导致的:
- 你调用
x_r.value()的时候模型还没有执行solve()方法,决策变量还没有被赋值,返回值是None,自然无法和整数1做大小比较 - Python原生的
if语句是在建模阶段执行的,而你需要的条件逻辑是求解阶段的约束,两者执行时机完全不同,不能混用Python原生条件判断来定义模型约束
问题3:正确实现方案
使用大M法实现你要求的「x≥1则y=1,x=0则y=0」的逻辑,步骤如下:
- 先确定决策变量x_r的理论上界M:根据你的约束,x_r最多可生产数量取两个约束的最小值:
- 牛奶约束下最大值:8000//150 ≈53
- 时长约束下最大值:360//5=72
因此取M=60即可(只要大于x_r的最大可能取值就行)
- 添加两个线性约束即可实现开关逻辑:
x_r <= M * y_r:如果y_r=0,那么x_r必须<=0,结合x_r非负约束,x_r只能等于0,实现x=0对应y=0x_r >= y_r:如果y_r=1,那么x_r必须>=1,实现x≥1对应y=1
修正后完整代码
import pulp problem = pulp.LpProblem('ice', pulp.LpMaximize) # 定义决策变量 x_e = pulp.LpVariable('x_e', lowBound=0, cat=pulp.LpInteger) x_r = pulp.LpVariable('x_r', lowBound=0, cat=pulp.LpInteger) y_r = pulp.LpVariable('y_r', lowBound=0, cat=pulp.LpBinary) # 目标函数 problem += 50*x_e + 10*x_r # 基础约束 problem += 100*x_e + 150*x_r <= 8000 problem += 7*x_e + 5*x_r <= 360 # 开关逻辑约束(大M法) M = 60 problem += x_r <= M * y_r problem += x_r >= y_r # 求解 problem.solve() # 输出结果 print("意式浓缩冰淇淋",x_e.value(), "份") print("覆盆子冰淇淋",x_r.value(), "份") print("总利润",pulp.value(problem.objective), "日元") print("开关变量y_r取值", y_r.value())
运行结果
意式浓缩冰淇淋 50.0 份 覆盆子冰淇淋 2.0 份 总利润 2520.0 日元 开关变量y_r取值 1.0
和你之前直接加x_r>=1约束的运行结果完全一致,实现了相同的逻辑。
内容的提问来源于stack exchange,提问作者icecat
相关产品推荐
相关产品推荐

