Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constraint optimization in python with OR Tools: How to enforce a multi level constraint?

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.

like image 984
ThaNoob Avatar asked Apr 21 '26 16:04

ThaNoob


1 Answers

  1. OnlyEnforceIf is just an implication. You need to add the reverse direction.

  2. 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 
like image 189
Laurent Perron Avatar answered Apr 24 '26 04:04

Laurent Perron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!