如何将其存储在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
这些列表示:
顶点
和权重
。实现相邻列表的图论或数据结构方法如下:
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
类型(固定大小)不同,pythonlist
是一种可变类型,您可以在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))