rust-or / good_lp

Linear Programming for Rust, with a user-friendly API. This crate allows modeling LP problems, and lets you solve them with various solvers.
https://crates.io/crates/good_lp
MIT License
216 stars 35 forks source link

External solver failing due to LP file format #36

Closed mfuhr closed 10 months ago

mfuhr commented 11 months ago

Using an external solver fails on some problems, e.g., the first example on the main good_lp documentation page. When replacing default_solver with LpSolver(GlpkSolver::new()) the code panics with glpsol exited with status exit status: 1.

Running glpsol from the shell on a copy of the LP file shows more detail:

GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
 --lp example.lp
Reading problem data from 'example.lp'...
example.lp:8: missing variable name
CPLEX LP file processing error

The file is:

 1  \ good_lp_problem
 2
 3  Maximize
 4    obj: -3 b + 10 a
 5
 6  Subject To
 7    c0: -1 b + 1 a <= -2
 8    c1: -1 b + -1 a <= -3
 9
10  Bounds
11    a <= 1
12    2 <= b <= 4
13
14  End

The problem appears to be the + -1 a on line 8. Cplex (at least version 20.1.0.0 at NEOS) also fails with the error CPLEX Error 1434: Line 8: Couldn't convert '+-1' to a number but Gurobi accepts the file.

I think the formatting is done by linear_coefficients_str() in solvers/lp_solvers.rs:

fn linear_coefficients_str(
    expr: &Expression,
    variables: &[lp_solvers::problem::Variable],
) -> StrExpression {
    StrExpression(
        expr.linear_coefficients()
            .map(|(var, coeff)| format!("{} {}", coeff, variables[var.index()].name))
            .collect::<Vec<String>>()
            .join(" + "),
    )
}

I don't know if this is the correct fix or not, but changing the format string to "{:+} {}" and the join string to " " generates a file that's acceptable to Glpk, Cplex, and Gurobi, even for other problems where the first coefficient has a leading +.

Thanks!

lovasoa commented 11 months ago

Thanks, that's a great bug report! Since you found the source of the the error and even the fix, would you mind making a small PR, and maybe even adding a test?

mfuhr commented 11 months ago

Will do, although I confess to not having much git-fu. Got some learning to do first :-)

lovasoa commented 11 months ago

You can use GitHub CLI and then it's just

gh pr create

https://cli.github.com/

mfuhr commented 11 months ago

PR submitted; hopefully I got it right.

lovasoa commented 10 months ago

thanks ! fixed in 1.4.2 https://crates.io/crates/good_lp/versions