使用 OR 工具在 python 中进行约束优化:如何强制执行多级约束?

Tha*_*oob 3 python or-tools cp-sat

我有一个优化问题,我有一个“BoolVar”对象列表的列表。所以像这样:

[[BoolVar1,BoolVar2],[BoolVar3, BoolVar4],[BoolVar5,BoolVar6]]
Run Code Online (Sandbox Code Playgroud)

我需要评估以下内容:

(BoolVar1 && BoolVar2) || (BoolVar3 && BoolVar4) || (BoolVar5 && BoolVar6)
Run Code Online (Sandbox Code Playgroud)

我是否必须按如下方式执行此操作:

and12 = model.NewBoolVar("and12")
model.Add(and12 == True).OnlyEnforceIf([BoolVar1,BoolVar2])
and34 = model.NewBoolVar("and34")
model.Add(and34 == True).OnlyEnforceIf([BoolVar3,BoolVar4])
and56 = model.NewBoolVar("and56")
model.Add(and56 == True).OnlyEnforceIf([BoolVar5,BoolVar6])
model.AddBoolOr([and12,and34,and56])
Run Code Online (Sandbox Code Playgroud)

我已经尝试过这段代码,它似乎有效,但由于“OnlyEnforceIf”功能,我对此表示怀疑。如果不强制执行会怎样?那么 and12 是否设置为 False,或者可以是 False 或 True,因为此后该等式不再强制执行?我根据这篇文章找到了这段代码。

Lau*_*ron 6

  1. OnlyEnforceIf只是一个暗示。您需要添加相反的方向。

  2. 你应该留在布尔世界:

from ortools.sat.python import cp_model

model = cp_model.CpModel()

and12 = model.NewBoolVar("and12")
BoolVar1 = model.NewBoolVar("b1")
BoolVar2 = model.NewBoolVar("b2")
model.AddBoolAnd([BoolVar1, BoolVar2]).OnlyEnforceIf(and12)
model.AddBoolOr([and12]).OnlyEnforceIf([BoolVar1, BoolVar2])

solver = cp_model.CpSolver()
solver.parameters.enumerate_all_solutions = True
solver.Solve(model, cp_model.VarArraySolutionPrinter([BoolVar1, BoolVar2, and12]))
Run Code Online (Sandbox Code Playgroud)

输出

Solution 0, time = 0.00 s
  b1 = 0   b2 = 0   and12 = 0 
Solution 1, time = 0.00 s
  b1 = 1   b2 = 0   and12 = 0 
Solution 2, time = 0.00 s
  b1 = 0   b2 = 1   and12 = 0 
Solution 3, time = 0.00 s
  b1 = 1   b2 = 1   and12 = 1 
Run Code Online (Sandbox Code Playgroud)