Hi Runqui

Thank you for your response. In the meantime, with the help of my colleague, I also discovered something interesting. When you read the solution from a .sol file, they are used to start the optimization process. So if you do not wish to solve the optimization problem again and extract those values, you can use Start attribute as well. Below is a sample code to do so.

Thank you again :)

import gurobipy as gpfrom gurobipy import GRB# Create a new modelm = gp.Model("mip1")# Create variablesx = m.addVar(vtype=GRB.BINARY, name="x")y = m.addVar(vtype=GRB.BINARY, name="y")z = m.addVar(vtype=GRB.BINARY, name="z")# Set objectivem.setObjective(x + y + 2 * z, GRB.MAXIMIZE)# Add constraint: x + 2 y + 3 z <= 4m.addConstr(x + 2 * y + 3 * z <= 4, "c0")# Add constraint: x + y >= 1m.addConstr(x + y >= 1, "c1")# Optimize modelm.optimize()for v in m.getVars():    print('%s %g' % (v.VarName, v.X))print('Obj: %g' % m.ObjVal)print("\n\n\n\n")m.write("test.sol")# Create a new modelm = gp.Model("mip1")# Create variablesx = m.addVar(vtype=GRB.BINARY, name="x")y = m.addVar(vtype=GRB.BINARY, name="y")z = m.addVar(vtype=GRB.BINARY, name="z")m.update()m.read("test.sol")for v in m.getVars():    print('%s %g' % (v.VarName, v.Start))
• Gurobi Staff

Hi Runqui,

The simplest way is to store the solution in the SOL format. Then, you can get whatever solution value you need without running Gurobi again. Saving the computed solution to a SOL file is considered best practice even if you don't right away need all solution values.

You can generate a SOL file on the command line using

gurobi_cl ResultFile=model.sol model.lp

or you call any of the API methods that write a SOL file, e.g., Model.write().

Cheers,
Matthias

Thanks Matthias.

Actually, I've tried using the SOL file with codes in another post.

gv = m.getVars()
names = m.getAttr('VarName', gv)
for i in range(m.SolCount):
m.params.SolutionNumber = i
xn = m.getAttr('Xn', gv)
lines = ["{} {}".format(v1, v2) for v1, v2 in zip(names, xn)]
with open('{}_{}.sol'.format(m.ModelName, i), 'w') as f:
f.write("# Solution for model {}\n".format(m.modelName))
f.write("# Objective value = {}\n".format(m.PoolObjVal))
f.write("\n".join(lines))

And I indeed got the variables and the values in a structured format.

# Solution for model brp_demo
# Objective value = 0.0
visit_truck[0,0,0,0] 1.0
visit_truck[0,0,1,0] 1.0
visit_truck[0,0,2,0] -0.0
visit_truck[0,0,3,0] -0.0
visit_truck[0,0,4,0] -0.0
visit_truck[0,0,5,0] -0.0
visit_truck[0,0,6,0] -0.0
visit_truck[0,0,7,0] -0.0
... ...

However,

Then I called model.read(xx.sol) in a new program, and tried to get the variable values via model.getAttr('Xn', var), it is reported No variable names available to index.

import gurobipy as gp

model = gp.Model()
x = model.getVars()
model.getAttr('Xn', x)


So the question is how do I load the solution for further analysis? Does gurobipy have a built-in parser for SOL files so that I can normally call APIs of the class Model just like I solve it at the beginning? Or do I have to manually write a parser to get what I want?

• Gurobi Staff

You seem to be making this more complicated than it is. You can store all solutions in the solution pool like this:

for i in range(model.SolCount):    model.Params.SolutionNumber = i    model.write(f"{i}.sol")

Then, to read in a solution, you just do

model.read("model.sol")

You don't have to handle every single value manually.

Please note that you should only read in the best solution found before.

Best regards,
Matthias

I'll summarize the steps below of my method on saving the model and read solutions directly without taking long time to run again.

1. create a model m

3. solve model m with m.optimize()

4. save the results with m.write(<filename.sol>)

5. create a new model m1

6. add same variables as m for m1, using m1.addVars(), and then update with m1.update()
[ps: actually m1.optimize() should contain m1.update(). However, by testing, without m1.update() here would cause error]

8. execute model m1 by calling m1.optimize(), this could take nearly no time to solve as all values are given.

9. get the values with m1.getVars()

An example can be found below in the reply to the post of Ashutosh Shukla or this link.

Hi

I am stuck in the same problem. Below is the toy example I am trying to run and getting an error message : "

AttributeError: Unable to retrieve attribute 'X'

my code:

#!/usr/bin/env python3.7

# Copyright 2022, Gurobi Optimization, LLC

# This example formulates and solves the following simple MIP model:
#  maximize
#        x +   y + 2 z
#  subject to
#        x + 2 y + 3 z <= 4
#        x +   y       >= 1
#        x, y, z binary

import gurobipy as gp
from gurobipy import GRB

# Create a new model
m = gp.Model("mip1")

# Create variables

# Set objective
m.setObjective(x + y + 2 * z, GRB.MAXIMIZE)

# Add constraint: x + 2 y + 3 z <= 4
m.addConstr(x + 2 * y + 3 * z <= 4, "c0")

# Add constraint: x + y >= 1
m.addConstr(x + y >= 1, "c1")

# Optimize model
m.optimize()

for v in m.getVars():
print('%s %g' % (v.VarName, v.X))

print('Obj: %g' % m.ObjVal)

m.write("test.sol")

# Create a new model
m = gp.Model("mip1")

# Create variables

m.update()

for v in m.getVars():
print('%s %g' % (v.VarName, v.X))

Hello, Shukla,

Actually, you just have to call m.optimize() after m.read(). I tested your code, and can obtain the result now.

Sorry for my misleading in the previous post on "removing the model.optimize()". Actually, the idea is solving another model with constraints that forces all the values of variables being equal to the ones given in the sol file. Therefore, you still need to call optimize() to solve the model, and retrieve the value by "getVars()".

The complete code:

The results:

Hope that helps.

Thank you!

Runqiu