带有集合的Python BFS

时间:2011-05-25 12:24:02

标签: python graph breadth-first-search

我遇到了BFS code涉及收藏品和杂物,但我无法理解。我希望这里的一些pythonist可以帮助n00b。

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) new 是否访问了一系列节点?如果我想要节点,我是否只是将它们附加到列表中?

提前致谢。

克雷格

3 个答案:

答案 0 :(得分:2)

    集合的
  1. a |= b是相同的 为a = a.union(b)

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

  3. new还没有 访问过的节点。

答案 1 :(得分:1)

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

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) ]

答案 2 :(得分:0)

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包含结果。