混合整数线性规划中的整数除法

问题描述

在 MILP 程序中对整数除法进行编码的求解器友好方式是什么?目前我正在使用以下编码(在 Gurobi python 中),这可能不完全正确,我希望不是最佳的。

# res is an integer variable in the solver
# val is an integer variable in the solver
# divVal is just a python variable,a constant for solver
offset = 0.999
divRes = val / divVal
model.addConstr(divRes - offset <= res)
model.addConstr(res <= divRes)

上面的编码本质上是说 res 应该被分配一个介于 divRes - offsetdivRes间的值,因为 offset 是 0.999,所以范围内应该只有 1 个整数,并且求解器被迫将其分配给 res。有没有更好(更快)的编码方式?

编辑:通过整数除法我的意思是除法的结果是一个整数。如果除法后有任何小数部分,我想丢弃它并将结果舍入将存储在 res 中。我本质上想做的是将一个数字移动一些 x 位。在 MILP 求解器中,这归结为将一个数除以 (1 << x),但除法后有一些我想去掉的小数部分。

解决方法

model.addRange(val - divVal*res,0.99999,name="Range")

我更愿意只使用上面提到的范围约束。 将更严格的边界(给定范围内只有整数,我们需要)直接合并到模型中不仅可以改善数值行为,但它也加快了优化过程(因为 gurobi 使用分支定界算法来获得解决方案) https://www.gurobi.com/documentation/9.1/refman/improving_ranges_for_varia.html

最优性 - 模型的微小变化可以轻松计算出最优结果,如果 divVal* res 将变为整数。 Gurobi 不提供小于约束。此外,当变量的值距离最近的整数值小于 IntFeasTol 时,Gurobi 认为该变量的完整性限制得到满足。 IntFeasTol 容差的默认值为 1e-5,为了更好的结果,可以进一步减小到 1e-9。然而,制作多目标模型,给模型增加了额外的复杂性。我不想推荐它。

model.addRange(val - divVal*res,1,name="Range")

model.setObjective(res,GRB.MINIMIZE)