Hello!
I came across a nasty issue when trying to solve a model from an LP file.
As far as I can tell, the SCIPOPT LP parser follows the LP specification of CPLEX:
- https://www.scipopt.org/doc-7.0.3/html/reader__lp_8h.php
- https://www.ibm.com/docs/en/icos/12.9.0?topic=cplex-lp-file-format-algebraic-representation
From testing, I do know (now) that CPLEX does not support constant values within the constraint expressions. The specification itself does not explicitly state this:
This is not the nicest definition, but something that can be worked with.
Problem description
If CPLEX is presented with an LP file that violates this rule, an error is raised:
invalid.lp
\none
Maximize
var_x
Subject To
var_x - 1 = 0
Bounds
1 <= var_x <= 1
Binary
var_x
End
CPLEX output
CPLEX> read invalid.lp
CPLEX Error 1616: Line 5: Expected identifier, found '='.
No file read.
CPLEX>
If the same LP is given to SCIPOPT, it is read without error, and solved:
SCIPOPT output
SCIP> read C:\temp\scip\invalid.lp
read problem <C:\temp\scip\invalid.lp>
============
original problem has 1 variables (1 bin, 0 int, 0 impl, 0 cont) and 1 constraints
SCIP> optimize
presolving:
presolving (1 rounds: 1 fast, 0 medium, 0 exhaustive):
1 deleted vars, 0 deleted constraints, 0 added constraints, 0 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
0 implications, 0 cliques
presolving detected infeasibility
Presolving Time: 0.00
SCIP Status : problem is solved [infeasible]
Solving Time (sec) : 0.00
Solving Nodes : 0
Primal Bound : -1.00000000000000e+20 (objective limit, 0 solutions)
Dual Bound : +1.00000000000000e+20
Gap : 0.00 %
SCIP simply omits the constant in the constraint expression, and solves the (inconsistent) problem. In this case, the model becomes infeasible by omitting the constant. However, with a slight adjustment to the LB of var_x, the model will become feasible and the result will deviate from the intended/expected solution:
feasible_invalid.lp
\none
Maximize
var_x
Subject To
var_x - 1 = 0
Bounds
0 <= var_x <= 1
Binary
var_x
End
SCIP output (var_x LB = 0)
SCIP> read C:\temp\scip\feasible_invalid.lp
read problem <C:\temp\scip\feasible_invalid.lp>
============
original problem has 1 variables (1 bin, 0 int, 0 impl, 0 cont) and 1 constraints
SCIP> optimize
feasible solution found by trivial heuristic after 0.0 seconds, objective value 0.000000e+00
presolving:
presolving (1 rounds: 1 fast, 0 medium, 0 exhaustive):
1 deleted vars, 0 deleted constraints, 0 added constraints, 1 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
0 implications, 0 cliques
Presolving Time: 0.00
SCIP Status : problem is solved [optimal solution found]
Solving Time (sec) : 0.00
Solving Nodes : 0
Primal Bound : +0.00000000000000e+00 (1 solutions)
Dual Bound : +0.00000000000000e+00
Gap : 0.00 %
If the same file is parsed + solved with, e.g., Gurobi (which supports constants in constraint expressions), the following output is produced:
Gurobi output
gurobi> m = read('feasible_invalid.lp')
Read LP format model from file feasible_invalid.lp
Reading time = 0.00 seconds
: 1 rows, 2 columns, 2 nonzeros
gurobi> m.optimize()
Gurobi Optimizer version 9.5.0 build v9.5.0rc5 (win64)
Thread count: 4 physical cores, 4 logical processors, using up to 4 threads
Optimize a model with 1 rows, 2 columns and 2 nonzeros
Model fingerprint: 0xf7308cbe
Variable types: 1 continuous, 1 integer (1 binary)
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [0e+00, 0e+00]
Found heuristic solution: objective -0.0000000
Presolve removed 1 rows and 2 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Explored 0 nodes (0 simplex iterations) in 0.00 seconds (0.00 work units)
Thread count was 1 (of 4 available processors)
Solution count 2: 1 -0
Optimal solution found (tolerance 1.00e-04)
Best objective 1.000000000000e+00, best bound 1.000000000000e+00, gap 0.0000%
gurobi>
Expected behavior
- Main priority
- Given the current LP file format specification that SCIPOPT is following, I'd expect an error message when an invalid LP file is given. The silent fail might cause serious issues, since the resulting model might actually be feasible - but the solution differs from the "intended" model.
- Nice to have
- Add support for constant values in constraints, similar to Gurobi's LP file format
I hope this is the correct address for reporting such an issue. If this is not the case, please let me know where I can/should submit it.
Best Regards,
Jannick