JuMP Gurobi.jl CPLEX.jl Solution Pool

Hi community,

I was interested in setting and obtaining a solution pool for a MILP problem using a solver like CPLEX or Gurobi that support that capability.
Do you know how I can proceed or suggestions?

Thank you

I replied to your comment: https://github.com/jump-dev/CPLEX.jl/issues/197#issuecomment-970530377

PRs accepted.

It’s implemented in Gurobi, but not CPLEX.

1 Like

Thank you very much!
In Gurobi you mean like the following example?

m = Model(optimizer_with_attributes(Gurobi.Optimizer, “PoolSearchMode”=>2, “PoolSolutions” => 1000))
@variables(m,begin
0 <= x <= 5
0 <= y <= 10, Int
z, Bin
zz, Bin
end)
@objective(m, Max, x + 2y + 5*(z+zz))
@constraint(m, x + y + z + zz<= 10)
@constraint(m, x + 2y + z + zz <= 15)
@constraint(m, z + zz <= 1)
optimize!(m)
value(z, result=2)

https://jump.dev/JuMP.jl/stable/manual/solutions/#Multiple-solutions

Hi,

I am also interested in obtaining a solution pool from a MILP using Gurobi. I have looked at the docs but I cannot manage to retrieve the different solutions. For example, for the model mentioned by @davide-f here above:

using JuMP
m = Model(optimizer_with_attributes(Gurobi.Optimizer, “PoolSearchMode”=>2, “PoolSolutions” => 1000))
@variables(m,begin
0 <= x <= 5
0 <= y <= 10, Int
z, Bin
zz, Bin
end)
@objective(m, Max, x + 2y + 5*(z+zz))
@constraint(m, x + y + z + zz<= 10)
@constraint(m, x + 2y + z + zz <= 15)
@constraint(m, z + zz <= 1)
optimize!(m)

I get:

Academic license - for non-commercial use only
Optimize a model with 3 rows, 4 columns and 10 nonzeros
Variable types: 1 continuous, 3 integer (2 binary)
Coefficient statistics:
Matrix range [1e+00, 2e+00]
Objective range [1e+00, 5e+00]
Bounds range [5e+00, 1e+01]
RHS range [1e+00, 2e+01]
Found heuristic solution: objective 15.0000000
Presolve time: 0.00s
Presolved: 3 rows, 4 columns, 10 nonzeros
Variable types: 1 continuous, 3 integer (2 binary)
…
Explored 47 nodes (10 simplex iterations) in 0.01 seconds
Thread count was 8 (of 8 available processors)
Solution count 24: 19 19 19 … 5
No other solutions better than -1e+100
Optimal solution found (tolerance 1.00e-04)
Best objective 1.900000000000e+01, best bound 1.900000000000e+01, gap 0.0000%

And so we have:

  • 24 solutions (by running result_count(m))
  • But then value(z; result=i) and objective_value(m; result=i) always return the same value (for each i in {1,…,24})

Any idea of what is going on? Is the “result” argument not functioning?

Thank you!

UPDATE
I have found a workaround at the following link: Multi-cut Benders decomposition? - #3 by deschase

What is import Pkg; Pkg.status("Gurobi")? I can’t reproduce this:

julia> using JuMP, Gurobi

julia> m = Model(Gurobi.Optimizer)
Academic license - for non-commercial use only - expires 2022-06-19
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: Gurobi

julia> set_optimizer_attribute(m, "PoolSearchMode", 2)

julia> set_optimizer_attribute(m, "PoolSolutions", 1000)

julia> @variables(m, begin
           0 <= x <= 5
           0 <= y <= 10, Int
           z, Bin
           zz, Bin
       end)
(x, y, z, zz)

julia> @objective(m, Max, x + 2y + 5*(z+zz))
x + 2 y + 5 z + 5 zz

julia> @constraint(m, x + y + z + zz<= 10)
x + y + z + zz ≤ 10.0

julia> @constraint(m, x + 2y + z + zz <= 15)
x + 2 y + z + zz ≤ 15.0

julia> @constraint(m, z + zz <= 1)
z + zz ≤ 1.0

julia> optimize!(m)
Gurobi Optimizer version 9.1.0 build v9.1.0rc0 (mac64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 3 rows, 4 columns and 10 nonzeros
Model fingerprint: 0x32c0faa9
Variable types: 1 continuous, 3 integer (2 binary)
Coefficient statistics:
  Matrix range     [1e+00, 2e+00]
  Objective range  [1e+00, 5e+00]
  Bounds range     [5e+00, 1e+01]
  RHS range        [1e+00, 2e+01]
Found heuristic solution: objective 15.0000000
Presolve time: 0.00s
Presolved: 3 rows, 4 columns, 10 nonzeros
Variable types: 1 continuous, 3 integer (2 binary)

Root relaxation: objective 1.900000e+01, 3 iterations, 0.00 seconds

    Nodes    |    Current Node    |     Objective Bounds      |     Work
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

*    0     0               0      19.0000000   19.00000  0.00%     -    0s

Optimal solution found at node 0 - now completing solution pool...

    Nodes    |    Current Node    |      Pool Obj. Bounds     |     Work
             |                    |   Worst                   |
 Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

     0     0          -    0               -   19.00000      -     -    0s
     0     0          -    0               -   19.00000      -     -    0s
     0     2          -    0               -   19.00000      -     -    0s

Explored 47 nodes (10 simplex iterations) in 0.00 seconds
Thread count was 8 (of 8 available processors)

Solution count 24: 19 19 19 ... 5
No other solutions better than -1e+100

Optimal solution found (tolerance 1.00e-04)
Best objective 1.900000000000e+01, best bound 1.900000000000e+01, gap 0.0000%

User-callback calls 174, time in user-callback 0.00 sec

julia> print_var(v, i) = print(lpad("$(value(v; result = i))", 5), " ")
print_var (generic function with 1 method)

julia> begin
           println(" i     x     y     z   objective")
           for i in 1:result_count(m)
               print(lpad(i, 2), " ")
               print_var(x, i)
               print_var(y, i)
               print_var(z, i)
               println("  ", objective_value(m; result = i))
           end
       end
 i     x     y     z   objective
 1   0.0   7.0   1.0   19.0
 2   0.0   7.0   0.0   19.0
 3   4.0   5.0   1.0   19.0
 4   4.0   5.0  -0.0   19.0
 5   2.0   6.0   1.0   19.0
 6   2.0   6.0  -0.0   19.0
 7   5.0   4.0  -0.0   18.0
 8   5.0   4.0   1.0   18.0
 9   5.0   3.0   1.0   16.0
10   5.0   3.0  -0.0   16.0
11   5.0   5.0  -0.0   15.0
12   1.0   7.0   0.0   15.0
13   3.0   6.0  -0.0   15.0
14   5.0   2.0   1.0   14.0
15   5.0   2.0  -0.0   14.0
16   5.0   4.0  -0.0   13.0
17   5.0   1.0   1.0   12.0
18   5.0   1.0  -0.0   12.0
19   5.0   3.0   0.0   11.0
20   5.0  -0.0  -0.0   10.0
21   5.0   0.0   1.0   10.0
22   5.0   2.0  -0.0   9.0
23   5.0   1.0   0.0   7.0
24   5.0  -0.0  -0.0   5.0