将邻接矩阵转换为字典的有效方法是什么?

时间:2018-09-13 23:01:52

标签: python dictionary for-loop adjacency-matrix adjacency-list

我想知道什么是将邻接矩阵隐藏到表示一个节点与另一个节点之间的连接的字典的有效方法吗?

示例矩阵:

matrix = [
[0,1,0,0,0,0],
[0,0,0,0,0,0],
[0,1,0,1,0,0],
[0,0,0,0,0,0],
[0,0,0,1,0,1],
[1,0,0,0,0,0]
]

示例输出:

{0: [1], 1: [], 2: [1, 3], 3: [], 4: [3, 5], 5: [0]}

下面的代码实际上生成了正确的输出;但是,我认为效率很低,因为我使用了两个for循环。有什么方法可以在不使用任何库的情况下优化代码?请让我知道,谢谢!

def convertAdjMatrixtoDict(m):

    graph = {}
    for idx, row in enumerate(m):
        res = []
        for r in range(len(row)):
            if row[r] != 0:
                res.append(r)
            graph[idx] = res
    return graph

2 个答案:

答案 0 :(得分:2)

这是一个更Python化的解决方案,可能会更快一些。

{i: [j for j, adjacent in enumerate(row) if adjacent] for i, row in enumerate(matrix)}

我怀疑您使用原始Python会更快。我会考虑是否存在利用numpy之类的快速库的解决方案。

更新:我使用以下命令为两种解决方案计时。

import numpy as np

# Make a big example
num_nodes = 1000
matrix = np.random.randint(0, 2, [num_nodes, num_nodes])

# Convert to raw Python
matrix = [[element for element in row] for row in matrix]

您的解决方案花了0.62秒,我的花了0.12秒。因此,实际上速度提高了约5倍。

答案 1 :(得分:2)

通过使用NumPy在每一行中定位非零元素,您可以获得更好的性能:

import numpy as np
{i: np.nonzero(row)[0].tolist() for i,row in enumerate(matrix)}

1000x1000随机矩阵的时间:

  1. 原始代码:310ms
  2. @Denxiloe的代码:91ms
  3. 此代码:20毫秒