Most performant way for boolean-AND constraint

1,161 views
Skip to first unread message

adihe

unread,
Mar 19, 2019, 10:17:11 AM3/19/19
to or-tools-discuss
Hello all

I am using the following code in CP-SAT to implement X = A && B.

IntVar x = model.NewBoolVar("");
model.Add(x == 0).OnlyEnforceIf(new ILiteral[] { a.Not() } );
model.Add(x == 0).OnlyEnforceIf(new ILiteral[] { b.Not() });
model.Add(x == 1).OnlyEnforceIf(new ILiteral[] { a, b });

Is this the optimal way or is there a more performant approach?

Thank you for your feedback in advance.

Best regards,
Adrian



Laurent Perron

unread,
Mar 19, 2019, 10:38:32 AM3/19/19
to or-tools-discuss
model.AddBoolOr(new ILiteral[] {a.Not(), b.Not(), x });
model.AddImplication(x, a);
model.AddImplication(x, b);

--
You received this message because you are subscribed to the Google Groups "or-tools-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to or-tools-discu...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
--Laurent

adihe

unread,
Mar 19, 2019, 10:51:48 AM3/19/19
to or-tools-discuss
Thank you very much Laurent.

It works like a charm.

For my understanding: 

I checked the documentation for AddImplication at https://github.com/google/or-tools/blob/master/ortools/sat/doc/reference.md but I could not find details on why it would/could be potentially faster.

Could you give me a hint why it is so?

Thank you very much

Adrian

Laurent Perron

unread,
Mar 19, 2019, 11:08:47 AM3/19/19
to or-tools-discuss
your model is not Boolean, you add integer linear equations. Especially with the enforcement with 2 literals. they should be presolved into something simpler (I need to check).
This is way to complex for my liking. 

The fastest you can get is by using clauses (BoolOr). Implications will be transformed because a => b is actually a.Not() or b.

adihe

unread,
Mar 21, 2019, 10:51:47 AM3/21/19
to or-tools-discuss
Thank you Laurent.

wtv...@gmail.com

unread,
Mar 22, 2019, 4:04:21 AM3/22/19
to or-tools-discuss
model.AddImplication(x, a);
model.AddImplication(x, b);
It seems means X => A && B but not X = A && B?

Laurent Perron

unread,
Mar 22, 2019, 4:22:47 AM3/22/19
to or-tools-discuss
model.AddBoolOr(new ILiteral[] {a.Not(), b.Not(), x }); 

implements a && b => x

the two implications implement the opposite direction.
Laurent Perron | Operations Research | lpe...@google.com | (33) 1 42 68 53 00


wtv...@gmail.com

unread,
Mar 22, 2019, 4:41:30 AM3/22/19
to or-tools-discuss
Sorry, I forget this sentence. I have one puzzle when I test my code.
I have a constraint base <=> pack & flag.  
when I write this code,  it doesn't work.
cpPack.AddBoolAnd([pack, flag]).OnlyEnforceIf(base)
cpPack.Add(base == 1).OnlyEnforceIf([pack, flag])
then I change the code to following, it works.
base = cpPack.NewBoolVar("base")
flag = cpPack.NewBoolVar("flag")
cpPack.Add(z[j] - ze[i] == 0).OnlyEnforceIf(flag )
cpPack.Add(z[j] - ze[i] != 0).OnlyEnforceIf(flag.Not())
cpPack.AddBoolAnd([pack, flag]).OnlyEnforceIf(base)
cpPack.AddBoolOr([pack.Not(), flag .Not()]).OnlyEnforceIf(base.Not())
# cpPack.Add(base == 1).OnlyEnforceIf([pack, flag])

What is the difference between them? Do not two half-reified constraints equal to a full-reified constraint in ortools?

Laurent Perron

unread,
Mar 22, 2019, 8:16:57 AM3/22/19
to or-tools-discuss
It should be equivalent.
On tested on master, and it works fine.

Laurent Perron | Operations Research | lpe...@google.com | (33) 1 42 68 53 00


--
Reply all
Reply to author
Forward
0 new messages