how to write a conditional constraint in CPLEX python?

前提是你 提交于 2021-02-11 12:12:34

问题


I have a model that has one binary variable x [i] [j] [k]. I need to add a constraint that fullfils this condition:


if x[i][j][k1]==1  and  x[j][i][k2]==1 

Then:

 k2-k1>8

I have this code but I assum it is not correct :

  mdl.add((y[(i,j,k)]+y[(j,i,k1)]==2),(k1-k>8) )

I also, put this:

 mdl.add(mdl.if_then(y[(i,j,k1)]+y[(j,i,k2)]==2, k2-k1>8))

but I got this error:

    raise DOcplexException(resolved_message)

DOcplexException: Expecting linear constraint, got: False

How can I model this with cplex python API?


回答1:


let me share the if then example from

https://www.linkedin.com/pulse/making-optimization-simple-python-alex-fleischer/

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  then nbBuses30 more than 7")

#if then constraint
mdl.add(mdl.if_then(nbbus40>=3,nbbus30>=7))
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()



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

and if you want to see and in the if

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.if_then((nbbus40>=3) + (nbbus40<=7)>=2,nbbus30>=7))
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()



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

which you can also rewrite

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((((nbbus40>=3) + (nbbus40<=7)>=2))<=(nbbus30>=7))
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()



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



回答2:


Model.if_then links two linear constraints left-to-right. If the first one becomes satisfied, the second will be satisfied too.

In your case , I understand that in k2-k1>8 there are no decision variables involved. SO this is purely data-dependent, known at model build time.

In that case, the causality works the other way round: if k2-k1>8 then both x[i,j,k1] and x[i,j,k2] must be equal to 1.

The simplest code is then:

if k2-k1>8:
   m.add(x[i,j,k1] == 1)
   m.add(x[i,j,k2] == 1)


来源:https://stackoverflow.com/questions/62388899/how-to-write-a-conditional-constraint-in-cplex-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!