Get constraints in matrix format from gurobipy
Cannot comment on the answer of @david-nehme due to insufficient reputation, feel free to add this to his answer and delete mine.
Since Gurobi 9.0 you can query the coefficient matrix via .getA()
as a <class 'scipy.sparse.csr.csr_matrix'>
.
import matplotlib.pyplot as plt
import gurobipy as grb
m = grb.read("miplib/instances/miplib2010/aflow40b.mps.gz")
A = m.getA()
plt.spy(A) # different options, e.g. markersize=0.5
plt.show()
Also check out matrix plots using betterspy.
Before Gurobi 9.0
From the python API, there's no single function to get the matrix coefficients from a Gurobi model, but it's not to hard to write one yourself.
It is convenient to have lists of your variables and constraints. If you have a gurobi model in variable m
dvars = m.getVars()
constrs = m.getConstrs()
will give you the list of variables and constraints. You can then use m.getAttr to retrieve attributes related to the variables. To obtain the objective function coefficients, you query the 'Obj' attribute
obj_coeffs = m.getAttr('Obj', dvars)
This will give you a list of the objective coefficient for each variable in the model. For the constraint matrix, you likely want to store just the nonzeros. I'll just store them in the COOrdinate format
- row index
- column index
- coefficient
In this example, it is convenient to have the index of each variable and constraint object. I'll just create dictionaries that map the objects to the indices
var_index = {v: i for i, v in enumerate(dvars)}
constr_index= {c: i for i, c in enumerate(constrs)}
Each constraint object in the constrs
list corresponds to a constraint in the model. Each constraint has a
- left hand side expression
- sense (<=, ==, >=)
- right hand side constant
For the constraint matrix, you need only the left hand side. It is represented by a LinExpr object which you can obtain with the getRow method on the model. As of Gurobi 6.x, obtaining a list of column index, coefficient tuples requires a function like the following
def get_expr_coos(expr, var_indices):
for i in range(expr.size()):
dvar = expr.getVar(i)
yield expr.getCoeff(i), var_indices[dvar]
To get the matrix, you need to apply this function for every constraint.
def get_matrix_coos(m):
dvars = m.getVars()
constrs = m.getConstrs()
var_indices = {v: i for i, v in enumerate(dvars)}
for row_idx, constr in enumerate(constrs):
for coeff, col_idx in get_expr_coos(m.getRow(constr), var_indices):
yield row_idx, col_idx, coeff
Using this function, you can store the matrix into a structure like a pandas dataframe
nzs = pd.DataFrame(get_matrix_coos(m),
columns=['row_idx', 'col_idx', 'coeff'])
From this structure, you can do a basic plot of the nonzero pattern. Using a problem from the miplib aflow40b benchmark problem.
import matplotlib.pyplot as plt
import pandas as pd
import gurobipy as grb
m = grb.read("miplib/instances/miplib2010/aflow40b.mps.gz")
nzs = pd.DataFrame(get_matrix_coos(m),
columns=['row_idx', 'col_idx', 'coeff'])
plt.scatter(nzs.col_idx, nzs.row_idx,
marker='.', lw=0)
Update 19/06/20 for Gurobi 9.0
You can query the coefficient matrix via .getA()
as a <class 'scipy.sparse.csr.csr_matrix'>
.
import matplotlib.pyplot as plt
import gurobipy as grb
m = grb.read("miplib/instances/miplib2010/aflow40b.mps.gz")
A = m.getA()
plt.spy(A) # different options, e.g. markersize=0.5
plt.show()
Also check out matrix plots using betterspy.