Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scheme中实现深度优先搜索的问题_Scheme - Fatal编程技术网

在Scheme中实现深度优先搜索的问题

在Scheme中实现深度优先搜索的问题,scheme,Scheme,我试图在Scheme中实现深度优先搜索,但我只能让它部分工作。 这是我的代码: (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

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

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

过程应该以列表的形式返回从起始节点到目的节点的完整路径,但它似乎只适用于某些起始节点和目的节点。如果我以a和c开头,它会返回正确的列表(abc),但是如果我尝试以a和d开头,我会得到f作为回报。因此,可能是算法中的回溯有问题。但是我已经看了太长时间的代码,我真的找不到问题所在。

您不想在执行深度优先搜索时更改图形,只想更改当前节点。如果你想纯粹从功能上做事情,让你的功能看起来像:

(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

的第一个值。在进行深度优先搜索时,您不想更改图形,只想更改当前节点。如果你想纯粹从功能上做事情,让你的功能看起来像:

(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

的值,假设节点“a有子节点”(b c d e),节点“b有子节点”(a c),节点。。。首先,您需要一个将节点扩展到其子节点的函数

(define (expand graph node)
  (let ((c (assq node graph)))
    (if c (cdr c) '())))
第二:您必须记住所有访问的节点。通常情况下,hat与路径不同(在本例中可能并不重要)。第三:您需要记住要访问的所有节点(节点扩展过程的结果)。所以定义一个辅助函数

(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))))
使用visited、border和path的起始值调用该帮助器函数:

(define (dfs graph src dst)
  (dfs* graph '() (list src) '() dst)
对于呼吸优先搜索:将展开的节点附加到边界的末尾

        (else (dfs* graph
                   (cons (car border) visited)
                   (append (expand graph (car border)) (cdr border))
                   (cons (car border) path)
                   dest))))
编辑: a) 访问和路径相同,您可以删除其中一个 b) 路径以相反的顺序返回
c) 该过程不正确,路径包含所有访问的节点。但是dfs*结果的后处理将完成这项工作。

假设节点“a有子节点”(b c d e),节点“b有子节点”(a c),节点。。。首先,您需要一个将节点扩展到其子节点的函数

(define (expand graph node)
  (let ((c (assq node graph)))
    (if c (cdr c) '())))
第二:您必须记住所有访问的节点。通常情况下,hat与路径不同(在本例中可能并不重要)。第三:您需要记住要访问的所有节点(节点扩展过程的结果)。所以定义一个辅助函数

(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))))
使用visited、border和path的起始值调用该帮助器函数:

(define (dfs graph src dst)
  (dfs* graph '() (list src) '() dst)
对于呼吸优先搜索:将展开的节点附加到边界的末尾

        (else (dfs* graph
                   (cons (car border) visited)
                   (append (expand graph (car border)) (cdr border))
                   (cons (car border) path)
                   dest))))
编辑: a) 访问和路径相同,您可以删除其中一个 b) 路径以相反的顺序返回
c) 该过程不正确,路径包含所有访问的节点。但是dfs*结果的后处理可以完成这项工作。

else
子句中调用
深度优先搜索之前缺少括号。
(追加路径(列表(汽车邻居)))
是一件坏事。在
else
子句中调用
深度优先搜索之前缺少括号。
(追加路径(列表(汽车邻居))
是一件坏事。