【问题标题】:Small BFS Detail Clarification小型 BFS 详细说明
【发布时间】:2017-02-04 14:57:27
【问题描述】:

标准的 bfs 实现类似于(由 Wikipedia 提供):

 Breadth-First-Search(Graph, root):
    create empty set S
    create empty queue Q      
    root.parent = NIL
    Q.enqueue(root)                      
    while Q is not empty:
        current = Q.dequeue()
        if current is the goal
            return current
        for each node n that is adjacent to current:
            if n is not in S:
                add n to S
                n.parent = current
                Q.enqueue(n)

我想知道为什么在查看与当前相邻的邻居时无法检查当前是否是目标。例如。类似:

 Breadth-First-Search(Graph, root):
    create empty set S
    create empty queue Q      
    root.parent = NIL
    if root is the goal
        return root
    Q.enqueue(root)                      
    while Q is not empty:
        current = Q.dequeue()
        for each node n that is adjacent to current:
            if n is the goal          // check here instead
                  n.parent = current
                  return n
            if n is not in S:
                add n to S
                n.parent = current
                Q.enqueue(n)

我们的想法是,一旦在邻居中找到该词,您就会立即捕捉到它。您可以确保这是最短路径,因为队列中的路径不可能已经包含路径,因为我们也会在这种情况发生之前抓住它。

我知道这需要在 while 循环之前添加一个额外的检查,以查看 root 是否是目标,但除此之外,是否有一些原因 bfs 没有像这样实现?从技术上讲,它应该更快吧?

【问题讨论】:

    标签: algorithm optimization breadth-first-search


    【解决方案1】:

    如果您检查根目录,您的版本就可以正常工作(您应该将它放在问题中)。

    在某些情况下,您的方式会更快,而在某些情况下,您的方式会更慢。例如,如果两次访问每个节点的内容会受到某种惩罚(如额外的缓存未命中),它可能会更慢。

    通常差异并不显着,人们使用第一种方式只是因为代码更简单。

    【讨论】:

      【解决方案2】:

      我想我会进一步重构它。我注意到 root 没有直接添加到 S 中,这意味着稍后会添加它,然后再次检查。我将 S 和 Q 的创建移到了早期根返回之后。切换了while,这意味着不必将root排队到Q然后检查Q以查看root是否在其中,然后将root出队。我将 in S 检查移到 for each 循环内的第一个,因为该检查将阻止每个循环一次或多次目标检查,目标检查只会阻止 in S 检查一次。它还让我删除了 n.parent = current 代码行重复,对性能没有帮助,但我不喜欢重复。

       Breadth-First-Search(Graph, root):
          root.parent = NIL
          if root is the goal
              return root
          create empty set S
          add root to S
          create empty queue Q
          current = root
          while true
              for each node n that is adjacent to current:
                  if n in S:
                      continue
                  n.parent = current
                  if n is the goal
                      return n
                  add n to S
                  Q.enqueue(n)
              if Q empty
                  break
              current = Q.dequeue()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        • 2012-11-06
        相关资源
        最近更新 更多