Recursion 如何在Lisp中找到两个节点之间的最长路径?

Recursion 如何在Lisp中找到两个节点之间的最长路径?,recursion,lisp,depth-first-search,longest-path,Recursion,Lisp,Depth First Search,Longest Path,我需要编写一个Lisp函数,在不重新访问任何节点的情况下,查找两个节点之间的最长路径。但是,如果开始节点和结束节点相同,则可以重新访问该节点。该函数需要是递归和深度优先搜索 我已经试了好几个小时了,想不出一个解决办法。我知道函数的大致轮廓,但无法正确编程。在一些代码和大部分伪代码中: (defun longest-path (start end net &optional (current-path nil)) (cond ((and (eql start end)

我需要编写一个Lisp函数,在不重新访问任何节点的情况下,查找两个节点之间的最长路径。但是,如果开始节点和结束节点相同,则可以重新访问该节点。该函数需要是递归和深度优先搜索

我已经试了好几个小时了,想不出一个解决办法。我知道函数的大致轮廓,但无法正确编程。在一些代码和大部分伪代码中:

(defun longest-path (start end net &optional (current-path nil))  
    (cond ((and (eql start end)
                (not (null current-path)))
          (list start))
          (t
           (find neighbors of start/node)
           (remove any previously traveled neighbors to avoid loop)
           (call longest-path on these neighbors)
           (check to see which of these correct paths is longest))))
网络看起来有点像“((ab)(bc)),其中第一个项目是节点,其他所有项目都是它的邻居(例如,节点a有邻居b,节点b有邻居c)

是的,这是为了家庭作业,所以如果你觉得发布解决方案或其中的任何部分不舒服,就不要发布。我刚刚接触Lisp,想要一些技巧/帮助来获得一个良好的开端

谢谢

编辑:嗯,我能得到的最多是:

(defun longest-path (start end net &optional (current-path nil))
  (cond ((and (eql start end)
              (not (null current-path)))
         (list start))
        (t
         (push start current-path)
         (let ((neighbors (cdr (assoc start net))))
           (let ((new-neighbors (set-difference neighbors current-path)))
             (let ((paths (mapcar #'(lambda (node)
                                      (longest-path node end net current-path))
                            new-neighbors)))
               (let ((longest (longest paths)))
                 (if longest
                     (cons start longest)
                   nil))))))))


(defun longest (lst)
  (do ((l lst (cdr l))
       (r nil (if (> (length (car l)) (length r))
                  (car l)
                r)))
      ((null l) r)))

它生成正确的解决方案,除非开始节点和结束节点相同。我不知道如何执行搜索,即使它们是相同的。

我认为您需要检查三种情况:

  • 结束到达->返回此路径
  • 无更多选择->返回零
  • 查找邻居的最长路径
  • 代码大纲:

    (defun longest-path (node end-node net current-path)
      (cond ((eql node end-node)
             (or current-path (list node end-node)))
            ((null (node-neighbors node net))
             ())
            (t
             (let* ((neighbors (node-neighbors node net))
                    (not-visited-neighbors (set-difference neighbors current-path))
                    (paths (mapcar (lambda (next-node)
                                     (longest-path next-node end-node net
                                                   (cons node current-path)))
                                   not-visited-neighbors)))
               (first (sort paths #'> :key #'length))))))
    

    我记得Paul Graham的书中的这个算法:Ansi Common Lisp。以下是本书中一个练习的解答链接。这应该对你有帮助


    嗨,谢谢你的帮助。我尝试了你的代码,但没有得到正确的解决方案。例如,如果我尝试(最长路径'a'c'((ab)(bc))nil),我会得到(ba)。相反,我应该得到(A B C)。