在方案中实施深度优先搜索的问题

发布于 2024-10-19 22:57:09 字数 1062 浏览 2 评论 0原文

我试图在方案中实现深度优先搜索,但我只能让它部分工作。 这是我的代码:

 (define (depth-first-search graph node neighbour path dest)
  (cond ((null? neighbour) #f)
        ((equal? node dest) path)
        ((member (car neighbour) path) (depth-first-search graph node (cdr neighbour) path dest))
        ((memq (car neighbour) (car graph)) (depth-first-search (cdr graph) (car neighbour) (memq (car neighbour) (car graph)) (append path (list (car neighbour))) dest))
        (else depth-first-search (cdr graph) path dest)))

这是我的图表,数据结构:

  (define complete-graph
  '((a b c d e)
    (b a c)
    (c a b f)
    (d a e h)
    (e a d)
    (f c g i)
    (g f h i j) 
    (h d g j)
    (i f g j)
    (j g h i)))

这就是我调用该过程的方式:

(depth-first-search complete-graph (caar complete-graph) (cdar complete-graph) (list (caar complete-graph)) 'd)

过程应该以列表形式返回从起始节点到目标(ination)的完整路径,但它似乎只能工作具有一些起始节点和目标节点。如果我从 'a 和 'c 开始,它会返回正确的列表 '(abc),但如果我尝试使用 'a 和 'd,我会得到 #f 作为回报。所以很可能是算法中的回溯出了问题。但是我看了代码太久了,实在找不到问题所在。

Im trying to implement Depth First Search in Scheme, but I can only get it to partially work.
This is my code:

 (define (depth-first-search graph node neighbour path dest)
  (cond ((null? neighbour) #f)
        ((equal? node dest) path)
        ((member (car neighbour) path) (depth-first-search graph node (cdr neighbour) path dest))
        ((memq (car neighbour) (car graph)) (depth-first-search (cdr graph) (car neighbour) (memq (car neighbour) (car graph)) (append path (list (car neighbour))) dest))
        (else depth-first-search (cdr graph) path dest)))

And this is my graph, data structure:

  (define complete-graph
  '((a b c d e)
    (b a c)
    (c a b f)
    (d a e h)
    (e a d)
    (f c g i)
    (g f h i j) 
    (h d g j)
    (i f g j)
    (j g h i)))

This is how I call the procedure:

(depth-first-search complete-graph (caar complete-graph) (cdar complete-graph) (list (caar complete-graph)) 'd)

To procedure shoud return the full path frome the start-node to the dest(ination) as a list, but it only seems to work with some start and destination nodes. If I start with 'a and 'c, it returns the right list '(a b c), but if I try with 'a and 'd, I get #f in return. So it probably is something wrong with the backtracking in the algorithm. But I have looked at the code for too long, and I really can't find the problem..

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

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

发布评论

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

评论(2

ら栖息 2024-10-26 22:57:09

假设节点 'a 有子节点 '(bcde),节点 'b 有子节点 '(ac),节点 ... 首先,您需要一个将节点扩展到其子节点的函数。

(define (expand graph node)
  (let ((c (assq node graph)))
    (if c (cdr c) '())))

第二:你必须记住所有访问过的节点。一般来说,帽子与路径不同(也许在这个例子中并不重要)。第三:你需要记住你想要访问的所有节点(节点扩展过程的结果)。因此定义一个辅助函数

(define (dfs* graph visited border path dest)

如果没有剩余节点可供访问,则不存在道路。

  (cond ((null? border) #f)

如果边界中的第一个元素等于我们的目的地,那么我们很高兴

        ((eq? (car border) dest) (cons (car border) path))

让我们检查所有访问过的节点。如果之前访问过边界中的第一个节点,则继续进行而不进行节点扩展

        ((memq (car border) visited)
         (dfs* graph visited (cdr border) path dest))

否则扩展边界的第一个节点

        (else (dfs* graph
                   (cons (car border) visited)
                   (append (expand graph (car border)) (cdr border))
                   (cons (car border) path)
                   dest))))

使用访问、边界和路径的起始值调用该辅助函数:

(define (dfs graph src dst)
  (dfs* graph '() (list src) '() dst)

对于呼吸优先搜索:将扩展的节点附加在边界末尾

编辑:
a) 访问过的路径和路径相同,可以删除其中一个
b) 以相反的顺序返回路径
c) 程序不正确,路径包含所有访问过的节点。但是 dfs* 结果的后处理就可以完成这项工作。

Assuming node 'a has children '(b c d e), node 'b has children '(a c), node ... First you need a function that expands a node to its children.

(define (expand graph node)
  (let ((c (assq node graph)))
    (if c (cdr c) '())))

Second: you have to remember all visited nodes. In general hat is different from the path (maybe it does not matter in this example). Third: you need to remember all nodes you want to visit (result from the node expansion process). So define a helper function

(define (dfs* graph visited border path dest)

If there are no nodes left to visit, then no road exist.

  (cond ((null? border) #f)

If the first element in border is equal to our destination, then we are happy

        ((eq? (car border) dest) (cons (car border) path))

Lets check all visited nodes. If the first node in border was visited before then proceed without node expansion

        ((memq (car border) visited)
         (dfs* graph visited (cdr border) path dest))

Otherwise expand the first node of border

        (else (dfs* graph
                   (cons (car border) visited)
                   (append (expand graph (car border)) (cdr border))
                   (cons (car border) path)
                   dest))))

Call that helper function with starting values for visited, border and path:

(define (dfs graph src dst)
  (dfs* graph '() (list src) '() dst)

For breath first search: append the expanded node at the end of border

Edit:
a) visited and path are the same, you can drop one of them
b) the path is returned in reverse order
c) The procedure is not correct, path contains all visited nodes. But a post processing of the result of dfs* will do the job.

变身佩奇 2024-10-26 22:57:09

在进行深度优先搜索时,您不想更改图形,而只想更改当前节点。如果您想纯粹按功能执行操作,请让您的函数如下所示:(

(define (depth-first-search graph node dest path)
  (let dfs ((node node) (path path))
    (let ((recur (lambda (node) (dfs node (cons node path)))))
      ; Write code here
      ; Recursive calls should use recur, not dfs or depth-first-search
      ...)))

返回路径或 #f 作为结果)。您可以使用ormap(在 Racket 或 SRFI-1 中)迭代节点的所有邻居,返回第一个不是 #f 的值。

You don't want to change the graph as you do the depth-first search, just the current node. If you want to do things purely functionally, have your function look like:

(define (depth-first-search graph node dest path)
  (let dfs ((node node) (path path))
    (let ((recur (lambda (node) (dfs node (cons node path)))))
      ; Write code here
      ; Recursive calls should use recur, not dfs or depth-first-search
      ...)))

(returning a path or #f as the result). You can use ormap (in Racket or SRFI-1) to iterate through all neighbors of a node, returning the first value that is not #f.

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