首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将连续变量用于DOCPLEX (Python)上的IF-然后约束?

如何将连续变量用于DOCPLEX (Python)上的IF-然后约束?
EN

Stack Overflow用户
提问于 2019-11-14 09:21:53
回答 1查看 1.1K关注 0票数 2

我使用DOCPLEX建立一个混合整数线性规划(MILP)问题,然后通过Python上的CPLEX来解决这个问题。但是,在使用IF

代码语言:javascript
复制
DOcplexException: Model.if_then(), nbBus40 >= 3.0 is not discrete

之所以发生这种情况,是因为我已经将nbbus40变量声明为连续,如下代码所示:

代码语言:javascript
复制
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问题的方法,如下所示:

代码语言:javascript
复制
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)

结果:

代码语言:javascript
复制
nbBus40  =  0
nbBus30  =  10.0

如何对连续变量使用DOCPLEX中的IF-然后约束?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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将其留给用户的原因。

您可以这样编写约束:

代码语言:javascript
复制
 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。也许你可以详细说明为什么你要考虑一个小数的公共汽车。很可能还有其他的方法来实现你想要的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58853258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档