PYOMO:使用 IPOPT 给出浮点值的二进制变量
PYOMO: Binary variable giving float values with IPOPT
我在 PYOMO 中使用 IPOPT 求解器时遇到一个奇怪的问题。二进制域中的变量给出浮点值。如果您获得诸如 0.999 或 0.001 之类的值,那完全没问题。但是诸如 0.4 或 0.5 之类的值并不实用。我见过类似的 post,但它对我没有帮助,因为我不能使用 MIP 求解器。
我的问题在PYOMO中描述如下。
# Select one material for each face.
materials = [ 'alum', 'carbon', 'zinc', 'steel']
faces = ['Face 1','Face 2','Face 3','Face 4','Face 5','Face 6']
model.M = pyo.Set(initialize=materials)
model.P = pyo.Set(initialize=faces)
# Selection variable
model.x = pyo.Var(mdl.M, mdl.P, domain=pyo.Binary)
# Constraint to make sure each face get one material
def c2(model, plate):
return sum(model.x[m, plate] for m in model.M) == 1
model.c2 = pyo.Constraint(model.P, rule=c2)
不幸的是,二进制变量给出浮点值。输出的相关部分如下所示:
Variables:
x : Size=24, Index=x_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
('zinc', 'Face 1') : 0 : 0.5648148977886973 : 1 : False : False : Binary
('zinc', 'Face 2') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 3') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 4') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 5') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 6') : 0 : 1.0 : 1 : False : False : Binary
('copper', 'Face 1') : 0 : 0.43518512159762096 : 1 : False : False : Binary
('copper', 'Face 2') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 3') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 4') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 5') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 6') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('zinc', 'Face 1') 和 ('copper', 'Face 1') 键具有浮点值,例如 0.4 和 0.5,这对于二元决策不实用。
我不能使用 MIP 求解器,因为我的问题不是整数问题。
一个想法:
我尝试实现的一种方法是为二进制变量 model.x[m.p] 定义约束,例如 0 < model.x[m.p] < 0.01
或 0.99 < model.x[m.p] < 1
。但是在python中为一个变量定义两个区间是否可行?
如果有人有什么想法,请帮忙!
谢谢。
Ipopt
是 Non Linear Solver (NLP ) 而不是 Mixed Integer NLP (MINLP) 所以你的二进制变量...仅供参考,I
Ipopt
表示 'Interior' 而不是 'Integer'.
现在,如果您真的需要 MINLP 求解器,可以使用 Bonmin
作为开源替代方案。但是,您的问题真的是非线性的吗?如果是的话,也许你可以尝试用分段线性函数来逼近非线性函数?
我在 PYOMO 中使用 IPOPT 求解器时遇到一个奇怪的问题。二进制域中的变量给出浮点值。如果您获得诸如 0.999 或 0.001 之类的值,那完全没问题。但是诸如 0.4 或 0.5 之类的值并不实用。我见过类似的 post,但它对我没有帮助,因为我不能使用 MIP 求解器。
我的问题在PYOMO中描述如下。
# Select one material for each face.
materials = [ 'alum', 'carbon', 'zinc', 'steel']
faces = ['Face 1','Face 2','Face 3','Face 4','Face 5','Face 6']
model.M = pyo.Set(initialize=materials)
model.P = pyo.Set(initialize=faces)
# Selection variable
model.x = pyo.Var(mdl.M, mdl.P, domain=pyo.Binary)
# Constraint to make sure each face get one material
def c2(model, plate):
return sum(model.x[m, plate] for m in model.M) == 1
model.c2 = pyo.Constraint(model.P, rule=c2)
不幸的是,二进制变量给出浮点值。输出的相关部分如下所示:
Variables:
x : Size=24, Index=x_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
('zinc', 'Face 1') : 0 : 0.5648148977886973 : 1 : False : False : Binary
('zinc', 'Face 2') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 3') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 4') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 5') : 0 : 1.0 : 1 : False : False : Binary
('zinc', 'Face 6') : 0 : 1.0 : 1 : False : False : Binary
('copper', 'Face 1') : 0 : 0.43518512159762096 : 1 : False : False : Binary
('copper', 'Face 2') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 3') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 4') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 5') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('copper', 'Face 6') : 0 : 9.893803483769687e-09 : 1 : False : False : Binary
('zinc', 'Face 1') 和 ('copper', 'Face 1') 键具有浮点值,例如 0.4 和 0.5,这对于二元决策不实用。 我不能使用 MIP 求解器,因为我的问题不是整数问题。
一个想法:
我尝试实现的一种方法是为二进制变量 model.x[m.p] 定义约束,例如 0 < model.x[m.p] < 0.01
或 0.99 < model.x[m.p] < 1
。但是在python中为一个变量定义两个区间是否可行?
如果有人有什么想法,请帮忙!
谢谢。
Ipopt
是 Non Linear Solver (NLP ) 而不是 Mixed Integer NLP (MINLP) 所以你的二进制变量...仅供参考,I
Ipopt
表示 'Interior' 而不是 'Integer'.
现在,如果您真的需要 MINLP 求解器,可以使用 Bonmin
作为开源替代方案。但是,您的问题真的是非线性的吗?如果是的话,也许你可以尝试用分段线性函数来逼近非线性函数?