coin-or / Clp

COIN-OR Linear Programming Solver
Other
392 stars 82 forks source link

Dual values inside column generation #285

Closed fontanf closed 6 months ago

fontanf commented 6 months ago

I get a strange behavior with CLP inside a column generation algorithm for the bin packing problem. I illustrate with a problem containing 120 items.

First I create an LP with dummy columns. Each column has an objective value of 2 and satisfies one constraint.

Solving this LP leads to a solution with value 240, as expected.

Clp0006I 0  Obj 0 Primal inf 119.99999 (120) Dual inf 1.2e+12 (120)
Clp0006I 240  Obj 240
Clp0000I Optimal - objective value 240

As expected as well, all dual values are equal to 2.

row_pos 0 dual_out 0 -> 2
row_pos 1 dual_out 0 -> 2
row_pos 2 dual_out 0 -> 2
row_pos 3 dual_out 0 -> 2
...

Then, I compute the following new column:

objective coefficient: 1
row indices: 117 118 119
row coefficients: 1 1 1

Which reduced cost is -5, as expected.

I add this column to the same ClpSimplex object and I solve again the problem:

Clp0006I 0  Obj 240 Dual inf 4.9999999 (1)
Clp0006I 1  Obj 235
Clp0000I Optimal - objective value 235

The new objective value is 235, as expected.

The issue is that, here, the dual values are still all equal to 2.

Therefore, the same column is generated again. If I add it again to the LP and solve it again:

Clp0006I 0  Obj 235 Dual inf 4.9999999 (1)
Clp0006I 1  Obj 235
Clp0000I Optimal - objective value 235

And then one dual value changes:

row_pos 117 dual_out 2 -> -3

I would expect the dual value of constraints 118 and 119 to change as well.

I'm not sure if I miss something in the theory, if I don't use CLP correctly, or if this might be a bug in CLP.

Here are the methods I use to manipulate CLP

I use CLP 1.17.8 from https://github.com/coin-or/Clp/releases/download/releases%2F1.17.8/Clp-releases.1.17.8-x86_64-ubuntu20-gcc940-static.tar.gz

fontanf commented 6 months ago

If I replace

        model_.primal();

by

        model_.initialSolve();

then it seems to work as expected. But the warm-start is lost, which makes the resolution of the LP much longer

fontanf commented 6 months ago

If I don't add bounds when adding columns:

        model_.addColumn(
                row_indices.size(),
                row_indices_int.data(),
                row_coefficients.data(),
                COIN_DBL_MIN,
                COIN_DBL_MAX,
                objective_coefficient);

then it also seems to work as expected

fontanf commented 6 months ago

I think I get what happens. The solver considers that the active constraint is the variable bound and not the constraint. So, the updated dual is the one from the variable bound and it's not a bug.