Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Реализовать метод Флойда по готовому алгоритму, путь минимальной суммарной длины в графе 
V
    Опции темы
lestate
Дата 4.10.2006, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 4.10.2006

Репутация: 1
Всего: 1



помогите плз с методом Флойда(нахождение путя минимальной суммарной длины во взвешенном графе с произвольными весами для всех пар вершин) надо написать на лиспе 
сам алгоритм находиться здесь. 
http://khpi-iip.mipk.kharkiv.edu/library/d...u/din_0124.html
проблема с реализацией

Это сообщение отредактировал(а) lestate - 4.10.2006, 11:31
PM MAIL   Вверх
wwall
Дата 10.10.2006, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 28.9.2006

Репутация: 3
Всего: 4



Для себя решил взяться за эту задачу что бы понять Лисп (оказывается все что знал - пшик).  
Пока просто перевести цикл на лисп

     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? 

PM MAIL   Вверх
wwall
Дата 10.10.2006, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 28.9.2006

Репутация: 3
Всего: 4



проще вариант 

(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 не функция  smile 
                         (setf (aref testGraphD i j) (testThree (aref testGraphD i j) (aref testGraphD i k) (aref testGraphD k j)) )
                        )
                )
        )
)


насчет решения через mapcar - правильнее наверное appply и извращения с массивом?
PM MAIL   Вверх
wwall
Дата 10.10.2006, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 28.9.2006

Репутация: 3
Всего: 4



Блин! Скобки упустил.... 
Осталось написать правильно функцию testThree написать...  smile

Добавлено @ 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 - эквивалент бесконечности 
PM MAIL   Вверх
wwall
Дата 11.10.2006, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 28.9.2006

Репутация: 3
Всего: 4



Итогом 

Код


(defun testThree (x y z)
    (if (< (+ x y) z)  (+ x y) z) 
)


(defun eqThree ( x y z)
    (or (= x y) (or (= y z) (= x z)))
)

(defun initialArray (graphD graphS)
(setq MAX 4)
(loop for k from 0 to MAX do
        (loop for i from 0 to MAX do
                (loop for j from 0 to MAX when (not (eqThree i j k)) do 
                        (setq x (aref graphD k j))
                        (setq y (aref graphD i k))
                        (setq z (aref graphD i j))
                        (setq _ (aref graphS i j))
            (setf (aref graphD i j) (testThree x y z))
            (setf (aref graphS i j) (if (= (aref graphD i j) z) _ k))
                )
        )
)
(cons graphD graphS)
)


(defun findPath (fromNode toNode graphS step)
    (setq tempToNode (aref graphS fromNode toNode))
    (print (format nil "On enter: step=~D fromNode =~D toNode =~D temp =~D" step fromNode toNode tempToNode))
    (if (= toNode tempToNode) 
        (list fromNode toNode) 
        (list (findPath fromNode tempToNode graphS (+ 1 step)) (findPath tempToNode toNode graphS (+ 1 step))) )
)

(setq testGraphD  (make-array '(5 5) :initial-contents '(
        ('NO        3            10    999    9999)
        (3       'NO    9999   5       9999)
        (10      9999     'NO  6       15)
        (9999     5        6       'NO  4)
        (9999     9999      9999   4       'NO)
        ))
)
(setq testGraphS  (make-array '(5 5) :initial-contents '(
        ('NO    1    2    3    4)
        (0      'NO    2    3    4)
        (0      1     'NO    3    4)
        (0     1       2       'NO  4)
        (0     1      2    3    'NO)
        ))
)


(if (= (testThree 1 2 4) 3) (print '(test 1 passed)) (print "test 1 NOT passed"))
(if (= (testThree 4 2 5) 5) (print '(test 2 passed)) (print "test 2 NPT passed"))
(setq res (initialArray testGraphD testGraphS))
(print (findPath 0 4  (cdr res) 0))



вывод - (((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, 16:46
PM MAIL   Вверх
wwall
Дата 11.10.2006, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 28.9.2006

Репутация: 3
Всего: 4



(print (apply #'append (findPath 0 4  (cdr res) 0)))
будет печатать правильно. Подсмотренно у svg. Почему работает не знаю, буду благодарен если кто объяснит

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума LISP
Void
  • Пожалуйста, создавайте темы с содержательными названиями.
  • Lisp — это целое семейство языков. Всегда указывайте в теме используемый диалект (Common Lisp, Scheme и т.д.).
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | LISP | Следующая тема »


 




[ Время генерации скрипта: 0.0716 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.