【问题标题】:What is an efficient way to convert an adjacency matrix to a dictionary?将邻接矩阵转换为字典的有效方法是什么?
【发布时间】:2019-02-18 17:28:48
【问题描述】:

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

示例矩阵:

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

【问题讨论】:

  • 您只访问每个邻接点一次。这大约和它的速度一样快。库不是免费的性能。仅仅因为你没有看到这些操作并不意味着它们更有效率。

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


【解决方案1】:

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

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

随机 1000x1000 矩阵的时序:

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

【讨论】:

    【解决方案2】:

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

    {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 倍。

    【讨论】:

    • @djennacs 没问题。我不确定加速来自哪里——可能是因为它一次构建所有对象而不是附加项目。我已经尝试过使用numpy.nonzero 的解决方案,但只是调用此函数并迭代其结果(不构建任何字典)已经比我的解决方案花费更长的时间(0.15 秒),所以我认为这种方法不会有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 2015-12-22
    相关资源
    最近更新 更多