避免输入四舍五入#

数值问题的一个常见来源是用于表示约束矩阵系数的数字中的数值舍入。为了说明这个问题,考虑以下示例:

\[\begin{split}\begin{array}{rcl} x - 6y &=&1\\ 0.333x - 2y &= & .333 \end{array}\end{split}\]

可能会想说这两个方程是等价的,但是将两者都添加到模型中会导致错误的结果。这对我们的用户来说是一个重要的观点:Gurobi 将始终信任他们提供的输入数字,并且除非可以证明更改不会影响解决方案,否则永远不会更改它们。

因此,考虑到这一点,在预求解过程中,Gurobi 可以使用第二个约束来确定:

\[y := 0.1665x - 0.1665\]

当代入第一个约束时,这会产生

\[\begin{split}\begin{array}{rcl} x - 6\cdot(0.1665x - 0.1665) &=& 1\\ \Leftrightarrow 0.001x &=& 0.001 \end{array}\end{split}\]

因此,\(x = 1,\ y = 0\) 是唯一的解。

如果用户提供了以下两个方程:

\[\begin{split}\begin{array}{rcl} x - 6y&=&1\\ 0.3333333333333333x - 2y&=&0.3333333333333333 \end{array}\end{split}\]

这将给出:

\[y := 0.1666666666666667x - 0.1666666666666667\]

结果是:

\[\begin{split}\begin{array}{rcl} x - 6\cdot(0.1666666666666667x - 0.1666666666666667) &=& 1\\ \Leftrightarrow 2\cdot10^{-16} x + 1 + 2\cdot10^{-16} &\approx& 1 \end{array}\end{split}\]

即使将系数视为零的阈值非常小,这里的结果是第一个约束确实是多余的。任何具有\(x = 6y + 1\)的解决方案都将被视为可行。

主要观点是,完全平行或线性依赖(在双精度浮点和小容差范围内)的约束是无害的,但几乎相互平行的约束在线性系统求解和预处理中会产生微小的系数,这可能会对求解过程造成严重破坏。在下一节中,我们将详细讨论双精度浮点数的限制,特别是为什么\(1\approx 1+2\cdot10^{-16}\)