【问题标题】:Is this really a breadth first search这真的是广度优先搜索吗
【发布时间】:2014-08-16 12:55:04
【问题描述】:

OnLisp 的 P.303 上有一段广度优先搜索的伪代码,如下所示。 对于下图,它将首先处理节点 1,然后将节点 2、3 和 4 放入队列中,然后再次迭代调用自身。 然后,它将继续处理队列开头的节点 4。这又会将节点 7 和 8 放入队列的开头,依此类推。

最后,它遍历的路径将是 1->4->7-11->12->8->3->2->5->9->10->6,即深度优先搜索。 我错了吗?

(define (path node1 node2)
  (bf-path node2 (list (list node1))))

(define (bf-path dest queue)
  (if (null? queue)
      '@
      (let* ((path (car queue))
             (node (car path)))
        (if (eq? node dest)
            (cdr (reverse path))
            (bf-path dest
                    (append (cdr queue)
                    (map (lambda (n)
                           (cons n path))
                         (neighbors node))))))))

【问题讨论】:

  • 你测试过这段代码吗?我没有,但它不像你描述的那样看起来是正确的。当 bf-dest 被递归调用时,看看新队列将是什么:(append (cdr queue) (map ... (neighbors node)))。它是当前队列的rest,后跟当前节点的任何子节点。节点以广度优先的方式进行探索,而不是深度优先。 bf-dest 返回的路径是从根到目的地的路径。如果只有一条这样的路径(并且树是有限的),那么广度优先和深度优先都会找到它。
  • 要查看节点实际遍历的顺序,请尝试在let* 中,在if 之前添加一些输出。只需打印node
  • 队列的前面不是4,是2。

标签: tree scheme lisp common-lisp on-lisp


【解决方案1】:

广度优先搜索利用先进先出队列来查找要遍历的元素。

它应该查看第一个节点 (1),然后获取其子节点 (2, 3, 4) 并按该顺序填充列表。现在查看列表中的第一个元素并获取其子元素(5, 6) 并将它们添加到要查看的事物列表的末尾(3, 4, 5, 6)

仅在第一个元素上重复此操作。

3 -> (4, 5, 6)
4 -> (5, 6, 7, 8)
5 -> (6, 7, 8, 9, 10)
6 -> (7, 8 , 9, 10)
7 -> (8, 9, 10, 11, 12)
8 -> (9, 10, 11, 12)
9 -> (10, 11, 12)
10 -> (11, 12)
11 -> (12)
12 -> ()

通过先进后出(在您正在执行的操作中循环最近添加的元素),您可以创建深度优先搜索。

【讨论】:

  • 如果您继续写明智的答案,您将能够很快发表评论。
  • 这正确解释了广度优先搜索是什么,但没有讨论引用的代码是否正确。
猜你喜欢
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多