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)