Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the longest path between two nodes in Lisp?

I need to program a Lisp function that finds the longest path between two nodes, without revisiting any nodes. Though, if the start and end node are the same, this node can be revisited. The function needs to be both recursive and depth-first-search.

I've been trying to get at this for hours, and cannot come up with a solution. I know the general outline of the function, but cannot program it correctly. In some code and mostly pseudo-code:

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

The net looks something like '((a b) (b c)) , where the first item is the node, and everything else is its neighbors (e.g. node a has neighbor b, node b has neighbor c).

Yes, this is for homework, so if you don't feel comfortable posting a solution, or any part of it, don't. I'm just new to Lisp and would like some tips/help to get a decent start.

Thanks

Edit: Well, the most I could get was this:

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

It produces correct solutions, except when the start and end node are the same. I can't figure out how to perform a search even when they're the same.

like image 649
Jay Avatar asked Oct 15 '10 19:10

Jay


1 Answers

I have remembered this algorithm from Paul Graham's book: Ansi Common Lisp. Here is the link of the solution of one exercise from book. This should help you.

Solution

like image 105
asdr Avatar answered Oct 03 '22 13:10

asdr