使用列表列表在 Python 中以广度优先方式遍历图

Posted

技术标签:

【中文标题】使用列表列表在 Python 中以广度优先方式遍历图【英文标题】:Traversing a Graph in Breadth First in Python Using a List of List 【发布时间】:2015-03-19 09:24:39 【问题描述】:

所以我已经看到很多使用字典来实现广度优先搜索。我只想知道是否可以使用列表列表遍历图表。然后返回父数组。 [每个顶点的父母。]如果是这样,怎么做?说,我有一个这样的邻接列表

  G =  [[(1, None), (2, None)], [(0, None)], []]

其中 G 是有向且未加权的图。因此NONE。否则它会有一个数字。 vertex(0) 与 vertex(1) 和 vertex(2) 都相邻。 Vertex(1) 仅与 vertex(0) 相邻。顶点 (2) 不与任何顶点相邻。

我应该先创建一个新的顶点列表吗?我应该摆脱体重吗?我不知道如何解决这个问题。你能帮忙的话,我会很高兴。谢谢

【问题讨论】:

如果图中的节点是从0到n的数字,那么将其表示为列表的列表或列表的字典实际上没有区别。 【参考方案1】:

当然,无论哪种方式都可以。您可以像这样表示您的图表:

g = [[1, 2], [0], []]

然后g[g[j][0]] 让您返回在jth 元素的邻接列表中排在第一位的顶点的邻接列表。列表列表与键为0,...,n 且值为ints 列表的字典之间没有区别,但在我看来,除非需要字典,否则列表是一个更明智的想法。如果没有重量,就没有理由为您的所有重量使用None

但是请注意,BFS 将要求您跟踪是否已访问顶点,您可以在跟踪父节点的同时进行:

parents = [None, None, None]

您通常还希望在访问节点时跟踪当前所处的深度(除非您只是在测试,例如连接性),您可以这样做:

import collections
Vertex = collections.namedtuple("Vertex", ["idx", "depth"])

现在,当您从队列中弹出一个顶点 v 时,您会遍历其邻接列表中的每个 u_idx。如果parents[u_idx] is None(尚未访问),则将Vertex(u_idx, v.depth + 1)推送到您的队列并标记parents[u_idx] = v

【讨论】:

感谢您的回复!我如何跟踪父节点? @RylaiCrestfall 我在解决方案中添加了。 @PatrickCollins,使用父数组来跟踪访问的顶点效果不佳,因为初始顶点在其父节点为 None 时被访问。 @citxx 然后将其父设置为自身。这是一个很小的问题。

以上是关于使用列表列表在 Python 中以广度优先方式遍历图的主要内容,如果未能解决你的问题,请参考以下文章

Python二叉树的三种深度优先遍历

networkx图论Depth First Search广度优先搜索遍历DFS,基于栈,Python

Java实现无向图的邻接列表表示,深度遍历及广度遍历

Python二叉树的三种深度优先遍历

图论广度优先搜索

广度优先bfs的python实现