python - Cplex中的Python稀疏矩阵?
问题描述
我正在研究一个大型二次规划问题。我想使用 Python API 将定义目标函数的 Q 矩阵输入 IBM 的 Cplex。Q 矩阵是使用 scipy lil 矩阵构建的,因为它是稀疏的。理想情况下,我想将矩阵传递给 Cplex。Cplex 是否接受 scipy lil 矩阵?
我可以将 Q 转换为 Cplex 接受的列表格式,我们称之为 qMat。但是 qMat 的大小变得太大,机器内存不足(即使是 120 Gig)。
以下是我正在进行的代码。在实际问题中,n 约为 50 万,m 约为 500 万。在实际问题中,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)
解决方案
如果n = 500000
和m = 5000000
,则为 2.5e12 个非零。对于其中的每一个,您大约需要一个double
用于非零值,一个CPXDIM
用于索引。即每个非零 8+4=12 个字节。这将给出:
>>> print(2.5e12 * 12 / 1024. / 1024. / 1024.)
27939.6772385
大约 28TB 内存!目前尚不清楚您计划拥有多少个非零,但使用此计算,您可以轻松找出是否可以按照您的要求进行操作。
如评论中所述,CPLEX Python API 不接受 scipy lil 矩阵。您可以尝试docplex,它对 numpy 友好,或者您甚至可以尝试直接生成LP 文件。
就减少转换开销而言,使用以下内容可能是您最好的选择(我认为我在上面的评论部分犯了一个错误):
my_prob.objective.set_quadratic(list(zip(Q.rows, Q.data)))
或者
my_prob.objective.set_quadratic([[row, data] for row, data in zip(Q.rows, Q.data)]))
无论如何,您应该使用这些来查看什么可以提供最佳性能(在速度和内存方面)。
推荐阅读
- functional-programming - 函数式编程术语:提升与函子/应用提升
- php - 如何创建 Codeigniter 路由
- erlang - Rebar3编译时如何添加额外的文件或目录?
- php - Symfony\Component\HttpKernel\Exception\HttpException 无消息 Laravel 5.6
- firebase - 在Firestore中使用云功能触发onCreate时如何使用事务更新数据?
- r - 读入复杂数组中的 .xrdml 数据
- google-apps-script - Apps 脚本错误 - 休假申请表
- node.js - 如何用观察者替换订阅者?
- android - 我的 ListView 未正确显示 - 如何解决?
- google-apps-script - GMail 插件中 ScriptApp 范围使用的替代方案