I have an optimization problem where I have a list of lists of "BoolVar" objects. So something like this:
[[BoolVar1,BoolVar2],[BoolVar3, BoolVar4],[BoolVar5,BoolVar6]]
I need to evaluate the following:
(BoolVar1 && BoolVar2) || (BoolVar3 && BoolVar4) || (BoolVar5 && BoolVar6)
Do I have to do this as follows:
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])
I've tried this code and it seems to be working but I'm doubtful because of the "OnlyEnforceIf" function. What happens if it's not enforced? Is and12 then set to False or can it be either False or True, since then this equation is not enforced? I came to this code based on this post.
OnlyEnforceIf is just an implication. You need to add the reverse direction.
You should stay in the Boolean world:
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]))
outputs
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With