我使用DOCPLEX建立一个混合整数线性规划(MILP)问题,然后通过Python上的CPLEX来解决这个问题。但是,在使用IF
DOcplexException: Model.if_then(), nbBus40 >= 3.0 is not discrete之所以发生这种情况,是因为我已经将nbbus40变量声明为连续,如下代码所示:
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.continuous_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),(nbbus30>=7)))
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)但是,如果我将nbbus40变量保持为整数,则得到解决MILP问题的方法,如下所示:
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.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)结果:
nbBus40 = 0
nbBus30 = 10.0如何对连续变量使用DOCPLEX中的IF-然后约束?
发布于 2019-11-14 14:28:38
从这里复制我的答案
不能将连续变量用于if-然后约束。
原因是:“if”子句可以取值为true或false。取决于此,“not”子句是否被激活。如果nbBus40是连续的,那么CPLEX就必须区分nbBus40、>= 3和nbBus40 <3的情况。注意,后者是严格不等式!严格不等式不是线性规划理论所支持的。
如果nbBus40是整数,那么要区分的情况可以写成nbBus40 >= 3和nbBus40 <= 2。这些都不是严格的不等式。
一个典型的方法是使用epsilon并定义nbBus40 >= 3和nbBus40 <= 3-EPS两种情况。这也将得到支持。然而,eps应该取决于实际的表达式,因此没有很好的方法来选择泛型eps。这就是docplex将其留给用户的原因。
您可以这样编写约束:
with Model() as m:
nbBus40 = m.continuous_var()
nbBus30 = m.continuous_var()
helper = m.binary_var()
eps = 1e-3
m.add(m.if_then(helper == 0, nbBus40 <= 3 - eps))
m.add(m.if_then(helper == 1, nbBus40 >= 3))
m.add(m.if_then(helper == 1, nbBus30 >= 7))
m.solve()然而,请注意,拥有这些eps经常会引起数值上的麻烦。因此,最好避免连续表达式上的if_then。也许你可以详细说明为什么你要考虑一个小数的公共汽车。很可能还有其他的方法来实现你想要的。
https://stackoverflow.com/questions/58853258
复制相似问题