Мне нужно запрограммировать функцию Лиспа, которая находит самый длинный путь между двумя узлами без повторного посещения каких-либо узлов. Однако, если начальный и конечный узлы совпадают, к этому узлу можно вернуться. Функция должна быть как рекурсивной, так и поиском в глубину.
Я пытался разобраться в этом несколько часов и не могу придумать решения. Я знаю общую схему функции, но не могу ее правильно запрограммировать. В некотором коде и в основном псевдокоде:
(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)))
Он дает правильные решения, за исключением случаев, когда начальный и конечный узлы совпадают. Я не могу понять, как выполнять поиск, даже если они одинаковы.