在Gurobi中提高约束添加的性能(Python-Interface)

时间:2016-08-06 03:29:06

标签: python constraints linear-programming gurobi

我得到了这个决定变量:

x={}
for j in range(10):
    for i in range(500000):
        x[i,j] = m.addVar(vtype=GRB.BINARY, name="x%d%d" %(i,j))

所以我需要为每个x [i,j]变量添加约束,如下所示:

for p in range(10):
    for u in range(500000):
        m.addConstr(x[u,p-1]<=x[u,p])

这花了我很多时间,更多的是12小时,然后我的电脑上出现了缺少内存弹出窗口。 有人可以帮助改善这个约束添加问题

2 个答案:

答案 0 :(得分:2)

最有可能的是,您的物理内存不足并使用虚拟(交换)内存。这不会导致您的计算机报告内存不足警告或错误。

我重写了你的代码如下:

from gurobipy import *

m = Model()

x={}
for j in range(10):
  for i in range(500000):
    x[i,j] = m.addVar(vtype=GRB.BINARY, name="x%d%d" %(i,j))
m.update()

for p in range(10):
  for u in range(500000):
    try:
      m.addConstr(x[u,p-1]<=x[u,p])
    except:
      pass
m.update()

我在使用Intel Xeon E3-1240处理器(3.40 GHz)和32 GB物理内存的计算机上使用Gurobi Optimizer 6.5.2对此进行了测试。它能够在1分14秒内制定变量和约束。您可以使用列表保存少量内存,但我相信Gurobi Var和Constr对象需要比Python字典或列表更多的内存。

答案 1 :(得分:1)

一般评论:

  • 一般来说,添加500万个约束看起来非常昂贵

具体备注:

方法

  • 您正在使用词典浪费时间和空间
    • 尽管具有持续访问的复杂性,但这些常量很大
    • 他们也在浪费记忆
  • 在这样一个简单的二维案例中:坚持阵列!

有效期

  • 您的索引缺少第一个元素的border-case,因此索引中断了!

试试这个(更有效的方法;使用numpy的数组):

import numpy as np
from gurobipy import *

N = 10
M = 500000

m = Model("Testmodel")
x = np.empty((N, M), dtype=object)
for i in range(N):
    for j in range(M):
        x[i,j] = m.addVar(vtype=GRB.BINARY, name="x%d%d" %(i,j))
m.update()

for u in range(M):  # i switched the loop-order
    for p in range(1,N):  # i'm handling the border-case
        m.addConstr(x[p-1,u] <= x[p,u])

<强>结果:

  • ~2分钟
  • ~2.5GB 内存(包括Gurobi内部的完整程序)