如何将其存储在python中图形的邻接列表中?

如何将其存储在python中图形的邻接列表中?,python,adjacency-list,Python,Adjacency List,假设我有一个包含以下内容的文本文件: 0 1 4 0 2 3 1 4 7 5 3 8 这些列表示: 顶点 另一个顶点 这两个顶点之间的距离 例如,在文本文件的第一行中,4是点0和点1之间的距离 那么,在python中如何将顶点和距离存储在邻接列表中呢?在图论中,an是一组无序列表,用于表示图形。每个列表描述图中顶点的邻域集 因为您正在讨论加权图的相邻列表,所以需要定义一个结构来存储顶点和权重。实现相邻列表的图论或数据结构方法如下: class Node(): def __init__(

假设我有一个包含以下内容的文本文件:

0 1 4
0 2 3
1 4 7
5 3 8
这些列表示:

  • 顶点
  • 另一个顶点
  • 这两个顶点之间的距离 例如,在文本文件的第一行中,4是点0和点1之间的距离

    那么,在python中如何将顶点和距离存储在邻接列表中呢?

    在图论中,an是一组无序列表,用于表示图形。每个列表描述图中顶点的邻域集

    因为您正在讨论加权图的相邻列表,所以需要定义一个结构来存储
    顶点
    权重
    。实现相邻列表的图论或数据结构方法如下:

    class Node():
        def __init__(self, v, w, next=None):
            self.v = v
            self.w = w
            self.next = next
        ...
    
    class LinkedList():
        def __init__(self, head=None)
            self.head = head
    
        def add_node():
            pass
        ...
    
    这里,
    节点
    类是组成
    链接列表
    的基本元素,
    链接列表
    用于表示一个顶点的相邻列表。我不会为你实现整个课程。看

    假设您的图形是有方向的,则此图形的相邻列表为:

    0 -> [1:4]-> [2:3]
    1 -> [4:7]
    2 -> []
    3 -> []
    4 -> []
    5 -> [3:8]
    
    其中,
    0->[1:4]->[2:3]
    表示顶点
    0
    的相邻列表,该列表包含两条边:
    0->1
    带权重
    4
    0->2
    带权重
    3
    <代码>[1:4]可以用class
    节点来描述,整行可以用class
    链接列表来表示。查看更多信息

    要表示整个图形,只需使用
    LinkedList
    列表,例如

    g = [LinkedList_for_0, LinkedList_for_1, ...]
    
    在这种方法中,
    g[i]
    将是顶点
    i
    的相邻列表

    要构建整个图形,可以迭代所有边:

    g = [[] for v in range(number_of_vertex)]
    for f, t, w in edges:
        g[f].add_node(Node(t,w))
    
    如上所述,实现相邻列表是一种更具数据结构的方式。如果你想练习你对数据结构和图论知识的理解,你可以试试这种方法。但是,实际上,与
    C/C++
    array
    类型(固定大小)不同,python
    list
    是一种可变类型,您可以在python
    列表上执行添加、删除等操作。因此,
    LinkedList
    实际上是不必要的。我们可以用一种类似于Python的方式重新定义这些类:

    class Node():
        def __init__(self, v, w):
            self.v = v
            self.w = w
    
    这里,
    节点
    类不包含
    next
    成员。因此,相邻列表可以表示为
    节点的列表,例如,顶点的相邻列表
    0

    [Node(1,4), Node(2,3)]
    
    整个图可以表示为一个二维列表(这里我们假设这是一个无向图):

    python way算法:

    g = [[] for v in range(number_of_vertex)]
    for f,t,w in edges:
        g[f].append(Node(t,w))
        g[t].append(Node(f,w))
    
    注意:需要为边的两端添加新节点

    实际上,在处理图问题时,我认为边列表或稀疏矩阵是最常见的表示形式。如果可能的话,我建议你使用这种表示法


    谢谢。

    嵌套字典是表示邻接列表的自然方式。字典在这种情况下很方便,因为它们比列表更好地表示稀疏映射,并允许高效查找

    adjacency_list = {}
    for line in open(file):
        from, to, weight = map(int, line.split())
        adjacency_list.setdefault(from, {})[to] = weight
        adjacency_list.setdefault(to, {})[from] = weight  # for undircted graph add reverse edges
    
    要获得节点
    i
    j
    之间的边的权重,您需要查找
    邻接列表.get(i,{}).get(j)
    (如果边不存在,将返回
    None

    如果您不想处理
    setdefault
    get
    ,您可能希望至少对顶级字典使用
    defaultdict
    。如果您使用
    adjacence\u list=defaultdict(dict)
    进行初始化,那么设置权重的方法就是
    adjacence\u list[from][to]=weight
    (内部字典将在需要时自动创建)。

    看看这个库,它非常棒,而且易于使用

    从中,可以使用边属性存储任何感兴趣的值-距离,在您的情况下:

    边通常具有与其关联的数据任意数据可以作为边属性与边关联。如果数据是数字且目的是表示加权图,则对属性使用“权重”关键字。某些图形算法,如Dijkstra的最短路径算法,使用此属性名称获取每条边的权重

    在您的情况下,一种可能的实施方式是:

    import networkx as nx
    
    G=nx.Graph()
    
    for line in file:
        a, b, w = map(int, line.strip().split(' '))
        G.add_edge(a, b, weight=w)
    

    您可以将此脚本用于加权图

    from collections import defaultdict
    
    adj = defaultdict(list)
    
    content = open('input.txt', 'r').readlines()
    
    for line in content:
        u, v, w = map(int, line.strip().split(' '))
        # if edge is on-way
        adj[u].append((v, w))
        # otherwise,
        adj[u].append((v, w))
        adj[v].append((u, w))
    

    非常感谢你!如果我的图是无向的怎么办?如果你的图是无向的,当你在一条边上迭代
    a,b,w
    时,你应该为顶点
    a
    的相邻列表添加一个新节点
    [b,w]
    ,为顶点
    b
    的相邻列表添加一个新节点
    [a,w]
    。你可能应该删除关于链接列表的第一部分。看起来您的第二部分使用了一个名为Node的边。@KennyOstrom第一部分试图用数据结构的方式描述这个问题。关于命名:顶点的相邻列表
    v
    是一个相邻列表,它们是顶点。在第二部分中,顶点
    f
    的相邻列表表示为
    [节点(t1,w1),节点(t2,w2)]
    <代码>节点(t1,w1)
    表示顶点
    t1
    是顶点
    f
    的邻居,边
    加权
    w1
    @KennyOstrom。第一部分是这个答案中最有趣的部分。它讲述了构建邻接列表的基本方法(这就是我们研究数据结构的原因),第二部分只是对第一部分的抽象,
    from collections import defaultdict
    
    adj = defaultdict(list)
    
    content = open('input.txt', 'r').readlines()
    
    for line in content:
        u, v, w = map(int, line.strip().split(' '))
        # if edge is on-way
        adj[u].append((v, w))
        # otherwise,
        adj[u].append((v, w))
        adj[v].append((u, w))