Python BFS 与集合

发布于 2024-11-09 12:09:11 字数 708 浏览 3 评论 0原文

我遇到了 BFS 代码,其中涉及集合和双端队列,但我不太理解。我希望这里的一些 Python 爱好者可以帮助新手。

from collections import deque

def bfs(g, start):
    queue, enqueued = deque([(None, start)]), set([start])
    while queue:
        parent, n = queue.popleft()
        yield parent, n
        new = set(g[n]) - enqueued
        enqueued |= new
        queue.extend([(n, child) for child in new])

问题:

1) |= 运算符似乎与按位运算有关 - 我不知道它与 BFS 有何关系,有什么提示吗?

2) 据我了解,popleft()应该只返回一个值,那么它是如何返回parent和n的呢?

3) 访问的一系列节点是新的吗?如果我想要这些节点,我是否只需将它们附加到列表中?

提前致谢。

克雷格

I came across a BFS code which involves collections and deques but I could not understand it much. I hope some of the pythonistas here can help a n00b out.

from collections import deque

def bfs(g, start):
    queue, enqueued = deque([(None, start)]), set([start])
    while queue:
        parent, n = queue.popleft()
        yield parent, n
        new = set(g[n]) - enqueued
        enqueued |= new
        queue.extend([(n, child) for child in new])

Questions:

1) The |= operator seems to be related to bitwise operations - I have no idea how it relates to a BFS, any hints?

2) popleft() should return only one value from what I understand, so how is it returning parent and n here?

3) Is new the series of nodes visited? If I want the nodes, do I just keep appending them to a list?

Thanks in advance.

Craig

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

知你几分 2024-11-16 12:09:11
  1. a |= b 对于集合来说是相同的
    对于集合来说 a = a.union(b).

  2. popleft() 确实返回
    只有一个元素,恰好
    是一个 2 元组,因此可以是
    解压缩为两个值。

  3. new 是尚未的集合
    访问过的节点。

  1. a |= b for sets is the same
    as a = a.union(b).

  2. popleft() does indeed return
    only one element, which happens to
    be a 2-tuple, and therefore can be
    unpacked into two values.

  3. new is the set of not yet
    visited nodes.

甜`诱少女 2024-11-16 12:09:11

只是回答你的最后一个问题:你的代码片段有一个生成器,这意味着它在广度优先遍历图时会产生节点。它不执行任何实际搜索,只是为您遍历节点。使用这段代码的方式是迭代结果,这将依次为您提供所有节点(按广度优先顺序):

for parent_node, node in bfs(my_graph):
    if node == needle:
        break

或者,例如,如果您想要匹配特定条件的所有节点的列表:

nodes = [ node for parent_node, node in bfs(my_graph) if condition(node) ]

Just to answer your last question: the piece of code you have there is a generator, which means it yields nodes as it traverses the graph breadth-first. It doesn't do any actual searching, it just traverses the node for you. The way you use this piece of code is by iterating over the result, which will give you all nodes in turn (in breadth-first order):

for parent_node, node in bfs(my_graph):
    if node == needle:
        break

Or if you want, for example, a list of all nodes that match a particular condition:

nodes = [ node for parent_node, node in bfs(my_graph) if condition(node) ]
往昔成烟 2024-11-16 12:09:11

1)

x |= y 将 x 设置为 x 和 y 的布尔 OR。 set 覆盖运算符以表示集合并集。基本上,这是一种编写 enqueued.update(new) 的奇特方式。

2)

queue 的第一个元素始终是 2 元组。

tpl = (a,b)
x,y = tpl

是一种奇特的书写方式

tpl = (a,b)
assert len(tpl) == 2
x = tpl[0]
y = tpl[0]

3)

new 只是新的(未访问的)节点的临时变量。 enqueued 包含结果。

1)

x |= y sets x to the boolean OR of x and y. set overrides the operator to mean the set union. Basically, it's a fancy way of writing enqueued.update(new).

2)

The first element of queue is always a 2-tuple.

tpl = (a,b)
x,y = tpl

is a fancy way of writing

tpl = (a,b)
assert len(tpl) == 2
x = tpl[0]
y = tpl[0]

3)

new is just a temporary variable for - well - the new(unvisited) nodes. enqueued contains the result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文