Gurobi / python中的稀疏矩阵LP问题

时间:2014-03-31 16:55:11

标签: python scipy sparse-matrix linear-programming gurobi

我正在尝试解决在Gurobi / python中使用稀疏矩阵表示的LP问题。

  

max c'x,受A x = b,L≤x≤U

其中A是大小为~1000 2 的SciPy linked list sparse matrix。使用代码

model = gurobipy.Model()
rows, cols = len(b), len(c)
for j in range(cols):
    model.addVar(lb=L[j], ub=U[j], obj=c[j])
model.update()
vars = model.getVars()
S = scipy.sparse.coo_matrix(A)
expr, used = [], []
for i in range(rows):
    expr.append(gurobipy.LinExpr())
    used.append(False)
for i, j, s in zip(S.row, S.col, S.data):
    expr[i] += s*vars[j]
    used[i] = True
for i in range(rows):
    if used[i]:
        model.addConstr(lhs=expr[i], sense=gurobipy.GRB.EQUAL, rhs=b[i])
model.update()
model.ModelSense = -1
model.optimize()

该问题在~1s内建立并解决,比Gurobi / Matlab中的相同任务慢约10-100倍。您是否有任何提高问题定义效率的建议,或避免转换为sparse coordinate格式的建议?

1 个答案:

答案 0 :(得分:3)

在处理稀疏矩阵时,MATLAB总是比scipy更有效。但是,有一些事情可以尝试加快速度。

Gurobi的Python界面采用了单独的稀疏约束。这意味着您希望以压缩的稀疏行格式(而不是坐标格式)访问矩阵。

尝试做:

   S = S.tocsr()

或以压缩稀疏行格式直接构建矩阵。

page表示您可以从CSR格式的scipy稀疏矩阵访问原始数据,指示和行指针。因此,您应该能够按如下方式迭代这些:

  model = gurobipy.Model()
  row, cols = len(b), len(c)
  x = []
  for j in xrange(cols):
      x.append(model.addVar(lb=L[j], ub=U[j], obj=c[j])
  model.update()

  # iterate over the rows of S adding each row into the model
  for i in xrange(rows):
      start = S.indptr[i]
      end   = S.indptr[i+1]
      variables = [x[j] for j in S.indices[start:end]]
      coeff     = S.data[start:end]
      expr = gurobipy.LinExpr(coeff, variables)
      model.addConstr(lhs=expr, sense=gurobipy.GRB.EQUAL, rhs=b[i])

   model.update()
   model.ModelSense = -1
   model.optimize()

请注意,我使用LinExpr()构造函数将所有术语一次添加到表达式中。