如何通过Python中的矢量计算加快大型稀疏矩阵矢量?

时间:2018-08-08 14:19:24

标签: python performance vector graph sparse-matrix

我有一个用稀疏节点-节点矩阵M表示的图。如果在Node [i]和Node [j]之间存在边,则M(i,j)处的项> 0。矩阵中有圆圈(循环)。但这是一个流量控制问题。下面的代码描述了以下情况:有A,B,C,D和E节点。边缘列表:

  • A到B:2
  • B到C:3
  • B到D:3
  • 从C到A:4
  • E到A:1

在这种情况下,存在一个循环:A-> B-> C-> A。但是,如果我想知道E的最远节点,则它是A,因为B是A和D,对于C是A。因此,我们不算两次边(从A到B),因为它的边值比循环中最大(为4)。

我有一个代码,但是很慢。节点数> 100k,但矩阵非常稀疏,最大outDegree为<20。

这只是一个虚拟数据集。在我们的服务器上,对1行的计算运行了大约30秒。因此,一跳(距离)的总时间超过100k *〜30sec,但是我需要计算至少5跳。只是无尽的:(任何想法都非常感谢!

from datetime import datetime
from scipy.sparse import csr_matrix
from scipy.sparse import lil_matrix

d = datetime.now()
d0 = d
n = 100000 # 200000
row  = np.array([0, 1, 1, 2, 4])
col  = np.array([1, 2, 3, 0, 0])
data = np.array([2, 3, 3, 4, 1])
M1 = csr_matrix((data, (row, col)), shape=(n, n))
M2 = M1.T.tocsr()

R = lil_matrix((n,n), dtype = int)


i = 0
for i in range(5): # <----------------------- just 5 rows to track time
    v1 = M1[i, :]
    if v1.nnz > 0:
        for j in range(n):
            v2 = M2[j, :]
            if v2.nnz > 0:
                v = [ v2[0, k] for k in range(n) if (0 < v1[0, k] < v2[0, k])]
                if len(v) > 0: R[i, j] = max(v)
    print(datetime.now()-d)
    d = datetime.now()
print("Total time: {}".format(datetime.now()-d0))
print(R)

0 个答案:

没有答案