Visual c++ 为什么编译器会更改线性规划解决方案的结果?(GLPLK/GLPSOL)

Visual c++ 为什么编译器会更改线性规划解决方案的结果?(GLPLK/GLPSOL),visual-c++,gcc,glpk,Visual C++,Gcc,Glpk,尝试使用GLPLK的GLPSOL解决线性规划问题时,我们遇到了一个障碍,即在非常特定的情况下,使用不同编译器创建的GLPSOL可执行文件之间的结果是不同的 情况是,我们有几个有效的解决方案存在问题。简单地说,我们有一个表,其中每行(X)只能分配一列(Y),反之亦然。因此,分配唯一列/行对的所有组合都是有效的 例如,对于2x2表格,以下各项有效: {(X0,Y0),(X1,Y1)} {(X0,Y1),(X1,Y0)} 现在,我们在windows下使用的原始glpsol二进制文件按顺序返回结

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

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

例如,对于2x2表格,以下各项有效:

 {(X0,Y0),(X1,Y1)}   {(X0,Y1),(X1,Y0)}
现在,我们在windows下使用的原始glpsol二进制文件按顺序返回结果,如下所示:

 {(X0,Y0),(X1,Y1)...(Xn,Yn)}
 {(X0,Y0),(Xn,Y1),(X1,Y2) ....}
我们注意到Linux二进制文件存在一个问题,因为它以不同的顺序返回解决方案,如下所示:

 {(X0,Y0),(X1,Y1)...(Xn,Yn)}
 {(X0,Y0),(Xn,Y1),(X1,Y2) ....}
请注意,顺序不是随机的,每次执行都遵循相同的模式

经过大量调查,我发现问题在于使用哪个编译器创建每个二进制文件。在上面的例子中,Windows二进制文件是用Visual C++编译的,而Linux二进制文件使用的是GCC。 我已经通过使用GCC重新编译Windows二进制文件验证了这一点,得到了相同的模式。使用Borland编译会产生不同的模式

所以问题主要是,为什么会发生这种情况

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

<强>注:我通过将它们作为文本打开并在可执行引用的Visual C++和GNU GCC中定位文本字符串来确定每个二进制文件所使用的编译器。


谢谢

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


如果这两种解决方案都是最优的,我就不会太担心这个问题。

也许你应该发布你的代码。可能是您使用的是编译器特定的可忽略特性(
#pragma
等),或者您的代码依赖于未定义的行为,这些行为在不同的编译器之间实现不同。我现在使用的是GLPK发行版中的代码,我们的目的是尝试将二进制作为一个“黑盒”来处理,我们不需要做太多修改。当然,由于缺少其他选项,我现在正在深入研究,我将检查是否有编译器特定的功能,尽管我怀疑问题在于您提到的未定义的行为。显然,您的算法不是为了保证输出顺序而编写的。标准库包含许多非稳定排序算法,当多个项目比较相等时,这些算法肯定会返回不同(但相当正确)的顺序。或者,不同平台上的浮点舍入可能略有不同。这是我正在研究的一种可能性,因为源代码直接来自GNU下载页面。不幸的是,对于我们的应用程序,结果分配的顺序很重要。不过,谢谢你的指点。你总是可以添加一个约束来获得特定的顺序。但是,这可能会增加求解时间。您将如何添加这样的约束?在我们创建问题的方式中,变量是按照适当的优先级顺序创建的。GLPSOL问题是很久以前由一个外部团队设计的,所以所有这些对我来说都是新的。对于增加的解决方案时间,考虑到用例,这不是什么大问题。确保特定排序的一种可能方法是要求对解决方案中的变量值(子集)进行排序。类似于:s.t.c{i in i}:x[i]谢谢,我会调查的。