Python中的邻接矩阵

时间:2015-04-06 01:34:37

标签: python adjacency-matrix

我无法找到任何关于如何在Python中创建邻接矩阵的明确解释,并考虑了权重。我认为创建它应该相对简单。

我有以下矩阵......

   1   2   3   4   5   6
1  0   15  0   7   10  0
2  15  0   9   11  0   9
3  0   9   0   0   12  7
4  7   11  0   0   8   14
5  10  0   12  8   0   8
6  0   9   7   14  8   0

数字1到6是顶点,其中的数字是每个相邻顶点之间的权重。例如,边缘1-2具有重量15。

我如何在python中实现它?我只需要一个简单的例子,不一定要使用我提供的那个。

我知道如何创建邻接列表......

graph = {'1': [{'2':'15'}, {'4':'7'}, {'5':'10'}],
    '2': [{'3':'9'}, {'4':'11'}, {'6':'9'}],
    '3': [{'5':'12'}, {'6':'7'}],
    '4': [{'5':'8'}, {'6':'14'}],
    '5': [{'6':'8'}]}

但我需要一个邻接矩阵。

5 个答案:

答案 0 :(得分:3)

我喜欢python中的二维结构的tupled键。

{(1, 1): 0, (3, 2): 9... }

我认为它在概念上最清晰,因为它丢弃了上述解决方案中的中间数据结构。尽管如此,如果您打算以行或列方式访问结构,那么中间数据结构(内部列表或行/列)可能很有用。

 for x, row in enumerated(matrix, 1):
       # process whole row 
       for y in enumerate(row, 1):
             # process cell...

如果细胞方式的数据访问是你的游戏,那么为了表达简单,很难击败以下内容:

for (x, y), value in matrix.iteritems():
      # act on cell

如果你愿意,可以对它进行排序。

 # (1, 1), (1, 2)...
 for (x, y), value in sorted(matrix.iteritems()):
       # act on cell

答案 1 :(得分:2)

我认为存储邻接矩阵的最常见和最简单的概念是使用2D数组,在python中对应嵌套列表

mat = [[0, 15, 0, 7, 10, 0], [15, 0, ...], [...], [...]]
m[0][1]  # = 15 (weight of 1-2)

如果值是只读的,则可以使用嵌套元组,而不是:)

当然,你可以随心所欲地使用词典或写一个类并重新定义__getattr__,以便在访问时间和存储方面更有效率,因为矩阵是对称的。

答案 2 :(得分:2)

这将转换您的"邻接列表" (真的是一个字典,而不是列表)变成一个真正的矩阵:

import networkx as nx

graph = {'1': [{'2':'15'}, {'4':'7'}, {'5':'10'}],
    '2': [{'3':'9'}, {'4':'11'}, {'6':'9'}],
    '3': [{'5':'12'}, {'6':'7'}],
    '4': [{'5':'8'}, {'6':'14'}],
    '5': [{'6':'8'}]}
new_graph = nx.Graph()
for source, targets in graph.iteritems():
    for inner_dict in targets:
        assert len(inner_dict) == 1
        new_graph.add_edge(int(source) - 1, int(inner_dict.keys()[0]) - 1,
                           weight=inner_dict.values()[0])
adjacency_matrix = nx.adjacency_matrix(new_graph)

graph的格式在networkx中使用并不是特别方便。)networkx支持对图形及其邻接矩阵的各种操作,因此请在此图中使用格式应该对你很有帮助。另请注意,我已将图表转换为使用Python索引(即从0开始)。

In [21]: adjacency_matrix
Out[21]: 
matrix([[  0.,  15.,   0.,   7.,  10.,   0.],
        [ 15.,   0.,   9.,  11.,   0.,   9.],
        [  0.,   9.,   0.,   0.,  12.,   7.],
        [  7.,  11.,   0.,   0.,   8.,  14.],
        [ 10.,   0.,  12.,   8.,   0.,   8.],
        [  0.,   9.,   7.,  14.,   8.,   0.]])

答案 3 :(得分:1)

如前所述,在Python中处理矩阵的标准方法是使用NumPy。这是一个简单地从邻接列表中读取邻接矩阵的函数。 (节点的隐式排序由参数nodes显式化。)

import numpy

def weighted_adjmatrix(adjlist, nodes):
    '''Returns a (weighted) adjacency matrix as a NumPy array.'''
    matrix = []
    for node in nodes:
        weights = {endnode:int(weight)
                   for w in adjlist.get(node, {})
                   for endnode, weight in w.items()}
        matrix.append([weights.get(endnode, 0) for endnode in nodes])
    matrix = numpy.array(matrix)
    return matrix + matrix.transpose()

在这种情况下,weighted_adjmatrix(graph, nodes=list('123456'))给出NumPy数组

array([[ 0, 15,  0,  7, 10,  0],
       [15,  0,  9, 11,  0,  9],
       [ 0,  9,  0,  0, 12,  7],
       [ 7, 11,  0,  0,  8, 14],
       [10,  0, 12,  8,  0,  8],
       [ 0,  9,  7, 14,  8,  0]])

如果需要常规列表,可以调用方法tolist()

答案 4 :(得分:0)

    [Op.and]: {
        [Op.or]: [{x: 1}, {x: 1}],
        [Op.or]: [{y}, {y}]
    }