0

我有一个我正在尝试解决的 MILP 模型。我有一个新的约束,我之前在这个问题上解释过 我的新约束是:

如果:y[(i,j,k)]==1

那么 : y[(j,i,k+1)] ,y[(j,i,k+2)],y[(j,i,k+3)] ,y[(j,i,k+ 4)],y[(j,i,k+5)],y[(j,i,k+6)],y[(j,i,k+7)],y[(j,i, k+8)==0 。

我以这种方式将这个约束放在我的模式上:

        mdl.add_constraints((y[(i,j,k)]+y[(j,i,k+1)] +y[(j,i,k+2)]+y[(j,i,k+3)]
       +y[(j,i,k+4)]+y[(j,i,k+5)]+y[(j,i,k+6)]+y[(j,i,k+7)]+y[(j,i,k+8)]  )<=1 for k in K4 for i in T for j in T ) 

但是用这个新的constriant运行我的模型会使我的模型求解速度很慢。我的约束是否有问题,或者有没有办法改变它以使我的模型可以更快地解决?

编辑: 当我以这种方式放置条件时,运行时间很快,但模型不尊重解决方案中的 if then 约束。我的代码:

        for i in T:
            for j in T:
                if i!=j:
                    for k in K4:
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+1)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+2)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+3)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+4)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+5)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+6)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+7)]==0))
                        mdl.add( mdl.if_then( y[(i,j,k)]==1 , y[(j,i,k+8)]==0))
       
4

1 回答 1

0

关于第二个公式:我是否理解 Cplex 为您提供了一个违反 if_then 的解决方案,即 y[i,j,k] 为 1 而任何其他 y[j,i,k+..] 不是0 ? 如果是这样,这很奇怪,值得调查。正如蒂姆所说,转储LP使用Model.export_as_lp(),我们来看看。

此外,我对这个替代提法有两点评论:

  • if_then 中的“if 约束”实际上是某个变量等于 1,因此可以使用指标约束重写。

  • 假设您的 y 变量是二进制的,那么可以在一个约束中强制所有 8 个变量为零,说明它们的总和为 0。因此,我会将替代公式中的内部语句重写为:

    mdl.add_indicator(y[i,j,k],
                      mdl.sum(y[j,i,k+d] for d in range(9)) ==0))
    

这意味着每当变量 y[i,j,k] 等于 1 时,所有 y[j,i,k+d] 变量都为零(假设它们是二进制的)

与 if_then 不同,指标约束不会生成中间二元变量,因此该公式会生成更小的模型。同样,如果该公式生成了违反它的解决方案,则将 LP 文件转发给我们以进行调查。

于 2020-07-15T07:34:12.357 回答