Open jwnimmer-tri opened 1 year ago
Reproduction script:
#!/bin/bash
set -euo pipefail
cat > example.cpp <<EOF
#include "ClpSimplex.hpp"
#include <iostream>
int main(int argc, const char* argv[]) {
ClpSimplex model;
model.readMps("infeasible.mps", true);
model.primal();
std::cout << "status = " << model.status() << "\n";
if (model.status() == 1) {
return 0; // success
}
return 1; // failure
}
EOF
cat > infeasible.mps <<EOF
NAME ClpDefau
ROWS
N OBJROW
L R0000000
E R0000001
COLUMNS
C0000000 OBJROW -1. R0000000 1.
C0000000 R0000001 2.
C0000001 OBJROW -1. R0000000 2.
C0000001 R0000001 1.
RHS
RHS R0000000 3. R0000001 4.
BOUNDS
LO BOUND C0000001 2.
ENDATA
EOF
mkdir good bad
(cd good && wget https://raw.githubusercontent.com/coin-or/coinbrew/master/coinbrew)
chmod u+x good/coinbrew
cp good/coinbrew bad/
(cd good && ./coinbrew fetch Clp@1.17.7)
(cd good && ./coinbrew build --tests=none Clp)
(cd good && g++ -omain ../example.cpp $(env PKG_CONFIG_PATH=dist/lib/pkgconfig pkg-config --cflags --libs clp))
LD_LIBRARY_PATH=good/dist/lib good/main
(cd bad && ./coinbrew fetch Clp@1.17.8)
(cd bad && ./coinbrew build --tests=none Clp)
(cd bad && g++ -omain ../example.cpp $(env PKG_CONFIG_PATH=dist/lib/pkgconfig pkg-config --cflags --libs clp))
LD_LIBRARY_PATH=bad/dist/lib bad/main
Output from 1.17.7:
Coin0001I At line 1 NAME ClpDefau
Coin0001I At line 2 ROWS
Coin0001I At line 6 COLUMNS
Coin0001I At line 11 RHS
Coin0001I At line 13 BOUNDS
Coin0001I At line 15 ENDATA
Coin0002I Problem ClpDefau has 2 rows, 2 columns and 4 elements
Clp0027I Model was imported from infeasible.mps in 0.000235 seconds
Clp0006I 0 Obj -2 Primal inf 2.9999998 (2) Dual inf 1e+10 (1)
Clp0006I 1 Obj -3 Primal inf 1.9999999 (1)
Clp0006I 1 Obj -3 Primal inf 1.9999999 (1) Dual inf 0.4999999 (1)
Clp0006I 2 Obj -2.3333333 Primal inf 1.3333332 (1)
Clp0001I Primal infeasible - objective value -2.3333333
status = 1
Output from 1.17.8:
Coin0001I At line 1 NAME ClpDefau
Coin0001I At line 2 ROWS
Coin0001I At line 6 COLUMNS
Coin0001I At line 11 RHS
Coin0001I At line 13 BOUNDS
Coin0001I At line 15 ENDATA
Coin0002I Problem ClpDefau has 2 rows, 2 columns and 4 elements
Clp0027I Model was imported from infeasible.mps in 0.000194 seconds
Clp0006I 0 Obj -2 Primal inf 2.9999998 (2) Dual inf 1e+10 (1)
Clp0006I 1 Obj -3 Primal inf 1.9999999 (1)
Clp0006I 1 Obj -3 Primal inf 1.9999999 (1) Dual inf 0.4999999 (1)
status = 4
BTW, the linear program we solve is very simple
max x0 + x1
s.t x0 + 2 * x1 <= 3;
2 * x0 + x1 == 4
x0 >= 0, x1 >= 2
which is obviously infeasible given x0 >= 0, x1 >= 2 and x0 + 2 * x1 <= 3.
Seems to be a series of tiny things going wrong. The code starts off with primal, but then switches to dual and then thinks infeasible after one iteration. The code tested number of iterations since last re-factorization. If >1 would be OK and ==0 also. It decided to switch back to primal, but code gets confused and thinks user wants to stop. I don't think the fix I will put in can do any harm.
In Clp 1.17.7, the following program correctly reports a
model.status()
of1 - primal infeasible
.In Clp 1.17.8, the status is mis-reported as
4 - stopped due to errors
.I tested this using the reproduction script (attached in my next post) on Ubuntu 22.04 with GCC 11.3.0 and all of coinbrew's default options.
Bisecting, the failure started happening as of commit 85648fa3894dd6b0bfadce5a698fa6aec8a23b7c (and notably the subsequent commit 4152b2e404a411634398366054e50be0a9ddbb11 did not fix it), and is still failing on the 1.17.8 release tag. FYI @jjhforrest.
\CC @hongkai-dai