Гамильтонов цикл - Lisp
Формулировка задачи:
Здравствуйте, есть такое задание:
Определить функцию, на вход которой подается граф в виде ((a b) (b c) (c d)) a - начало дуги, b - конец. Функция должна определять, является ли он гамильтоновым, и если да, то найти гамильтонов цикл.
Цикл в графе называется гамильтоновым, если он содержит все вершины графа ровно по одному разу.
Нужна помощь, заранее спасибо.
Решение задачи: «Гамильтонов цикл»
textual
Листинг программы
- (defun is-bound (v1 v2 graph)
- (cond ((null graph) nil)
- ((or (equal (list v1 v2) (car graph)) (equal (list v2 v1) (car graph))) t)
- (t (is-bound v1 v2 (cdr graph)))))
- (defun setof (lst)
- (if (null lst) nil (cons (car lst) (setof (remove (car lst) (cdr lst))))))
- (defun vlist (graph)
- (setof (apply 'append graph)))
- (defun backtrack (n vlst pth g)
- (cond ((null pth) nil)
- ((and (is-bound (car pth) (car (last pth)) g) (= (length pth) n))
- (princ pth) (terpri))
- (t (dolist (v vlst t)
- (when (and (not (member v pth)) (is-bound v (car pth) g))
- (backtrack n vlst (cons v pth) g))))))
- (defun hamilt (graph)
- (let* ((vlst (vlist graph))
- (n (length vlst)))
- (backtrack n vlst (list (car vlst)) graph)))
- (hamilt '((1 2) (1 3) (1 4) (1 5) (2 3) (3 4) (4 5)))
- (5 4 3 2 1)
- (2 3 4 5 1)
- ==> T
- (hamilt '((1 2) (2 3) (3 4) (4 1)))
- (1 4 3 2)
- (3 4 1 2)
- ==> T
Объяснение кода листинга программы
В этом коде реализован алгоритм поиска Гамильтонова цикла в графе с помощью рекурсивного спуска. Он состоит из нескольких функций:
is-bound
— проверяет, является ли пара вершин элементом графа.setof
— рекурсивно удаляет элемент из списка и добавляет его в начало нового списка.vlist
— рекурсивно собирает список вершин графа.backtrack
— рекурсивно ищет путь в графе от начальной вершины до конечной, помечая проходящие через неё вершины.hamilt
— ищет Гамильтонов цикл в графе. При вызове функцииhamilt
с графом в виде списка пар вершин, она возвращает список вершин, образующих Гамильтонов цикл, если он существует. В противном случае возвращаетnil
. Например, для графа((1 2) (2 3) (3 4) (4 1))
функцияhamilt
вернёт список(1 4 3 2)
, что означает, что цикл образуют вершины 1, 4, 3 и 2.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д