如何在 Pyomo - 混合整数线性程序中建立正确的链接约束?
How to build a correct linking constraint in Pyomo - Mixed Integer Linear program?
上下文:我正在做一项作业,我正在使用 Pyomo 来学习这个框架。
这是作业:
从这个问题中,我明白我应该引入一个二元变量来触发固定成本约束。
这是我的实现:
from pyomo.environ import *
VERY_LARGE_NUMBER = 1e8
def part_4_april(data, limit_ballons, limit_labor):
model = ConcreteModel()
PACKAGES = data.keys()
model.x = Var(PACKAGES, within=NonNegativeReals)
model.y = Var(PACKAGES, within=Binary)
model.profit = Objective(
expr=sum(
(
(data[p]["price"] - data[p]["cost"]) * model.x[p]
- data[p]["fixed_cost"] * model.y[p]
)
for p in PACKAGES
),
sense=maximize,
)
model.ballon_cst = Constraint(
expr=sum(data[p]["ballons"] * model.x[p] for p in PACKAGES) <= limit_ballons
)
model.labor_cst = Constraint(
expr=sum(data[p]["labor"] * model.x[p] for p in PACKAGES) <= limit_labor
)
model.fixed_cost_cst = Constraint(
expr=sum(model.x[p] - VERY_LARGE_NUMBER * model.y[p] for p in PACKAGES) <= 0
)
opt = SolverFactory("cbc")
results = opt.solve(model, tee=True)
model.pprint()
return model
if __name__ == "__main__":
# part 4
data = {
"Standard": {"labor": 3, "ballons": 2, "cost": 2, "price": 3, "fixed_cost": 10},
"Joyful": {"labor": 5, "ballons": 5, "cost": 3, "price": 5, "fixed_cost": 5},
"Fabulous": {"labor": 8, "ballons": 8, "cost": 4, "price": 7, "fixed_cost": 1},
}
model = part_4_april(data, limit_ballons=360, limit_labor=500)
print("----- PART 4: April -----")
print("Profit:", model.profit())
for c in data.keys():
print(" ", c, ":", model.x[c]())
代码没有产生预期的输出,相反,它必须产生以下输出:
# must produce :
# Profit: 188.0
# Standard : 140.0
# Joyful : 0.0
# Fabulous : 10.0
我的代码或我使用二进制变量的方式有问题吗?
根据 Bethany Nicholson 和 Erwin Kalvelangen 的评论,我终于找到了解决方案 - 我的代码存在两个问题。首先,固定成本不得包含 sum
并且应单独应用于所有包
# NOT...
# model.fixed_cost_cst = Constraint(
# expr=sum(model.x[p] - VERY_LARGE_NUMBER * model.y[p] for p in PACKAGES) <= 0
# )
# must be applied to all packages individually
def fixed_cost_rule(model, p):
return model.x[p] - VERY_LARGE_NUMBER * model.y[p] <= 0
model.fixed_cost_cst = Constraint(PACKAGES, rule=fixed_cost_rule)
其次,结果必须是159而不是188。
上下文:我正在做一项作业,我正在使用 Pyomo 来学习这个框架。 这是作业:
从这个问题中,我明白我应该引入一个二元变量来触发固定成本约束。
这是我的实现:
from pyomo.environ import *
VERY_LARGE_NUMBER = 1e8
def part_4_april(data, limit_ballons, limit_labor):
model = ConcreteModel()
PACKAGES = data.keys()
model.x = Var(PACKAGES, within=NonNegativeReals)
model.y = Var(PACKAGES, within=Binary)
model.profit = Objective(
expr=sum(
(
(data[p]["price"] - data[p]["cost"]) * model.x[p]
- data[p]["fixed_cost"] * model.y[p]
)
for p in PACKAGES
),
sense=maximize,
)
model.ballon_cst = Constraint(
expr=sum(data[p]["ballons"] * model.x[p] for p in PACKAGES) <= limit_ballons
)
model.labor_cst = Constraint(
expr=sum(data[p]["labor"] * model.x[p] for p in PACKAGES) <= limit_labor
)
model.fixed_cost_cst = Constraint(
expr=sum(model.x[p] - VERY_LARGE_NUMBER * model.y[p] for p in PACKAGES) <= 0
)
opt = SolverFactory("cbc")
results = opt.solve(model, tee=True)
model.pprint()
return model
if __name__ == "__main__":
# part 4
data = {
"Standard": {"labor": 3, "ballons": 2, "cost": 2, "price": 3, "fixed_cost": 10},
"Joyful": {"labor": 5, "ballons": 5, "cost": 3, "price": 5, "fixed_cost": 5},
"Fabulous": {"labor": 8, "ballons": 8, "cost": 4, "price": 7, "fixed_cost": 1},
}
model = part_4_april(data, limit_ballons=360, limit_labor=500)
print("----- PART 4: April -----")
print("Profit:", model.profit())
for c in data.keys():
print(" ", c, ":", model.x[c]())
代码没有产生预期的输出,相反,它必须产生以下输出:
# must produce :
# Profit: 188.0
# Standard : 140.0
# Joyful : 0.0
# Fabulous : 10.0
我的代码或我使用二进制变量的方式有问题吗?
根据 Bethany Nicholson 和 Erwin Kalvelangen 的评论,我终于找到了解决方案 - 我的代码存在两个问题。首先,固定成本不得包含 sum
并且应单独应用于所有包
# NOT...
# model.fixed_cost_cst = Constraint(
# expr=sum(model.x[p] - VERY_LARGE_NUMBER * model.y[p] for p in PACKAGES) <= 0
# )
# must be applied to all packages individually
def fixed_cost_rule(model, p):
return model.x[p] - VERY_LARGE_NUMBER * model.y[p] <= 0
model.fixed_cost_cst = Constraint(PACKAGES, rule=fixed_cost_rule)
其次,结果必须是159而不是188。