Search code examples
pythoncplex

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.


Solution

  • 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/