PAO.Pyomo 模型设置两个变量 x 和 y 是唯一的

问题描述 投票:0回答:1

背景是我正在尝试使用基于Python的对抗性优化包(PAO)来实现双层优化程序,该程序基于Pyomo。我是 Pyomo 的新手,尽管我之前使用过许多求解器,例如 Gurobi 和 Cplex。为了求解双层优化程序,我需要使用 pao.pyomo.MIBS 求解器。然而,我发现我的 Pyomo 程序甚至无法正确解决幼稚的不平等约束

z[0] != z[1]
。我的代码如下,它试图将值分配给满足约束
z[0], z[1] \in {0, 1}
z[0] != z[1]

import pyomo.environ as pyo
from pyomo.environ import *
from pao.pyomo import *

N = 2
M=1024

model = ConcreteModel()
model.z = Var(range(N), domain=Integers)
for i in range(N):
    model.z[i].setlb(0)
    model.z[i].setub(N-1)

model.delta = Var(range(N), range(N), domain=Binary)

model.unique_z = ConstraintList()
for i in range(N):
    for j in range(i+1, N):
        model.unique_z.add(model.z[i] - model.z[j] + M*(1-model.delta[i, j]) >= 1)
        model.unique_z.add(model.z[i] - model.z[j] - M*model.delta[i, j] <= -1)

model.obj = Objective(expr=sum(model.z[i] for i in range(N)), sense=maximize)
model.L = SubModel(fixed=model.z)

with Solver('pao.pyomo.MIBS') as solver:
    results = solver.solve(model)

print("obj =", model.obj.expr(), "z =", [model.z[i].value for i in range(N)])

所以基本约束就像这里,它借助二元变量

z[0] != z[1]
将不等约束
delta
表示为线性约束。一个明显的解决方案是
z[0]
z[1]
为 1,另一个变量为 0。

但是,我打印了模型的输出,发现模型将

z[0]
z[1]
都设置为 0。

>>> model.z.pprint()
z : Size=2, Index=z_index
    Key : Lower : Value : Upper : Fixed : Stale : Domain
      0 :     0 :     0 :     1 : False : False : Integers
      1 :     0 :     0 :     1 : False : False : Integers

>>> model.delta.pprint()
delta : Size=4, Index=delta_index
    Key    : Lower : Value : Upper : Fixed : Stale : Domain
    (0, 0) :     0 :  None :     1 : False :  True : Binary
    (0, 1) :     0 :     0 :     1 : False : False : Binary
    (1, 0) :     0 :  None :     1 : False :  True : Binary
    (1, 1) :     0 :  None :     1 : False :  True : Binary

>>> model.unique_z.pprint()
unique_z : Size=2, Index=unique_z_index, Active=True
    Key : Lower : Body                                : Upper : Active
      1 :   1.0 : z[0] - z[1] + 1024*(1 - delta[0,1]) :  +Inf :   True
      2 :  -Inf :       z[0] - z[1] - 1024*delta[0,1] :  -1.0 :   True

那么当

z[0]
z[1]
delta(0,1)
都为0时,这不是违反了
z[0] - z[1] - 1024*delta[0,1] <= -1
约束吗?我不明白为什么这可行。

我是 Pyomo 的初学者。如果我构建的模型或 Pyomo 输出中有任何误解,我将不胜感激任何澄清或建议。谢谢你。


编辑:感谢@AirSquid,问题似乎出在我的“pao.pyomo.MIBS”求解器上。任何人都可以对我当前执行的“pao.pyomo.MIBS”求解器的问题提出一些建议吗?我必须使用这个求解器来执行我的双层优化程序。

linear-programming pyomo mixed-integer-programming integer-programming
1个回答
1
投票

我怀疑您的求解代码有问题,并且您正在查看某种未解决或错误的解决方案。我不熟悉您在那里使用的代码序列。我通常:

  • SolverFactory
  • 获取求解器实例
  • 捕捉解决结果
  • 检查求解结果。 <-- must do to ensure optimal or result is junk.

你的数学是正确的。我稍微调整了你的模型并使用了不同的解算器,但它有效。您正在双重导入。您应该能够使用第一个 第二个导入行。我更喜欢

pyo
前缀,但无论如何。我注释掉了
pao
,因为它在我的示例中没有使用。

请注意,在

pyomo
中,
pprint
显示带有变量名称的构造,并且
display
可用于填写(或显示)已求解的值

代码:

# import pyomo.environ as pyo
from pyomo.environ import *
# from pao.pyomo import *


N = 6
M=1024

model = ConcreteModel()
model.z = Var(range(N), domain=Integers)
for i in range(N):
    model.z[i].setlb(0)
    model.z[i].setub(N-1)

model.delta = Var(range(N), range(N), domain=Binary)

model.unique_z = ConstraintList()
for i in range(N):
    for j in range(i+1, N):
        model.unique_z.add(model.z[i] - model.z[j] + M*(1-model.delta[i, j]) >= 1)
        model.unique_z.add(model.z[i] - model.z[j] - M*model.delta[i, j] <= -1)

model.obj = Objective(expr=sum(model.z[i] for i in range(N)), sense=maximize)
# model.L = SubModel(fixed=model.z)

solver = SolverFactory('cbc')
results = solver.solve(model)

# DO THIS.  Check for "OPTIMAL"
print(results)

print("obj =", model.obj.expr(), "z =", [model.z[i].value for i in range(N)])

# easy way to inspect the output of a variable (or the whole model)
model.z.display()
# model.display()

输出:

Problem: 
- Name: unknown
  Lower bound: 15.0
  Upper bound: 15.0
  Number of objectives: 1
  Number of constraints: 30
  Number of variables: 21
  Number of binary variables: 15
  Number of integer variables: 21
  Number of nonzeros: 6
  Sense: maximize
Solver: 
- Status: ok
  User time: -1.0
  System time: 0.27
  Wallclock time: 0.46
  Termination condition: optimal
  Termination message: Model was solved to optimality (subject to tolerances), and an optimal solution is available.
  Statistics: 
    Branch and bound: 
      Number of bounded subproblems: 270
      Number of created subproblems: 270
    Black box: 
      Number of iterations: 4106
  Error rc: 0
  Time: 0.47368288040161133
Solution: 
- number of solutions: 0
  number of solutions displayed: 0

obj = 15.0 z = [2.0, 4.0, 0.0, 1.0, 3.0, 5.0]
z : Size=6, Index=z_index
    Key : Lower : Value : Upper : Fixed : Stale : Domain
      0 :     0 :   2.0 :     5 : False : False : Integers
      1 :     0 :   4.0 :     5 : False : False : Integers
      2 :     0 :   0.0 :     5 : False : False : Integers
      3 :     0 :   1.0 :     5 : False : False : Integers
      4 :     0 :   3.0 :     5 : False : False : Integers
      5 :     0 :   5.0 :     5 : False : False : Integers
© www.soinside.com 2019 - 2024. All rights reserved.