Get constraints in matrix format from gurobipy

冷暖自知 提交于 2019-12-18 11:44:34

问题


I coded my model in gurobipy and I want to get the matrix of constraints and vector of cost. Is there any way to access those?


回答1:


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 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_coo(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_cos(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_coo(m), 
                    columns=['row_idx', 'col_idx', 'coeff'])
 plt.scatter(nzs.col_idx, nzs.row_idx, 
        marker='.', lw=0)



来源:https://stackoverflow.com/questions/38647230/get-constraints-in-matrix-format-from-gurobipy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!