scipopt / russcip

Rust interface for SCIP
https://crates.io/crates/russcip
Apache License 2.0
30 stars 10 forks source link

Maybe a bug about adding solutions #143

Open youngzhaozju opened 2 months ago

youngzhaozju commented 2 months ago

[test]

fn create_sol() {
    let mut model = Model::new()
        .hide_output()
        .include_default_plugins()
        .create_prob("test")
        .set_obj_sense(ObjSense::Minimize);

    let x1 = model.add_var(0., 1., 3., "x1", VarType::Binary);
    let x2 = model.add_var(0., 1., 4., "x2", VarType::Binary);
    let cons1 = model.add_cons_set_part(vec![], "c");
    model.add_cons_coef_setppc(cons1, x1.clone());

    model.add_cons_set_pack(vec![x2.clone()], "c");

    let sol = model.create_sol();
    assert_eq!(sol.obj_val(), 0.);

    sol.set_val(x1.clone(), 1.);
    sol.set_val(x2.clone(), 1.);
    assert_eq!(sol.obj_val(), 7.);

    assert!(model.add_sol(sol).is_ok());

    let mut model = model.solve();
    assert_eq!(model.n_sols(), 2);

// I added following code. It lead to error: assertion failed: model.add_sol(sol).is_ok() **let mut model = model.free_transform(); let sol = model.create_sol(); assert_eq!(sol.obj_val(), 0.);

    sol.set_val(x1, 1.);
    sol.set_val(x2, 1.);
    assert_eq!(sol.obj_val(), 7.);

    assert!(model.add_sol(sol).is_ok());**

}
youngzhaozju commented 2 months ago

I found that, from the first .solve(), it print:

presolving (1 rounds: 1 fast, 0 medium, 0 exhaustive): 1 deleted vars,

So, it means that a var was deleted. I tried to delete the following code , it works! // sol.set_val(x1.clone(), 1.); sol.set_val(x2.clone(), 1.);

My conclusion is that you cannot use the function add_sol() after free_transform. Is it right?

mmghannam commented 2 months ago

Hi @youngzhaozju! I agree with your analysis. I think what happened is that in presolving a variable was deleted in an attempt by SCIP to simplify the problem. Then, the relationship between the original variables and the transformed variables (after presolving) was deleted when you called free_transform. I'm curious to know why you're calling free_trasnform in that order. Anyway, you can completely avoid this if you disable presolving. (check the set_presolving method).