从gurobipy获取矩阵格式的约束

Mos*_*ori 7 python mathematical-optimization linear-programming sparse-matrix gurobi

我用gurobipy编写了我的模型,我想获得约束矩阵和成本向量.有没有办法访问这些?

Dav*_*hme 18

从python API中,没有一个函数可以从Gurobi模型中获取矩阵系数,但是自己编写一个并不困难.

拥有变量和约束列表很方便.如果你有一个变量的gurobi模型m

dvars = m.getVars()
constrs = m.getConstrs()
Run Code Online (Sandbox Code Playgroud)

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

obj_coeffs = m.getAttr('Obj', dvars)
Run Code Online (Sandbox Code Playgroud)

这将为您提供模型中每个变量的目标系数列表.对于约束矩阵,您可能只想存储非零值.我只是将它们存储在COOrdinate格式中

  • 行索引
  • 列索引
  • 系数

Gurobi python中的每个变量和约束对象都有一个索引.我将创建将对象映射到索引的字典

var_index = {v: i for i, v in enumerate(dvars)}
constr_index= {c: i for i, c in enumerate(constrs)}
Run Code Online (Sandbox Code Playgroud)

constrs列表中的每个约束对象对应于模型中的约束.每个约束包括其 - 左侧表达式 - sense(<=,==,> =) - 右侧常量

对于约束矩阵,您需要左侧.它由一个m对象表示,您可以使用该constrs方法在模型上获得该对象.从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]
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

使用此函数,您可以将矩阵存储到像pandas数据帧这样的结构中

 nzs = pd.DataFrame(get_matrix_coos(m), 
                    columns=['row_idx', 'col_idx', 'coeff'])
Run Code Online (Sandbox Code Playgroud)

从这个结构,你可以做一个非零模式的基本情节.使用来自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_coo(m), 
                    columns=['row_idx', 'col_idx', 'coeff'])
 plt.scatter(nzs.col_idx, nzs.row_idx, 
        marker='.', lw=0)
Run Code Online (Sandbox Code Playgroud)

非零的


ktn*_*tnr 5

由于声誉不足,无法对@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()
Run Code Online (Sandbox Code Playgroud)

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