Python 从元组列表生成邻接矩阵的更优雅的方法
假设我们从一个由元组列表表示的“友谊”图开始Python 从元组列表生成邻接矩阵的更优雅的方法,python,function,graph,adjacency-matrix,Python,Function,Graph,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)] 其中元素0是1的朋友(因此1是0的朋友) 我想从头开始构建邻接矩阵,,这种方法将始终适用于这种元组表示 我有以下(令人厌恶的)Python代码: def make_矩阵(行数、列数、条目数): 返回[[输入法]fn(i,j) 对于范
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)]
其中元素0是1的朋友(因此1是0的朋友)
我想从头开始构建邻接矩阵,,这种方法将始终适用于这种元组表示
我有以下(令人厌恶的)Python代码:
def make_矩阵(行数、列数、条目数):
返回[[输入法]fn(i,j)
对于范围内的j(num_cols)]
对于范围内的i(num_行)]
def邻接(连接):
新建=连接+[(x[1],x[0]),用于连接中的x]
元素=列表(设置([x[0]用于连接中的x]+[x[1]用于连接中的x]))
def测试(i,j):
如果(元素[i],元素[j])处于新的状态:
返回1
其他:返回0
返回make_矩阵(len(元素),len(元素),测试)
我知道这是低效和非常丑陋的。有没有更聪明的方法来解决这个问题?我上面给出的示例列表的输出应该是
[[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]]
更新:
根据其中一个答案,我有以下可能的解决方案,尽管我不知道是否更好
def调整(连接):
##第一步
temp=(为连接中的元素设置(元素[0])。并集(
设置(elem[1]用于连接中的elem)))
n=最大(温度)+1
ans=[]
##步骤2
对于i,uu在枚举中(临时):
ans.append([])
对于j,枚举中的u(临时):
ans[i]。追加(0)
##步骤3
对于成对输入连接:
ans[pair[0]][pair[1]]=1
ans[pair[1]][pair[0]]=1
返回ans
我的算法是这样的:
n
n+1
零数组创建n+1
。称之为M
x,y
,设置M[x][y]=1
n
。从这里不需要太多的思考就可以看出第1步是需要的
详细信息留给读者作为练习。如果您想要简短易读的解决方案(并且计划稍后使用graph),我建议您使用库。您的问题可以通过两条线来解决:
import networkx as nx
G = nx.Graph()
G.add_edges_from(friendships)
nx.to_numpy_matrix(G)
它将返回numpy矩阵:
matrix([[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.]])
或
nx.邻接矩阵(G)
将返回scipy稀疏矩阵:
<10x10 sparse matrix of type '<class 'numpy.int64'>'
with 24 stored elements in Compressed Sparse Row format>
我会:
import numpy as np
def adjacency(connections):
n_people = max(sum(connections, ())) + 1
mat = np.zeros((n_people, n_people), dtype='int')
for friend1, friend2 in connections:
mat[friend1, friend2] = 1
mat[friend2, friend1] = 1
return mat
如果“从头开始”的意思是你不想使用numpy:
def adjacency(connections):
n_people = max(sum(connections, ())) + 1
mat = [[0 for _ in range(n_people)] for _ in range(n_people)]
for friend1, friend2 in connections:
mat[friend1][friend2] = 1
mat[friend2][friend1] = 1
return mat
我不是一个Python程序员,但有点像
def to_adjacency_matrix(pairs):
size = 1 + max(map(max, pairs))
a = [[0 for j in range(size)] for i in range(size)]
for i, j in pairs:
a[i][j] = a[j][i] = 1
return a
你提前知道顶点的数量吗?@Code peedient no,这是挑战的一部分,也是我从头开始在middlefrom中定义总元素的原因-这是否意味着你实际上只在寻找本机解决方案,而库已经不存在了?@paritossingh是的。我对具有可调用的邻接函数的图形/网络库不感兴趣。
n
应该比最大值多一个ID@TavianBarnes或者,数组的维度应该比n
@AndresMejia多一个是的,该代码看起来非常接近地翻译了我的伪代码。然而,逻辑上有一个缺陷。例如,如果连接
是[(1,2)、(5,3)]
,那么n
应该是6。我把它作为练习留给你去发现问题。你可能会发现这很有帮助。@AndresMejia“我仍然有一种唠叨的怀疑,那就是它并不像可能的那么好”这种感觉会困扰你,不管你编写了多长时间的代码。我们只是随着经验的积累而提高,有时“足够好”就足够好了。@Code学徒好吧,也许你是对的。我将继续:)另外,您对大小的计算不太正确。例如,如果pairs=[(1,10)、(5,2)]
则将分配大小6
,而不是11
的正确值。注意reduce(max,foo)
相当于max(foo)
。提示:对于初始化a
,可以使用*
操作符简化内部列表理解a=[[0]*size]for i in-range(size)]
@code peedient抱歉键入reduce
在思考map
@code peedient时,我也确实最初编写了[[0]*size]
,然后对其进行了更改。不能说[[0]*size]*size
,因为这是对同一数组的引用数组。因此,上面的方法似乎更简单。