Solution pool provides access to multiple feasible solutions

1,969 views
Skip to first unread message

Po-Hsun Chang

unread,
Nov 30, 2014, 3:56:52 AM11/30/14
to gur...@googlegroups.com
Hi 

From Gurobi's home page, it says "Solution pool provides access to multiple feasible solutions" in Mixed-integer model. 
Is it a new function? because there are some issues about access multiple solutions were discussed in this forum, but all the conclusions didn't said any function about "solution pool", and I also can't find any information about solution pool from reference manual.
To access multiple solutions of an ILP problem, I know it can get all solutions by cutting plane one by one, is there another more efficient way?

Thanks

Jakob Sch.

unread,
Nov 30, 2014, 10:19:15 AM11/30/14
to gur...@googlegroups.com

Shawn

unread,
Sep 27, 2015, 8:08:02 PM9/27/15
to Gurobi Optimization
Hi everyone,

Can anyone think of a python script to loop through all the solutions in the solution pool and write them out as separate .sol files?

I would like to show decision makers some of the less feasible solutions to help explain the solution the solver found as optimal.

Thanks!
Shawn

Kostja Siefen

unread,
Sep 29, 2015, 5:04:46 AM9/29/15
to Gurobi Optimization
Hi Shawn,

you can write solution files for all incumbent solutions by continously incrementing the 'SolutionLimit' parameter (see http://www.gurobi.com/documentation/6.0/refman/solutionlimit.html).

Python example:

---

from gurobipy import *

# read and optimize included model misc07
model = read(os.environ['GUROBI_HOME'] + '/examples/data/misc07.mps')
model.params.solutionLimit = 1

# write out all incumbent solutions
while (model.getAttr('Status') != GRB.OPTIMAL):
    model.optimize()
    model.write("{0}.sol".format(model.getAttr('SolCount')))
    model.params.solutionLimit += 1

---

Regards,
Kostja Siefen

Tobias Achterberg

unread,
Sep 29, 2015, 5:13:10 AM9/29/15
to gur...@googlegroups.com
Alternatively, you run optimize() just once as usual and then query the number
of available solutions through the "SolCount" attribute. Then, you loop over the
values 0 to SolCount-1 and:

1. Set the "SolutionNumber" parameter, see
http://www.gurobi.com/documentation/6.0/refman/solutionnumber.html

2. Query the solution via the "Xn" attribute:
http://www.gurobi.com/documentation/6.0/refman/xn.html


Regards,

Tobias
> <http://www.gurobi.com/products/gurobi-optimizer/features-and-benefits>,
> it says "Solution pool provides access to multiple feasible
> solutions" in Mixed-integer model.
> Is it a new function? because there are some issues about access
> multiple solutions were discussed in this forum, but all the
> conclusions didn't said any function about "solution pool", and I
> also can't find any information about solution pool from reference
> manual.
> To access multiple solutions of an ILP problem, I know it can get
> all solutions by cutting plane one by one, is there another more
> efficient way?
>
> Thanks
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "Gurobi Optimization" group.
> To unsubscribe from this group and stop receiving emails from it, send an email
> to gurobi+un...@googlegroups.com <mailto:gurobi+un...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.

--
-----------------------------------------------------------------
Dr. Tobias Achterberg
Senior Software Developer
Gurobi Optimization
achte...@gurobi.com

-----------------------------------------------------------------
Sitz der Gesellschaft: Bad Homburg v.d.H.
Registergericht: Bad Homburg v.d.H., HRB 12607
Geschäftsführer: Robert E. Bixby, Dirk Zechiel

Kostja Siefen

unread,
Sep 29, 2015, 5:24:14 AM9/29/15
to Gurobi Optimization
Here is a Python example for this:

from gurobipy import *

# read and optimize model misc07
model = read(os.environ['GUROBI_HOME'] + '\\examples\\data\\misc07.mps')
model.optimize()
print ("Optimal solution has objective value {0} ".format(model.getAttr('ObjVal')))

# retrieve and print number of solutions in solution pool
solution_pool_size = model.getAttr('SolCount')
print ("Solution pool contains {0} solutions".format(solution_pool_size))

if (solution_pool_size > 0):

    # tell Gurobi to retrieve solution with worst objective value from solution pool
    model.params.solutionNumber = solution_pool_size - 1

    # print all variables with non-zero value
    for variable in model.getVars():
        value = variable.getAttr('Xn')
        if (value > 0):
            print("{0}: {1}".format(variable.getAttr('VarName'), value))

Regards,
Kostja

Greg Glockner

unread,
Sep 29, 2015, 12:44:22 PM9/29/15
to gur...@googlegroups.com
> you can write solution files for all incumbent solutions by continously incrementing the 'SolutionLimit' parameter (see http://www.gurobi.com/documentation/6.0/refman/solutionlimit.html).

Here is a corrected version:

from gurobipy import *

model = read('misc07.mps')
model.params.solutionLimit = 1

# write out all incumbent solutions
while (model.getAttr('Status') != GRB.OPTIMAL):
model.optimize()
model.write("{0}.sol".format(model.params.solutionLimit))
model.params.solutionLimit += 1


Note that this is simple code for illustration; a proper program should check that a solution exists and should have proper exception handling.

Greg Glockner

unread,
Sep 29, 2015, 12:53:06 PM9/29/15
to gur...@googlegroups.com
Here is a corrected version:


from gurobipy import *

# read and optimize model misc07
model = read('misc07.mps')
model.optimize()
print ("Optimal solution has objective value {0} ".format(model.getAttr('ObjVal')))

# retrieve and print number of solutions in solution pool
solution_pool_size = model.getAttr('SolCount')
print ("Solution pool contains {0} solutions".format(solution_pool_size))

model.params.solutionNumber = solution_pool_size

while (model.params.solutionNumber > 0):

# retrieve prior solution generated during MIP search
model.params.solutionNumber -= 1

# print all variables with non-zero value
for variable in model.getVars():
value = variable.getAttr('Xn')
if (value > 0):
print("{0}: {1}".format(variable.getAttr('VarName'), value))




Again, this is simple code for illustration; a proper program should check that a solution exists and should have proper exception handling.

Fabien Tricoire

unread,
Jul 28, 2016, 1:21:38 PM7/28/16
to Gurobi Optimization
Following up on this, is there a direct way to query the value taken by a LinExpr object in a certain solution?

Renan Garcia

unread,
Aug 1, 2016, 9:50:02 AM8/1/16
to gur...@googlegroups.com
The LinExpr.getValue() method (http://www.gurobi.com/documentation/6.5/refman/py_linexpr_getvalue.html) returns the value taken by the expression for the final solution. That is, the value corresponding to the X variable attribute (http://www.gurobi.com/documentation/6.5/refman/x.html#attr:X). Unfortunately, there is no direct query for sub-optimal solutions, i.e., corresponding to the Xn attribute (http://www.gurobi.com/documentation/6.5/refman/xn.html#attr:Xn). You'll need to calculate that explicitly. For example:

  val = sum(expr.getCoeff(i)*expr.getVar(i).Xn for i in range(expr.size()))

--

---
You received this message because you are subscribed to the Google Groups "Gurobi Optimization" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gurobi+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages