从 gurobipy 获取矩阵格式的约束

Get constraints in matrix format from gurobipy

我在 gurobipy 中编写了我的模型,我想获得约束矩阵和成本向量。 有什么方法可以访问这些吗?

Gurobi 9.0 之前

从pythonAPI来看,没有一个函数可以从Gurobi模型中获取矩阵系数,但是自己写一个并不难。

拥有变量和约束列表很方便。如果您在变量 m

中有一个 gurobi 模型
dvars = m.getVars()
constrs = m.getConstrs()

将为您提供变量和约束列表。然后,您可以使用 m.getAttr 检索与变量相关的属性。要获取 objective 函数系数,请查询 'Obj' 属性

obj_coeffs = m.getAttr('Obj', dvars)

这将为您提供模型中每个变量的 objective 系数列表。对于约束矩阵,您可能只想存储非零值。我将以 COOrdinate 格式

存储它们
  • 行索引
  • 列索引
  • 系数

在这个例子中,有每个变量和约束对象的索引是很方便的。我将创建将对象映射到索引的字典

var_index = {v: i for i, v in enumerate(dvars)}
constr_index= {c: i for i, c in enumerate(constrs)}

constrs 列表中的每个约束对象对应于模型中的一个约束。每个约束都有一个

  • 左侧表达式
  • 意义(<=、==、>=)
  • 右侧常量

对于约束矩阵,您只需要左侧。它由模型上的 LinExpr object which you can obtain with the getRow 方法表示。从Gurobi 6.x开始,获取列索引列表,系数元组需要如下函数

def get_expr_coos(expr, var_indices):
    for i in range(expr.size()):
        dvar = expr.getVar(i)
        yield expr.getCoeff(i), var_indices[dvar]

要获取矩阵,您需要为每个约束应用此函数。

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

使用此函数,您可以将矩阵存储为类似 pandas dataframe

的结构
 nzs = pd.DataFrame(get_matrix_coos(m), 
                    columns=['row_idx', 'col_idx', 'coeff'])

根据这个结构,您可以绘制非零模式的基本图。使用来自 miplib aflow40b 基准问题的问题。

 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)

Gurobi 9.0 更新 19/06/20

您可以通过.getA()查询系数矩阵作为<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()

还可以使用 betterspy 查看矩阵图。

由于声誉不足,无法评论@david-nehme 的回答,请随时将此添加到他的回答并删除我的。

从 Gurobi 9.0 开始,您可以通过 .getA() 作为 <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()

还可以使用 betterspy 查看矩阵图。