从元组列表生成邻接矩阵的更优雅方法

And*_*jia 4 python graph function adjacency-matrix

假设我们从一个由元组列表表示的“友谊”图开始,

friendships = [(0, 1), (0, 2), (1, 2), (1, 3), (2,
3), (3, 4),(4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]
Run Code Online (Sandbox Code Playgroud)

其中元素0是1的朋友(因此1是0的朋友)。

我想以一种始终适用于这种元组表示形式的方式从头构造邻接矩阵。

我有以下(排斥)Python代码:

friendships = [(0, 1), (0, 2), (1, 2), (1, 3), (2,
3), (3, 4),(4, 5), (5, 6), (5, 7), (6, 8), (7, 8), (8, 9)]
Run Code Online (Sandbox Code Playgroud)

我知道它效率低下而且非常难看。有没有更聪明的方法来解决这个问题?我上面给出的示例列表的输出应为

[[0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [1, 0, 1, 1, 0, 0, 0, 0, 0, 0],
 [1, 1, 0, 1, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 0, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 1, 0, 0, 1, 0],
 [0, 0, 0, 0, 0, 1, 0, 0, 1, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0]]
Run Code Online (Sandbox Code Playgroud)

更新: 根据答案之一,我有以下可能的解决方案,尽管我不知道它是否更好

def make_matrix(num_rows,num_cols,entry_fn):
    return [[entry_fn(i,j)
             for j in range(num_cols)]
            for i in range(num_rows)]
def adjacency(connections):
    new=connections+[(x[1],x[0]) for x in connections]
    elements=list(set([x[0] for x in connections]+ [x[1] for x in connections]))
    def test(i,j):
        if (elements[i],elements[j]) in new:
            return 1
        else: return 0
    return make_matrix(len(elements),len(elements),test)
Run Code Online (Sandbox Code Playgroud)

Cod*_*ice 5

我的算法将是这样的:

  1. 查找最大顶点ID。叫这个n
  2. 创建一个零的n+1by n+1数组。叫这个M
  3. 对于x, y输入列表中的每对,设置M[x][y] = 1

为了提出这个解决方案,我首先想到了步骤3。使用给定的输入,这似乎是填充邻接矩阵的最直接方法。但是,它需要固定大小的2D数组。因此,问题在于我如何n确定步骤2。从那里开始,不需要太多的精力就可以确定步骤1是什么。

这些细节留给读者练习。