sitting_duck
sitting_duck

Reputation: 3720

How to Implement Logical OR constraint in CPLEX Python

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.

Upvotes: 2

Views: 1102

Answers (3)

Alex Fleischer
Alex Fleischer

Reputation: 10059

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/

Upvotes: 2

Daniel Junglas
Daniel Junglas

Reputation: 5930

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.

Upvotes: 1

sascha
sascha

Reputation: 33512

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)

Upvotes: 0

Related Questions