【发布时间】:2014-04-28 12:28:19
【问题描述】:
我有一个有 1034 个顶点和 53498 个边的无向图。我正在计算顶点的优先附件索引。两个顶点之间的优先连接相似度定义为第一个顶点的度数乘以第二个顶点的度数的乘积。我注意到我的计算速度很慢。计算上述图表需要 2.7 分钟。我不确定是我的算法速度慢还是其他问题。如果有人能看一下我的代码,我将非常感激。
编辑:我刚刚意识到 S 是一个 1034_by_1034 矩阵。查看嵌套的 for 循环,它似乎是一个 O(n^2) 算法!我想这就是为什么它很慢。你不同意吗?
def pa(graph):
"""
Calculates Preferential Attachment index.
Returns S the similarity matrix.
"""
A = gts.adjacency(graph)
S = np.zeros(A.shape)
for i in xrange(S.shape[0]):
for j in xrange(S.shape[0]):
i_degree = graph.vertex(i).out_degree()
j_degree = graph.vertex(j).out_degree()
factor = i_degree * j_degree
S[i,j] = factor
return S
【问题讨论】:
-
我不懂python。也许您可以将所有 out_degree(x) 保存在一个数组中。然后做乘法。
-
我认为这取决于
out_degree()函数是如何实现的。如果是O(1),我相信它会很快完成。 -
一般来说,python 中的 for 循环不适合数字内容。如果您可以将这些 for 循环下推到 numpy 级别(或使用 numba/cython),您可以期待大幅加速。在 numpy 中,大多数事情都可以在没有 for 循环的情况下完成,通过在某些方法上使用轴参数,或者只是巧妙地使用索引。如果你展示那个 graph_vertex(i).out_degree() 方法,我们可能会加快很多
-
确实是
O(N^2)操作。但是 100 万个元素对于计算机来说仍然很小,它应该在一秒钟内完成,考虑到它只是你的代码需要的乘法。绝对out_degree()部分需要很长时间。可以尝试将i_degree和j_degree部分换成常量看看效果。 -
我认为说“由于这个算法是
O(N^2),它很慢”是一个逻辑谬误,因为它取决于输入大小。在这种情况下,对于O(N^2)算法,只有数千的输入大小仍然在一秒钟内运行。在你的情况下,我相信它在其他部分很慢。您是否仅使用以下语句运行该函数?A = gts.adjacency(graph)
标签: python performance algorithm numpy graph