IBMDecisionOptimization / docplex-examples

These samples demonstrate how to use the DOcplex library to model and solve optimization problems.
https://ibmdecisionoptimization.github.io/
Apache License 2.0
392 stars 228 forks source link

Many expressions in logical statement? #74

Open abernal2 opened 2 years ago

abernal2 commented 2 years ago

Hello,

I am working on a scheduling problem using CP. The behavior that I want is the following:

if at least one of a set of optional interval variables is present, then an integer variable is equal to 1.

If the 'set' was small I would explicitly write the constraint using the overloaded OR operator '|'. But the set is huge. I tried doing a loop: for var in set: expr += presenceOf(x) |

but this outputs an error. I also tried nested logical or to no avail. Is there a way to create the the logical statement presenceOf(x1) | presenceOf(x2) | ... | presenceOf(x_n)

where 'n' is large?

HuguesJuille commented 2 years ago

Hello, Would it be possible to share a code snippet to reproduce that issue ? What kind of error do you get ? What is the value of a large n in your case ?

Otherwise, could you try something like: mdl.add(mdl.any([mdl.presence_of(itv) for itv in set]) == IntegerVar)

Kind regards,

abernal2 commented 2 years ago

Hello @HuguesJuille ,

The interval variables I played with are from the house_building example https://github.com/IBMDecisionOptimization/docplex-examples/blob/master/examples/cp/visu/house_building_basic.py

My n for my real problem can be >= 300

The snippet I tried are:

sets = [masonry, facade, painting, roofing, plumbing, carpentry, ceiling] expr = 0 for itv_var in sets: expr += presenceOf(x) |

This generates a syntax error because of the type (stupid but just wanted to try it). The next snippet is trying the nested logical_or:

sets = [facade, painting, roofing, plumbing, carpentry, ceiling] expr = logical_or(masonry,None) for itv_var in sets: expr = logical_or(itv_var, expr)

And this generates a CPO expression can not be used as boolean. I actually found a solution after trial and error and I verified it via the exported model file. I tried

sets = [facade, painting, roofing, plumbing, carpentry, ceiling] mdl0.add(logical_or([presence_of(itv_var) for itv_var in sets]) == (IntegerVar==1))

Thanks,