Pyomo:如何在目标函数中添加启用设备的固定惩罚项
错误原因
你遇到的报错是因为Pyomo构建模型时处理的是符号变量,尚未进行求解赋值,无法直接在Python的if判断中使用Pyomo变量做布尔条件判断。这类带固定启用成本的逻辑需要用整数规划的标准建模方法实现。
解决方案:引入二元指示变量+大M约束
步骤如下:
- 新增一个二元域的变量
y_used,取值只能为0或1,1代表启用设备B,0代表不启用设备B - 增加绑定约束:
y <= M * y_used,其中M是设备B产量的理论最大值,本场景下需求最高为50,所以M取50即可。该约束可以保证:- 只要
y>0,y_used必须等于1 - 只要
y_used=0,y必须等于0
- 只要
- 目标函数中增加
300 * y_used项,实现启用B就加300固定惩罚的逻辑
修改后完整代码
from pyomo.environ import * model = ConcreteModel() model.x = Var(domain=NonNegativeReals) model.y = Var(domain=NonNegativeReals) # 新增二元指示变量 model.y_used = Var(domain=Binary) def production_cost(m): # 直接加固定惩罚项,y_used为1时自动加300 return 30*m.x + 40*m.y + 300 * m.y_used # 目标 model.mycost = Objective(rule=production_cost, sense=minimize) # 原有约束 model.demand = Constraint(expr = model.x + model.y >= 50) model.maxA = Constraint(expr = model.x <= 40) # 新增绑定约束,M取50即可 model.y_bind = Constraint(expr = model.y <= 50 * model.y_used) # 求解(glpk支持整数规划,无需更换求解器) results = SolverFactory('glpk').solve(model) # 输出结果 print('Cost=', model.mycost()) print('x=', model.x()) print('y=', model.y()) print('是否启用设备B:', '是' if model.y_used() ==1 else '否')
运行结果
本场景下因为设备A最多只能生产40件,必须启用设备B生产剩余的10件,所以最终结果为:
Cost= 1900.0 x= 40.0 y= 10.0 是否启用设备B: 是
如果后续调整设备A的最大产能到大于等于50,求解器会自动对比“启用B生产部分+付300固定成本”和“全用A生产”的总成本,选择更优方案。
内容的提问来源于stack exchange,提问作者Hookstark
相关产品推荐
相关产品推荐

