为什么编译器会改变线性编程解决方案的结果? (GLPLK / glpsol之类)

时间:2015-04-24 09:06:50

标签: visual-c++ gcc glpk

尝试使用 GLPLK的GLPSOL 来解决线性编程问题我们遇到了一个障碍,即在非常特殊的情况下,使用不同编译器创建的 glpsol 可执行文件之间的结果是不同的。

情况是我们遇到了几个有效解决方案的问题。简单地说,我们有一个表,其中每行(X)只能分配一列(Y),反之亦然。因此,分配唯一列/行对的所有组合都是有效的。

示例,对于2x2表,这些是有效的:

 {(X0,Y0),(X1,Y1)}   {(X0,Y1),(X1,Y0)}

现在,我们在 windows 下使用的原始glpsol二进制文件按顺序返回结果,如下所示:

 {(X0,Y0),(X1,Y1)...(Xn,Yn)}

我们注意到 Linux 二进制文件存在问题,因为它以不同的顺序返回解决方案,如下所示:

 {(X0,Y0),(Xn,Y1),(X1,Y2) ....}

请注意,顺序不是随机的,每次执行都遵循相同的模式。

经过多次调查后,我发现问题在于使用哪个编译器来创建每个二进制文件。在上面的示例中, Windows 二进制文件是使用 Visual C ++ 编译的,而 Linux 二进制文件是使用 GCC 。< / p>

我通过使用 GCC 重新编译 Windows 二进制文件来验证这一点,从而产生相同的模式。使用 Borland 进行编译会产生不同的模式。

所以问题是,为什么会发生

我猜这可能是每个编译器如何优化二进制文件的结果,但我不确定,我的目标是获得与原始可执行文件(用编译的结果)相同的结果Visual C ++ Windows Linux 。我怀疑使用 Visual C ++ 工具链进行交叉编译是不可取的。

注意:我设法确定每个二进制文件使用的编译器,方法是将它们作为文本打开,并在可执行文件中定位文本字符串,引用 Visual C ++ GNU GCC 分别。

谢谢!

1 个答案:

答案 0 :(得分:1)

使用不同编译器构建的解算器的版本可以在优化过程中采用不同的路径,这可能导致您观察到的行为。可能影响这一点的是:浮点语义的差异(可能由-ffast-math引起),排序的不同实现(qsort通常不是stable sort) - Ben提到了这一点Voigt,标准库中随机数生成器的不同实现。

如果两种解决方案都是最佳解决方案,我不会过于担心这一点。