Scheme 寻找球拍中两点之间的路径

Scheme 寻找球拍中两点之间的路径,scheme,racket,Scheme,Racket,我有以下连接列表: (define routelist (list (list'a 'b) (list'a 'c) (list'b 'e) (list'b 'f) (list'b 'c) (list'a 'd) (list'e 'f) (list'f 'g))) 将找到“a”和“g”之间的路线。此页面显示Prolog中的解决方案: 我可以管理以下解决方案,尽管它是迭代的: (define (ma

我有以下连接列表:

(define routelist
  (list
      (list'a 'b)
      (list'a 'c)
      (list'b 'e)
      (list'b 'f)
      (list'b 'c)
      (list'a 'd)
      (list'e 'f)
      (list'f 'g)))
将找到“a”和“g”之间的路线。此页面显示Prolog中的解决方案:

我可以管理以下解决方案,尽管它是迭代的:

(define (mainpath routelist start end (outl '()))
  (if (equal? start end)
      (println "Same start and end points.")
  (for ((item routelist)) 
    (when (equal? start (list-ref item 0))
          (set! outl (cons start outl))
          (if (equal? end (list-ref item 1))
              (begin 
                ; PATH FOUND:
                (set! outl (cons end outl))
                (println (reverse outl)))
              (begin 
                (mainpath (rest routelist) (list-ref item 1) end outl)
                (set! outl (rest outl))))))))

(mainpath routelist 'a 'g)
输出:

'(a b e f g)
'(a b f g)

如何在Racket中实现功能性解决方案?

以下是一个非常简单的解决方案:

(define (mainpath routelist start end)
  (define (neighbors node)
    (map second (filter (lambda (x) (eq? (first x) node)) routelist)))
  (define (visit node visited)
    (when (not (member node visited))
      (when (eq? node end)
        (println (reverse (cons node visited))))
      (let ((new-visited (cons node visited)))
        (map (lambda (x) (visit x new-visited)) (neighbors node)))))
  (visit start '())
  "No more paths")

这个递归函数还可以管理带有循环的图,它保留一个沿当前路径已访问的节点列表,并在访问了从开始节点可访问的所有节点后停止。当当前节点是结束节点时,将打印当前路径。

使用DFS算法即可

(define (mainpath routelist start end)
  (letrec ([next-nodes (λ (node)
                        (for/list ([al routelist]
                                   #:when (eq? node (first al)))
                                  (second al)))]
           [path (λ (node vlist)
                   (let ([new-list (cons node vlist)])
                     (when (eq? node end)
                       (println (reverse new-list)))
                     (for ([next (next-nodes node)]
                           #:unless (memq next vlist))
                          (path next new-list))))])
    (path start '())))

如何将图形用于此功能?routelist是直接图的表示形式,其中每个节点由一个符号表示,列表中的一对表示两个节点之间的一条弧。请注意,您链接的页面标题为“图形中的路径”…我可以在此处显示'a到'g'之间的路径图吗?@mso,您是指通过图形用户界面显示的图形?你可以看一下,但我没有这方面的经验。