为什么 or-tools 中的布尔变量不起作用?

Jos*_*oob 5 python constraint-programming or-tools cp-sat

我正在重新使用 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)
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息

TypeError: bad operand type for unary -: 'BoundedLinearExpression'
Run Code Online (Sandbox Code Playgroud)

看来我在这里滥用 OR 工具语法来限制我的约束。我很难理解在线 OR 工具的文档,而且我似乎忘记的东西比我想象的要多得多。

Ana*_*lii 3

根据这里的一个例子,你就快到了。

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

情况1:x = true

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

model.Add(y < c).OnlyEnforceIf(x) 
Run Code Online (Sandbox Code Playgroud)

案例 2: x = false,

如案例 1中所述,OnlyEnforceIf如果其参数未计算为 ,则不会激活约束true。因此,您不能只保留 casey >= c本身并希望 if 会暗示它x = false。因此,为这种情况添加反向约束,如下所示:

model.Add(y >= c).OnlyEnforceIf(x.Not())
Run Code Online (Sandbox Code Playgroud)

因为,对于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) 
Run Code Online (Sandbox Code Playgroud)