2
$\begingroup$

I am solving a MILP using Gurobi and Pyomo. I would like to obtain as many optimal solutions as possible. Here is what I have so far:

opt = SolverFactory('gurobi_persistent')
n_of_s = 10
opt.set_instance(model)
opt.set_gurobi_param('PoolSolutions', n_of_s)
opt.set_gurobi_param('PoolSearchMode', 2)
opt.solve(model, tee=True)
opt.set_gurobi_param('SolutionNumber',2) 
model.pprint()

At some point Gurobi displays Solution count 3: 5000 5000 5000. However, when trying to access the value of optimal variables, I can only access one solution.

I have tried using the Xn attribute, but Gurobi states AttributeError: '_GeneralVarData' object has no attribute 'Xn'.

$\endgroup$
6
  • $\begingroup$ Do you mean local optimum? Most of the time, there is only one global optimum. I remember seeing a way to add a hash function constraint somewhere. $\endgroup$ Jun 24 at 15:39
  • $\begingroup$ No I mean global. It's a milp $\endgroup$
    – DeepNet
    Jun 24 at 17:12
  • $\begingroup$ May be constraint the solution to be not equal to existing solutions? Stop when the objective function's value at the optimum changes. $\endgroup$ Jun 24 at 21:50
  • $\begingroup$ I changed three gurobi parameters and it worked for me. PoolSolutions : how many MIP solutions to be stored (set it to 500)? PoolGap: Limit the search space by setting a gap for the worst possible solution that will be accepted (0.8 for 80% worst solution). PoolSearchMode: Do a systematic search for the k-best solutions (setting it to 2 forces gurobi to find required no. of feasible solutions if they exist). $\endgroup$ Jun 25 at 1:20
  • 1
    $\begingroup$ After solving the model, check how many solutions were stored by printing m.SolCount . Then, you can retrieve those solutions using: for sol in range(m.SolCount - 1): m.setParam(GRB.Param.SolutionNumber, sol+1); var.Xn $\endgroup$ Jun 25 at 1:23
3
$\begingroup$

Yes, you can. For example, with Pyomo package, the gurobi solver is selected using the following code:

opt = SolverFactory("gurobi", solver_io='python')
opt.options["NonConvex"] = 2
opt.options['MIPGap'] = 0.01
opt.options['SolCount'] = 2

results = opt.solve(model, load_solutions=True, tee=True)

The attributes of gurobi solver can be visited by using opt._solver_model. For example, you can see the number of solutions by calling its attribute of 'SolCount' as opt._solver_model.SolCount. Similarly, you can access the multiple solutions by using its attribute Xn in the same way as using "Gurobi" directly. For example, you can access all the solutions in this way:

xs=[]
for s in range(opt._solver_model.SolCount):
   opt._solver_model.params.SolutionNumber = s
   x=opt._solver_model.getAttr("Xn")
   xs.append(x)

Similarly, you can access all gurobi solver's attributes. BTW, you can read the code under pyomo package to see how pyomo visits gurobi solver in the directory of ...\Lib\site-packages\pyomo\solvers\plugins\solvers\gurobi_direct.py. Hope it helps.

$\endgroup$
1
  • $\begingroup$ I did not see "add more lines". I did edit my first answer before, so I am not sure which one you are seeing. Anyway, it does not make any sense. Ignore it, pls. (it was my first time to post on this forum, so I might have already made some confusion about how to properly use the forum; sorry for that) $\endgroup$
    – Li Bai
    Jun 25 at 7:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.