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
396 stars 228 forks source link

CPO expression can not be used as boolean #49

Closed SHosseini94 closed 3 years ago

SHosseini94 commented 3 years ago

Hi, I am using docplex.cp for solving my cp problem. I should enforce the model to compare two CPO integer expressions and based on the comparison, which is greater, equal, or smaller, do some specific steps. But, I got this error: "CPO expression can not be used as boolean" when I tried to compare these expressions using "if " structure in python. I was wondering if you could help me in this regard.

Thanks

ooudot commented 3 years ago

Hello,

As described in the documentation here: http://ibmdecisionoptimization.github.io/docplex-doc/cp/creating_model.html most of the Python operators are overloaded to generate equivalent modeling expression instead of doing normal stuff. The result is then always a CPO expression if at least one of the operands is a CPO expression.

Now, you want to compare two expressions at solve time, you have to build the corresponding model expression using appropriate modeling primitives. For example, if you want a variable a to be 38 or 42 depending on a condition variable x, just add a constraint ((x == 0) & (a == 38)) | ((x == 1) & (a == 42)) to your model, as in the following example:

from docplex.cp.model import *

mdl = CpoModel()
x = integer_var(0, 1, "x")
a = integer_var(name="a")

mdl.add(((x == 0) & (a == 38)) | ((x == 1) & (a == 42)))

# List all solutions
for mres in mdl.start_search(SearchType='DepthFirst', Workers=1):
    print("x: {}, res: {}".format(mres[x], mres[a]))

Displayed result is as expected:

x: 0, res: 38
x: 1, res: 42

Note that you can, in this case, also use the expression:

mdl.add(a == mdl.conditional(x == 0, 38, 42))

In a more general case, you can also use if_then constraint as follows:

mdl.add(if_then(x == 0, a == 38))
mdl.add(if_then(x == 1, a == 42))
SHosseini94 commented 3 years ago

Hi, Thanks for your response.

Is there any expression in CP to get the order of interval vars in a sequence in the modeling? I need to do some calculations based on the order of intervals in a sequence and add constraints to the model! I tried to do this by using your explanations, but I wasn't able to do it.

ooudot commented 3 years ago

Hi,

Yes, you can use sequence variables to do so (created using method sequence_var() in module docplex.cp.expression (http://ibmdecisionoptimization.github.io/docplex-doc/cp/docplex.cp.expression.py.html).

May I recommend you to read principles of scheduling in CPO, for example here: https://www.ibm.com/docs/en/icos/20.1.0?topic=optimizer-getting-started-cp

You have also a lot of examples here: https://github.com/IBMDecisionOptimization/docplex-examples/tree/master/examples/cp/basic

SHosseini94 commented 3 years ago

Thanks for your response.

I know sequence_var structure. I am working on a scheduling problem in which I used sequence_var and a no_overlap constraint. There is a specific constraint in my model requiring access to the order of interval variables of this sequnce_var! In other words, I need to do some expressions on elements of this sequence_var based on their position.

model=CpoModel() tasks=interval_var_list(asize=4,name="tasks") seq=sequence_var(tasks,types=[0,1,2,3],name="sequence") model.add(no_overlap(seq,distance_matrix,1)

I know that when we solve the model, model.solve() and print the solution, we observe that the value of sequence_var is an order of its interval_var. I was wondering if it would be possible to use this order during modeling. I mean, for example, seq[0] represents the first interval variable, or for instance, seq[1] represents the second interval variable. (I know that sequence_var doesn't have index, I just say it as an example to clarify my issue)

Best

ooudot commented 3 years ago

No, you can not access the interval variables in a sequence variable by index during modeling.

You can only use expressions and constraints that are available on sequence variables, and that are listed in the head comment here: http://ibmdecisionoptimization.github.io/docplex-doc/cp/docplex.cp.modeler.py.html