Graph 在图中查找从一个节点到另一个节点的所有路径

Graph 在图中查找从一个节点到另一个节点的所有路径,graph,path,scheme,racket,Graph,Path,Scheme,Racket,我试图找到图中两个节点之间的所有路径。我的图表定义为: (define-struct graph (nodes neighbors node=?)) (define G1 (make-graph '(A B C D E F G) (lambda (n) (cond [(symbol=? n 'A) '(B E)] [(symbol=? n 'B) '(E F)]

我试图找到图中两个节点之间的所有路径。我的图表定义为:

(define-struct graph (nodes neighbors node=?))

(define G1 (make-graph '(A B C D E F G)
              (lambda (n)
                (cond [(symbol=? n 'A) '(B E)]
                      [(symbol=? n 'B) '(E F)]
                      [(symbol=? n 'C) '(D)]
                      [(symbol=? n 'D) '()]
                      [(symbol=? n 'E) '(C F A)]
                      [(symbol=? n 'F) '(D G)]
                      [(symbol=? n 'G) '()]))
              symbol=?)))
我的算法是: 1.主函数返回一个列表,因此我在图上进行递归 2.将源连接到从其邻居到目标的路径

(define (find-paths origination destination G)
  (cond
    [(symbol=? origination destination) (list (list destination))]
    [else (local ((define neighbor ((graph-neighbors G) origination))
                  (define candidate (find-paths/list neighbor destination G)))
            (join origination candidate))]))

(define (find-paths/list lo-Os d g)
  (cond
    [(empty? lo-Os) empty]
    [else (local ((define candidate (find-paths (first lo-Os) d g)))
            (cond
              [(empty? candidate) (find-paths/list (rest lo-Os) d g)]
              [else (append (find-paths (first lo-Os) d g)
                            (find-paths/list (rest lo-Os) d g))]))]))

(define (join node list-of-node)
  (map (lambda (n) (cons node n)) list-of-node))
当我测试
(查找路径'A'E G1)
时,它会准确地返回我想要的内容,即
(list(list'A'E)(list'A'B'E))
。但是当我测试
(查找路径'A'cg1)
时,代码卡住了,IDE说它内存不足


有人能给我解释一下为什么吗?

在'A'和'E'之间有一个无限循环。因为当你 试着从“A”到“C”,它会测试“E”的所有邻居,让它回到“A”,然后再从那里回到“E”。我添加了一个
displayln
来显示这一点

(find-pahts A C)
(find-pahts B C)
(find-pahts E C)
(find-pahts C C)
(find-pahts C C)
(find-pahts F C)
(find-pahts D C)
(find-pahts G C)
(find-pahts A C)
(find-pahts B C)
(find-pahts E C)
(find-pahts C C)
(find-pahts C C)
(find-pahts F C)
(find-pahts D C)
(find-pahts G C)
正如你所看到的,你陷入了一个无限循环。它尝试“E”C,这会导致“C”C,这是一条路径。然后它依次从F转到E,它尝试D和G,这两个都是死胡同。然后是‘E’的最后一个邻居,它是‘A’,重新开始

(define (find-paths origination destination G)
  (local ((define (find-paths-ac orig seen)
            (cond
              [(symbol=? orig destination) (list (list destination))]
              [(member orig seen) empty]   ; you can also return an error here. 
              [else (local 
                      ((define neighbor ((graph-neighbors G) orig))
                       (define candidate 
                         (find-paths/list neighbor (cons orig seen))))
                      (join orig candidate))]))

          (define (find-paths/list lo-Os seen)  
            (cond [(empty? lo-Os) empty]
                  [else (local ((define candidate (find-paths-ac (first lo-Os) seen)))
                          (cond [(empty? candidate) (find-paths/list (rest lo-Os) seen)]
                                [else 
                                  (append candidate
                                    (find-paths/list (rest lo-Os) seen))]))]))) 
    (find-paths-ac origination empty)))
在这个版本中,我添加了一个参数来跟踪我已经看到的节点。它会的
如果两次到达同一节点(循环),则发出错误信号。

是否尝试在
查找路径/列表中添加类似
(displayln(list'find paths origination destination))
的内容作为
查找路径的第一行和
(displayln(list'find paths/list lo Os d))
?可能您会看到它返回到
(查找路径'A'cg1)
,这就是您的无限循环。作为猜测,请检查您的基本情况以查找空列表?但是(查找路径'a'C G1')的答案不是错误;事实上,存在一条从a到C的路径。它发出错误信号,因为您进入了一个无限循环。你说你想找到“所有路径”。如果对其使用
displayln
,可以看到它在错误之前找到了一条路径。它只是被忽略了。我的版本检测到无限循环,在这种情况下,您可以修改它,使其具有不同的行为。我选择发出错误信号只是为了停止计算。如果将我的错误消息替换为
,它将返回从'A到'C
'(A B E C)
'(A E C)