简体   繁体   English

Cplex中的Python稀疏矩阵?

[英]Python sparse matrix in Cplex?

I am working on a large quadratic programming problem.我正在研究一个大型二次规划问题。 I would like to feed in the Q matrix defining the objective function into IBM's Cplex using Python API.我想使用 Python API 将定义目标函数的 Q 矩阵输入到 IBM 的 Cplex 中。 The Q matrix is built using scipy lil matrix because it is sparse. Q 矩阵是使用 scipy lil 矩阵构建的,因为它是稀疏的。 Ideally, I would like to pass the matrix onto Cplex.理想情况下,我想将矩阵传递给 Cplex。 Does Cplex accept scipy lil matrix? Cplex 是否接受 scipy lil 矩阵?

I can convert the Q to the format of list of lists which Cplex accepts, lets call it qMat.我可以将 Q 转换为 Cplex 接受的列表列表格式,我们称之为 qMat。 But the size of qMat becomes too large and the machine runs out of memory (even with 120 Gig).但是 qMat 的大小变得太大,机器内存不足(即使有 120 Gig)。

Below is my work in progress code.以下是我正在进行的工作代码。 In the actual problem n is around half a million, and m is around 5 million.在实际问题中,n 大约为 50 万,m 大约为 500 万。 In the actual problem Q is given and not randomly assigned as in the problem below.在实际问题中,Q 是给定的,而不是像下面的问题那样随机分配。

from __future__ import division
import numpy as np
import cplex
import sys
import random
from scipy import sparse

n = 10
m = 5

def create():
    Q = sparse.lil_matrix((n, n))
    nums = random.sample(range(0, n), m)
    for i in nums:
        for j in nums:
            a = random.uniform(0,1)
            Q[i,j] = a
            Q[j,i] = a
    return Q

def convert(Q):
    qMat = [[[], []] for _ in range(n)]
    for k in xrange(n-1):
        qMat[k][0] = Q.rows[k]
        qMat[k][1] = Q.data[k]
    return qMat

Q = create()
qMat = convert(Q)
my_prob = cplex.Cplex()
my_prob.objective.set_quadratic(qMat)

If n = 500000 and m = 5000000 , then that is 2.5e12 non-zeroes.如果n = 500000m = 5000000 ,则为 2.5e12 个非零值。 For each of these you'd need roughly one double for the non-zero value and one CPXDIM for the index.对于这些中的每一个,非零值大约需要一个double CPXDIM值,索引需要一个CPXDIM That is 8+4=12 bytes per non-zero.即每个非零 8+4=12 个字节。 This would give:这将给出:

>>> print(2.5e12 * 12 / 1024. / 1024. / 1024.)
27939.6772385

Roughly, 28TB of memory!大约 28TB 的内存! It's not clear exactly how many non-zeros you plan on having, but using this calculation you can easily find out whether it is even possible or not to do what you're asking.目前尚不清楚您计划拥有多少个非零值,但使用此计算,您可以轻松找出是否有可能执行您所要求的操作。

As mentioned in the comments, the CPLEX Python API does not accept scipy lil matrices.如评论中所述,CPLEX Python API 不接受 scipy lil 矩阵。 You could trydocplex , which is numpy friendly, or you could even try generating an LP file directly.您可以尝试docplex ,它对 numpy 友好,或者您甚至可以尝试直接生成LP 文件

Using something like the following is probably your best bet in terms of reducing the conversion overhead (I think I made an off-by-one error in the comments section above):就减少转换开销而言,使用类似以下内容可能是您最好的选择(我想我在上面的评论部分犯了一个错误):

my_prob.objective.set_quadratic(list(zip(Q.rows, Q.data)))

or或者

my_prob.objective.set_quadratic([[row, data] for row, data in zip(Q.rows, Q.data)]))

At any rate, you should play with these to see what gives the best performance (in terms of speed and memory).无论如何,您应该使用这些来查看什么可以提供最佳性能(在速度和内存方面)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM