如何从列表中创建邻接矩阵?

时间:2018-05-17 17:54:34

标签: python list adjacency-matrix

我有一个列表:

#include <iostream>

class test
{
    int a, b;

public:
    static float f;
};

float test::f;

int main()
{
    test::f = 3.14;
    std::cout << f;
}

(它比这大得多),第一项和第二项实际上是节点名称,第三项是它们之间的边缘权重(我没有制作图表,但是&#39; sa list)。

我想在此列表中创建一个邻接矩阵。

3 个答案:

答案 0 :(得分:2)

是的,您可以使用defaultdict

执行此操作
In [1]: in_list =  [['10', '20', 2], ['10', '21', 2], ['10', '1', 2], ['10', '0', 3], ['10', '3', 2], ['10'
   ...: , '2', 2], ['10', '5', 3], ['10', '4', 3], ['10', '7', 2], ['10', '6', 2], ['10', '9', 2], ['10', '
   ...: 8', 2], ['10', '11', 2], ['10', '10', 2], ['10', '13', 2], ['10', '12', 2], ['10', '15', 2], ['10',
   ...:  '14', 2], ['10', '17', 0], ['10', '16', 3], ['10', '19', 2], ['10', '18', 2], ['1', '20', 3], ['1'
   ...: , '21', 3], ['1', '1', 3], ['1', '0', 0], ['1', '3', 3], ['1', '2', 3], ['1', '5', 4], ['1', '4', 4
   ...: ], ['1', '7', 3], ['1', '6', 3], ['1', '9', 3], ['1', '8', 3], ['1', '11', 3], ['1', '10', 3], ['1'
   ...: , '13', 3], ['1', '12', 3], ['1', '15', 3]]                                                        

In [2]: from collections import defaultdict

In [3]: tree = lambda: defaultdict(tree)

In [5]: adj_mat = tree()

In [6]: for edge in in_list:
   ...:     start, end, weight = edge
   ...:     adj_mat[start][end] = weight
   ...:                                 

In [7]: adj_mat
Out[7]:        
defaultdict(<function __main__.<lambda>>,
            {'1': defaultdict(<function __main__.<lambda>>,
                         {'0': 0,                          
                          '1': 3,                          
                          '10': 3,                         
                          '11': 3,                         
                          '12': 3,                         
                          '13': 3,                         
                          '15': 3,                         
                          '2': 3,                          
                          '20': 3,                         
                          '21': 3,                         
                          '3': 3,                          
                          '4': 4,                          
                          '5': 4,                          
                          '6': 3,
                          '7': 3,
                          '8': 3,
                          '9': 3}),
             '10': defaultdict(<function __main__.<lambda>>,
                         {'0': 3,
                          '1': 2,
                          '10': 2,
                          '11': 2,
                          '12': 2,
                          '13': 2,
                          '14': 2,
                          '15': 2,
                          '16': 3,
                          '17': 0,
                          '18': 2,
                          '19': 2,
                          '2': 2,
                          '20': 2,
                          '21': 2,
                          '3': 2,
                          '4': 3,
                          '5': 3,
                          '6': 2,
                          '7': 2,
                          '8': 2,
                          '9': 2})})

当我实现这一点时,我注意到你的所有边缘都来自1或10.嗯,很奇怪。

<强> 解释

  1. defaultdict只是一个活泼的哈希映射的名字(如果你来自perl背景)
  2. 矩阵中的条目是边权重
  3. 如果边缘是双向的,则只需在for循环中添加adj_mat[end][start] = weight

答案 1 :(得分:2)

通常,除非某些约束强迫您使用vanilla Python,否则您应该将NumPy用于矩阵。 NumPy非常有效地处理矩阵。

此外,如果您决定使用NumPy(并且您应该),这是过去曾为该库提出的问题:numpy/scipy build adjacency matrix from weighted edgelist

答案 2 :(得分:0)

def make_adj_matrix(data, directed=False):
    summary = {}
    result = []
    nodes = []

    for start, end, weight in data:
        # store nodes names for further use
        if start not in nodes:
            nodes.append(start)
        if end not in nodes:
            nodes.append(end)

        # collect and sum all weights
        summary.setdefault(start, {}).setdefault(end, 0)
        summary[start][end] += weight
        if not directed:
            summary.setdefault(end, {}).setdefault(start, 0)
            summary[end][start] += weight

    # # here you can sort your nodes
    # nodes.sort()

    # constructing result
    for i in nodes:
        row = []
        for j in nodes:
            row.append(summary.get(i, {}).get(j, 0))
        result.append(row)

    return result