rust-or/rust-lp-modeler

Glpk Solution format parser doesn't cover all cases

Closed this issue · 1 comments

In the glpsol sometimes leaves blanks for the upper and lower bound of a variable which makes the read_solution method output "Incorrect solution format".

Example:

Problem:    
Rows:       3
Columns:    2
Non-zeros:  4
Status:     OPTIMAL
Objective:  obj = 1 (MAXimum)

   No.   Row name   St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 c1           B              1             0               
     2 c2           NL             0             0                          -1 
     3 c3           NS             1             1             =             1 

   No. Column name  St   Activity     Lower bound   Upper bound    Marginal
------ ------------ -- ------------- ------------- ------------- -------------
     1 a            B              1                             
     2 b            B              0                             

Karush-Kuhn-Tucker optimality conditions:

KKT.PE: max.abs.err = 0.00e+00 on row 0
        max.rel.err = 0.00e+00 on row 0
        High quality

KKT.PB: max.abs.err = 0.00e+00 on row 0
        max.rel.err = 0.00e+00 on row 0
        High quality

KKT.DE: max.abs.err = 0.00e+00 on column 0
        max.rel.err = 0.00e+00 on column 0
        High quality

KKT.DB: max.abs.err = 0.00e+00 on row 0
        max.rel.err = 0.00e+00 on row 0
        High quality

End of output

Produced by the following code:

use lp_modeler::operations::LpOperations;
use lp_modeler::problem::{LpObjective, LpProblem};
use lp_modeler::solvers::{GlpkSolver, SolverTrait};
use lp_modeler::variables::LpContinuous;

fn main() {
    let a = &LpContinuous::new("a");
    let b = &LpContinuous::new("b");

    let mut problem = LpProblem::new("One Problem", LpObjective::Maximize);

    problem += a;
    problem += a.ge(0);
    problem += b.ge(0);

    problem += (1 * a + 1 * b).equal(1.0);

    let solver = GlpkSolver::new();

    match solver.run(&problem) {
        Ok((status, var_values)) => {
            println!("Status {:?}", status);
            for (name, value) in var_values.iter() {
                println!("value of {} = {}", name, value);
            }
        }
        Err(msg) => println!("{}", msg),
    }
}

I would be willing to write the necessary changes and tests in a pull request if you are interested.

Hey, your contributions are welcome !