Прокомментировать код - Lisp (229547)

Узнай цену своей работы

Формулировка задачи:

Добрый вечер, можете пожалуйста прокомментировать сей чудесный код (автор -

Catstail

) более подробно?
Листинг программы
  1. ;; Проверить ребро
  2. (defun chk-vert (v s)
  3. (let ((a1 (car v))
  4. (a2 (cadr v)))
  5. (not (forsome s (lambda (w) (and (member a1 w) (member a2 w)))))))
  6. ;; Добавление очередного ребра в "лес"
  7. (defun ins-vert (v w)
  8. (let* ((a1 (car v))
  9. (a2 (cadr v))
  10. (w1 (car (remove-if-not (lambda (x) (member a1 x)) w)))
  11. (w2 (car (remove-if-not (lambda (x) (member a2 x)) w))))
  12. (cond ((and (null w1) (null w2)) (cons (butlast v) w))
  13. ((null w1) (cons (cons a1 w2) (remove-if (lambda (x) (member a2 x)) w)))
  14. ((null w2) (cons (cons a2 w1) (remove-if (lambda (x) (member a1 x)) w)))
  15. (t (cons (append w1 w2) (remove-if (lambda (x) (or (member a1 x) (member a2 x))) w))))))
  16.  
  17. ;; Очередной шаг
  18. (defun action (graph &optional (w nil) (r nil))
  19. (cond ((null graph) r)
  20. ((chk-vert (car graph) w) (action (cdr graph) (ins-vert (car graph) w) (append r (list (car graph)))))
  21. (t (action (cdr graph) w r))))
  22. (defun kruskal (graph)
  23. (let ((g (qsort-a graph (lambda (x) (nth 2 x)))))
  24. (action g)))
P.S.: Реализация алгоритма Краскала (Крускала) - поиск минимального остовного дерева графа.

Решение задачи: «Прокомментировать код»

textual
Листинг программы
  1. ;; Проверить ребро
  2.  
  3. (defun chk-vert (v s) ;; s - набор ребер уже включенных в каркас. v - очередное проверяемое ребро
  4.   (let ((a1 (car v)) ;; начало v
  5.         (a2 (cadr v))) ;; конец v
  6.     ;; далее проверяется, не содержатся ли обе вершины v в одном из "островов" каркасе s
  7.     ;; если содержатся - это ребро включать нельзя, т.к. возникнет цикл
  8.     (not (forsome s (lambda (w) (and (member a1 w) (member a2 w)))))))
  9.        
  10. ;; Добавление очередного ребра в "лес"        
  11.        
  12. (defun ins-vert (v w)    ;; v - ребро, w - текущий каркас (лес, набор ребер).    
  13.   (let* ((a1 (car v)) ;; начало v
  14.          (a2 (cadr v)) ;; конец v
  15.          (w1 (car (remove-if-not (lambda (x) (member a1 x)) w))) ;; w1 - вершина из каркаса, соединенная с началом v
  16.          (w2 (car (remove-if-not (lambda (x) (member a2 x)) w)))) ;; w2 - вершина из каркаса, соединенная с концом v
  17.     (cond ((and (null w1) (null w2)) (cons (butlast v) w)) ;; если w1 и w2 = nil, просто присоединяем ребро (без длины) к каркасу
  18.           ((null w1) (cons (cons a1 w2) (remove-if (lambda (x) (member a2 x)) w))) ;; присоединяем к верш. w1
  19.           ((null w2) (cons (cons a2 w1) (remove-if (lambda (x) (member a1 x)) w))) ;; присоединяем к верш. w2
  20.           (t (cons (append w1 w2) (remove-if (lambda (x) (or (member a1 x) (member a2 x))) w)))))) ;; объединение двух несвязанных "островов" добавляемым ребром в единый остров
  21.  
  22. ;; Очередной шаг
  23.    
  24. (defun action (graph &optional (w nil) (r nil))
  25.   (cond ((null graph) r) ;; если граф пуст - каркас сидит в r
  26.           ;; если очередное ребро графа не приведет к циклу, добавляем его к каркасу,
  27.           ;; а из графа при след. рекурсивном вызове исключаем
  28.         ((chk-vert (car graph) w) (action (cdr graph) (ins-vert (car graph) w) (append r (list (car graph)))))
  29.         ;; если ребро нельзя добавлять - пропускаем
  30.         (t (action (cdr graph) w r))))
  31.        
  32. ;; Ведущая программа:
  33.  
  34. (defun kruskal (graph)
  35.   (let ((g (qsort-a graph (lambda (x) (nth 2 x))))) ;; сортируем ребра по возрастанию длин
  36.      (action g)))  ;; и запускаем action...

Объяснение кода листинга программы

  1. chk-vert - это функция, которая проверяет, можно ли добавить очередное ребро в каркас. Если оба конца ребра уже присутствуют в одном из островов каркаса, ребро не добавляется, чтобы избежать создания цикла.
  2. ins-vert - это функция, которая добавляет очередное ребро в каркас. Если оба конца ребра уже присутствуют в каркасе, ребро не добавляется. Если один или оба конца отсутствуют в каркасе, они добавляются в соответствующую вершину.
  3. action - это функция, которая выполняет очередной шаг алгоритма. Если граф пуст, возвращается текущий каркас. Если очередное ребро не приводит к циклу, оно добавляется в каркас и исключается из графа для следующего рекурсивного вызова. Если ребро приводит к циклу, оно пропускается.
  4. kruskal - это ведущая программа, которая использует функцию action для обработки графа. Сначала граф сортируется по возрастанию длин ребер, а затем передается в функцию action для обработки.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.818 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут