| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > LISP > Реализовать метод Флойда по готовому алгоритму |
| Автор: lestate 4.10.2006, 11:29 |
| помогите плз с методом Флойда(нахождение путя минимальной суммарной длины во взвешенном графе с произвольными весами для всех пар вершин) надо написать на лиспе сам алгоритм находиться здесь. http://khpi-iip.mipk.kharkiv.edu/library/datastr/book_sod/kgsu/din_0124.html проблема с реализацией |
| Автор: wwall 10.10.2006, 16:03 |
| Для себя решил взяться за эту задачу что бы понять Лисп (оказывается все что знал - пшик). Пока просто перевести цикл на лисп for (i=0;i<MaxNodes;i++) for (j=0;j<MaxNodes;j++) if (i!=j && i!=ved && j!=ved && DD[i][ved]>0 && DD[ved][j]>0) if (DD[i][ved]+DD[ved][j]<DD[i][j] || DD[i][j]==0) { DD[i][j]=DD[i][ved]+DD[ved][j]; SS[i][j]=ved; } ved++; } получилось (defun testThree (x y z) (if (< (+ x y) z) (+ x y) z) ) (setq testGraphD '( (EMPTY 3 NO NO) (3 EMPTY NO 5 NO) (10 NO EMPTY 6 15) (NO 5 6 EMPTY 4) (NO NO NO 4 EMPTY))) (setq MAX 5) (loop for i from 0 to MAX do ( loop for j from 0 to MAX do ( loop for k from 0 to MAX do ( ( ; не знаю как прервать цикл, поэтому пока не проверям i!=j j!=k i!=k ; вот здесь как то нужно получить элементы матрицы (setq x (nth j (nth i testGraphD))) (setq y (nth k (nth i testGraphD))) (setq z (nth j (nth k testGraphD))) (setq res (testThree x y z)) ;как теперь поставить на место res yf место (nth j (nth i testGraphD))? ) ) ) )) И еще, можно ли такой обход сделать с помощью mapcar? |
| Автор: wwall 10.10.2006, 17:06 |
| проще вариант (setq testGraphD (make-array '(5 5) :initial-contents '( ('EMPTY 3 10 'NO 'NO) (3 'EMPTY 'NO 5 'NO) (10 'NO 'EMPTY 6 15) ('NO 5 6 'EMPTY 4) ('NO 'NO 'NO 4 'EMPTY) ))) (setq MAX 5) (loop for i from 0 to MAX do (loop for j from 0 to MAX do (loop for k from 0 to MAX do ( ; только вот строчка что ниже - не работает. ; говорит что setf не функция (setf (aref testGraphD i j) (testThree (aref testGraphD i j) (aref testGraphD i k) (aref testGraphD k j)) ) ) ) ) ) насчет решения через mapcar - правильнее наверное appply и извращения с массивом? |
| Автор: wwall 10.10.2006, 17:31 |
| Блин! Скобки упустил.... Осталось написать правильно функцию testThree написать... Добавлено @ 17:41 Правильное определение (defun testThree (x y z) (if (and (numberp z) (and (numberp x) (numberp y)) ) (if (< (+ x y) z) (+ x y) z) 'EMPTY) ) (setq testGraphD (make-array '(5 5) :initial-contents '( ('EMPTY 3 10 9999 99999) (3 'EMPTY 99999 5 99999) (10 99999 'EMPTY 6 15) (99999 5 6 'EMPTY 4) (99999 99999 99999 4 'EMPTY) ))) здесь 99999 - эквивалент бесконечности |
| Автор: wwall 11.10.2006, 16:44 | ||
Итогом
вывод - (((0 1) (1 3)) (3 4)) что есть правильно. Понимаю что косячно, но не знаю: 1. Как добавить то что вернула функция в список, что бы не было лишних скобок 2. Как убрать функцию initialArray внутрь findPath (что бы она была видна только оттуда), в таком случае можно было бы вызвать так (findPath 0 4 testGraphD) 3. Как определить количество строк/колонок в массиве (не нужна былабы строка (setq MAX 4)) 4. Можно ли сделать так (setq (x y z) (1 2 3)), что бы в результате х=1, у=2, z=3 (это для красоты)? Это в общем решение в императивном стиле. Как сделать в функциональном - не знаю. Придумаю - напишу сюда. Кстати, может кто покритикует код? |
| Автор: wwall 11.10.2006, 17:41 |
| (print (apply #'append (findPath 0 4 (cdr res) 0))) будет печатать правильно. Подсмотренно у svg. Почему работает не знаю, буду благодарен если кто объяснит |