邻接矩阵获取加速

问题

在原有图基础上,来了新的节点及边关系后如何能快速的得到新的邻接矩阵,并进行后续处理是比较重要的。如果说直接在原有图上进行边的添加,再基于图去生成邻接矩阵的话,这个耗时会是相当费时的。

import networkx as nx

origin_G = nx.read_gpickle('graph.pkl')  # 获得原始图
nodes = origin_G.nodes  # 图的所有节点

new_node = max(nodes) + 1  # 对于最新的节点而言,对其编码为原始节点中最大id节点+1
new_edges = [(new_node, 1), (new_node, 10), ...]

origin_G.add_edges_from(new_edges)  # 向图中添加新的边
new_adjacency = nx.adjacency_matrix(origin_G)  # 得到新的邻接矩阵

上述耗时根据图的大小不同,本人实验的图的话上述大概耗时10秒左右;

解决办法

有了原始图之后,我们可以直接从原始图得到原始的邻接矩阵,对于新的节点而言,我们可以直接对原始矩阵进行扩增列和行来表示新的邻接矩阵,基于边关系更改邻接矩阵中的值即可,不用进行复杂的往图中添加边,从图中获取邻接矩阵。

from scipy import sparse 

origin_adjacency = nx.adjacency_matrix(origin_G).toarray()  # 转化为ndarray进行处理,否则是scipy sparse格式

m, n = origin_adjacency.shape
row_pad = np.array([[0] * m])  # 增加空行
col_pad = np.array([[0] * (n+1)])  # 增加空列
tmp_adjacency = np.insert(origin_adjacency, m, values=row_pad, axis=0)  # 原始邻接矩阵末尾加一行全零值
new_adjacency = np.insert(tmp_adjacency, n, values=col_pad, axis=1)  # 在添加行的矩阵上最后一列多加一列全零值

for edge in new_edges:
    i, j = edge
    new_adjacency[i][j] = 1
    new_adjacency[j][i] = 1  # 无向图
new_adj = sparse.csr_matrix(new_adjacency)  # 转化为scipy sparse 格式   

上述耗时大约为 8 ∗ 1 0 − 7 8*10^{-7} 8107秒左右,从10秒加速了好几个量级,且二者得到的结果一样,保证了准确性提高了速度。

总结

虽然封装的方法使用起来非常方便快捷,但如果能够理解一些基础性的原理和操作的话,通过简单的加减乘除等操作处理能够在保证结果准确的前提下,大大提升速度。

参考

  • https://stackoverflow.com/questions/7922487/how-to-transform-numpy-matrix-or-array-to-scipy-sparse-matrix
  • https://stackoverflow.com/questions/26576524/how-do-i-transform-a-scipy-sparse-matrix-to-a-numpy-matrix
  • https://blog.csdn.net/tintinetmilou/article/details/78119320
  • https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.toarray.html

你可能感兴趣的:(图计算,邻接矩阵,图,python,network,稀疏矩阵)