0

I am modeling the situation I want using python cplex. While using it, a few questions arose, and these are:

  1. Can I use nested IF-THEN constraints in CPLEX?

First, I could find below how to use the basic IF-THEN constraint.

How to use Continuous Variables for IF-THEN constraints on DOCPLEX (Python)?

However, I couldn't find a way to use nested IF-THEN constraints even there, so I did some thinking.

To explain by citing the answer above, I want the following situation:

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')  
**mdl.add(mdl.if_then(((nbbus40>=3) and (nbbus40<=7)),(nbbus30>=7)))**
mdl.minimize(nbbus40*500 + nbbus30*400)

If I try something like line 5 of the code above, can't I use nested IF-THEN constraints?

If this is wrong, how should I use nested IF-THEN constraints?

  1. In general, I understand that inequality can be used as a constraint in CPLEX. For example, if I want to give the condition of A=1, I can satisfy it by giving both the condition A>=1 and the condition A<=1. My question is, is there a way to specify (constrain) a value using only the equal sign (I think 2 conditions in 1 constraint is wasteful)?

Thank you.

1 Answer 1

1

In Making optimization simple with python you relied on if then but you should try if then (v2)

With your model I would write

mdl.add((mdl.logical_and((nbbus40>=3),(nbbus40<=7)))<=(nbbus30>=7))

instead of

mdl.add(mdl.if_then(((nbbus40>=3) and (nbbus40<=7)),(nbbus30>=7)))

Full example:

from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
   print(v," = ",v.solution_value)

print()
print("with if nb buses 40 more than 3  and less than 7 then nbBuses30 more than 7")

#if then constraint

mdl.add((mdl.logical_and((nbbus40>=3),(nbbus40<=7)))<=(nbbus30>=7))

mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

 

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value) 

'''

which gives

nbBus40  =  6.0
nbBus30  =  2.0

with if nb buses 40 more than 3  and less than 7 then nbBuses30 more than 7
nbBus40  =  8.0
nbBus30  =  0.0

'''
3
  • Thank you for the reply. By the way, in the case of IF_THEN(A and B, C), this example seems to work well, but how should I write the code in case IF_THEN(A and (B or C), D)? Should I write logical_or nested?
    – pioneer
    Commented Feb 21, 2022 at 8:00
  • mdl.add((mdl.logical_and((nbbus40>=3),mdl.logical_or(nbbus40<=7,nbbus30>=2)))<=(nbbus30>=7)) works fine Commented Feb 21, 2022 at 8:30
  • Thank you. I've tested your answers and confirmed that they all work.
    – pioneer
    Commented Feb 21, 2022 at 11:01

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.