为什么or-tools中的布尔变量不起作用? 案例 1:x = true情况 2:x = false,

问题描述

我将重新使用Google的OR工具并尝试(相对)简单的优化。我正在使用CP SAT求解器,并且这里可能缺少基本内容我有一些变量x,y和一些常数c。如果y小于c,我希望x等于1,否则等于0。

from ortools.sat.python import cp_model

solver = cp_model.cpsolver()
model = cp_model.CpModel()
c = 50
x = model.NewBoolVar(name='x')
y = model.NewIntvar(name='y',lb=0,ub=2**10)

model.Add(x == (y < c))

model.Maximize(x+y)

status = solver.solve(model)

我收到一条错误消息

TypeError: bad operand type for unary -: 'BoundedLinearExpression'

似乎我在这里将OR工具语法误用于我的约束。我在在线了解OR工具的文档时遇到了困难,而且我似乎已经忘记了很多东西。

解决方法

根据 here 中的示例,您差不多就可以了。

构建 x == (y < c) 约束

案例 1:x = true

如果 xtrue,那么 y < c 也必须是 true。这正是 OnlyEnforceIf 方法的用途。如果 OnlyEnforceIf 的参数是 true,那么 Add 方法中的约束将被激活:

model.Add(y < c).OnlyEnforceIf(x) 

情况 2:x = false,

案例 1 中所述,如果 OnlyEnforceIf 的参数未评估为 true,则不会激活约束。因此,您不能只保留 case y >= c 并希望它在 x = false 时隐含。因此,为这种情况添加一个反向约束,如下所示:

model.Add(y >= c).OnlyEnforceIf(x.Not())

由于对于 x = falsex.Not() 将是 true,因此在求解方程时将激活并使用约束 y >= c

完整代码

from ortools.sat.python import cp_model

solver = cp_model.CpSolver()
model = cp_model.CpModel()
c = 50
x = model.NewBoolVar(name='x')
y = model.NewIntVar(name='y',lb=0,ub=2**10)

model.Add(y < c).OnlyEnforceIf(x) 
model.Add(y >= c).OnlyEnforceIf(x.Not())

model.Maximize(x+y)

status = solver.Solve(model)