python - 皮莫 | Couenne 求解器 | 将索引变量域限制为两个整数值
问题描述
我是 Pyomo 的新手,正在努力理解 Pyomo 语法背后的直觉以及它如何构建模型。这可能就是为什么我无法弄清楚如何使用 Pyomo 和 Couenne 求解器定义和解决N个变量必须仅取 ±1 值的“二元”问题。
首先,我尝试了Integers
域bounds=(-1, 1)
并尝试添加严格的不等式:
import pyomo.environ as pyo
import numpy as np
N = 5
w = np.ones(range(N))
pyoModel = pyo.ConcreteModel('binary model')
pyoModel.o = pyo.Var(range(N), bounds=(-1, 1), within=pyo.Integers, initialize=1)
pyoModel.binaryConstraintP = pyo.Constraint(range(N), rule=strictlyPositive)
pyoModel.binaryConstraintN = pyo.Constraint(range(N), rule=strictlyNegative)
pyoModel.objective = pyo.Objective(expr=pyo.sum_product(pyoModel.o, w, index=range(N)), sense=pyo.maximize)
def strictlyPositive(model, i):
return model.o[i] > 0
def strictlyNegative(model, i):
return model.o[i] < 0
这最终得到:
ValueError:约束 'binaryConstraintP[0]' 遇到严格的不等式表达式('>' 或 '<')。所有约束都必须使用“<=”、“>=”或“==”来表示。
好的,不允许严格的不等式(不知道为什么!),我尝试切换到Binary
域并通过操纵目标中的变量来解决问题,使其位于 {-1, 1} - 即,如果o ∈ {0, 1} 然后 2 xo - 1 ∈ {-1, 1}:
import pyomo.environ as pyo
import numpy as np
N = 5
w = np.ones(range(N))
pyoModel = pyo.ConcreteModel('binary model')
pyoModel.o = pyo.Var(range(N), within=pyo.Binary, initialize=1)
pyoModel.objective = pyo.Objective(expr=pyo.sum_product(2 * pyoModel.o - 1, w, index=range(N)), sense=pyo.maximize)
拿到:
TypeError: *: 'int' 和 'IndexedVar' 的不支持的操作数类型
所以我使用了一个二和一的数组,而不是 2 和 1,但又遇到了关于形状广播的错误。我确定我在这里遗漏了一些东西,因为在目标中构建线性方程应该很容易,对吧?
我还尝试将域更改为用户定义的域:
...
pyoModel.domain = pyo.Set(initialize=[-1, 1])
...
pyoModel.o = pyo.Var(range(N), domain=pyoModel.domain, initialize=1)
...
with SolverFactory('couenne') as opt:
results = opt.solve(pyoModel, load_solutions=False)
...
并以Couenne错误告终:
TypeError:名称为“%s”的变量的域类型无效。变量不是连续的、整数的或二进制的。
我也想过使用 SOS,但更难理解它们是如何工作的!
同样,我必须在每种方法中遗漏一些东西。任何帮助都将不胜感激。
旁注:我尽可能简化了原始代码以使其更易于阅读。
解决方案
不允许严格不等式的原因是它可能不受底层解决方案理论的支持。我相信这适用于 MIP。您是否尝试在您定义的约束范围内将限制设置为非常小的值?例如
def strictlyPositive(model, i):
return model.o[i] >= 0.000000000000001
def strictlyNegative(model, i):
return model.o[i] <= -0.000000000000001
以这种方式模拟严格的不等式并不理想,因为它可能会导致数值问题,但值得一试。
推荐阅读
- javascript - 点击点赞后如何让点赞长度实时更新
- laravel - Laravel - 如何在多个包中运行计划
- git - 如何合并两个分支,其中第一个有一个提交 A,第二个有提交 A 修改为 B,3 个提交在 B 之上?没有合并提交
- aframe - 在移动设备上进入 VR 模式时 Aframe a-cursor 消失了
- mysql - mysql 行数与总 COUNT 不匹配
- powerbi - 如何在 Power BI 原始数据上创建集群
- html - 在屏幕顶部下方显示列表项目标
- php - fwrite(): 发送 15 个字节失败,errno=1 不允许操作
- javascript - 打字稿找不到offscreencanvas
- python - python代码结果可以用Latex写吗?