2

How can I implement a constraint like x[0,0] == 0 OR x[0,0] >= 2 in CPLEX Python MP?

Seems like a job for semiinteger but semiinteger_var_matrix() is not available in the version of CPLEX Python I am using in Watson Studio DO environment. I could use semiinteger_var_list() which is available but would like to do via logical OR constraint to teach myself. I tried x[0,0] != 1 but MP doesn't handle NE. So I figured that I could do it the logical OR constraint shown above. Looked at the doc and the source of docplex.mp.model yet cannot figure out how to do this. I am in the early stages of learning CPLEX Python.

jch
  • 3,600
  • 1
  • 15
  • 17

3 Answers3

2

Let me give you a small example with the bus story:

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 nb buses 40 less than 3 or more than 7")



mdl.add((nbbus40<=3) + (nbbus40>=7) >=1)


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 nb buses 40 less than 3 or more than 7
nbBus40  =  7.0
nbBus30  =  1.0

NB: You may also write

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 nb buses 40 less than 3 or more than 7")

option1=mdl.binary_var(name='option1')
option2=mdl.binary_var(name='option2')

mdl.add(option1==(nbbus40<=3))
mdl.add(option2==(nbbus40>=7))

mdl.add(1==mdl.logical_or(option1,option2))

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

mdl.solve()

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

Many other tiny docplex Python examples at https://www.linkedin.com/pulse/making-optimization-simple-python-alex-fleischer/

halfer
  • 19,824
  • 17
  • 99
  • 186
Alex Fleischer
  • 9,276
  • 2
  • 12
  • 15
  • pretty late comment but do you confirm that this doesn't work (in docplex at least) if the variables are continuous and not anymore integers? – Olf Jan 31 '20 at 15:42
  • 1
    You could have a look at https://stackoverflow.com/questions/58853258/how-to-use-continuous-variables-for-if-then-constraints-on-docplex-python – Alex Fleischer Jan 31 '20 at 16:55
1

True, semiinteger_matrix does not exist. But semiinteger_dict does. So you can do something like

x = model.semiinteger_var_dict((i, j) for i in range(I) for j in range(J))

and after that you can reference the variables as x[0,0] etc.

Daniel Junglas
  • 5,830
  • 1
  • 5
  • 22
0

The classic formulation, assuming also an upper bound u looks like:

introduce fresh binary variable b

post

x <= u * b
x >= l * b

In your case l=2.

The value of u is problem-dependent and it's important to make it as small as possible for a better relaxation. (an introductory blog-post on the topic)

sascha
  • 32,238
  • 6
  • 68
  • 110