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.010.99 < model.x[m.p] < 1。但是在python中为一个变量定义两个区间是否可行?

如果有人有什么想法,请帮忙!

谢谢。

IpoptNon Linear Solver (NLP ) 而不是 Mixed Integer NLP (MINLP) 所以你的二进制变量...仅供参考,I Ipopt 表示 'Interior' 而不是 'Integer'.

现在,如果您真的需要 MINLP 求解器,可以使用 Bonmin 作为开源替代方案。但是,您的问题真的是非线性的吗?如果是的话,也许你可以尝试用分段线性函数来逼近非线性函数?