Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/34: Рейтинг темы: голосов - 34, средняя оценка - 4.56
2 / 1 / 0
Регистрация: 17.02.2013
Сообщений: 82
1

Дана схема метрополитена, найти кратчайший путь между станциями

31.03.2013, 22:49. Показов 6156. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет!


Дана схема метрополитена, найти кратчайший путь между станциями.
Схема метрополитена задаётся с помощью матрицы смежности или матрицы инциденций. Каждому перегону соответствует некоторый вес (длительность перегона). Каждой пересадке также соответствует некоторый вес (длительность пересадки). Необходимо для заданной преподавателем схемы вывести самый короткий путь или все такие пути, если их несколько.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.03.2013, 22:49
Ответы с готовыми решениями:

Найти кратчайший путь между точками графа
вот есть программка, в ней нужно найти кратчайший путь между точками. ТОесть найти самую малую...

Найти кратчайший путь между двумя заданными пунктами
Прошу объявить общий сбор всех хакеров, нужно решить задачу на C++. У меня ВСТАЛА небольшая...

Найти кратчайший путь между двумя заданными городами
Дана плоская страна и в ней n городов. Предположим, что в этой стране есть дорожная сеть. Найти...

Найти кратчайший путь между вершиной и стороной в n-угольнике
Помогите понять, с помощью какого алгоритма можно решить эту задачу. Правильно ли я понимаю, что...

25
1050 / 944 / 107
Регистрация: 04.11.2012
Сообщений: 974
Записей в блоге: 3
05.05.2014, 21:50 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от castorsky Посмотреть сообщение
А какже рекурсия?
Всмысле рекурсивные лямбды интересуют?
Ну вот пример для AL, только так будет намного медленнее.
Lisp
1
2
3
4
5
6
7
8
9
10
11
(defun delit (seq i)
  ((lambda (del)
    (setq del '(lambda (seq i c len)
      (cond ((= c len) ())
            ((member c i) (apply del (list (cdr seq) i (1+ c) len)))
            (t (cons (car seq) (apply del (list (cdr seq) i (1+ c) len)))))))
    (apply del (list seq i 0 (length seq)))) ()))
 
Команда:
(delit '(0 1 2 3 4 5 6 7 8 9) '(4 0 9))
; (1 2 3 5 6 7 8)
1
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
05.05.2014, 21:55 22
Catstail, Спасибо. Получается костыль для экономии места и снимает проблемы с именами функций. Но что делать. Как-то я об этом не подумал.

Добавлено через 1 минуту
Lambdik, Вообще говоря именованные локальные функции.
2
1050 / 944 / 107
Регистрация: 04.11.2012
Сообщений: 974
Записей в блоге: 3
05.05.2014, 22:22 23
castorsky Да нет же, я все правильно написал.
Именованных локальных функций нету. А рекурсии полно, в том числе и для безымянных функций. Я же привел пример выше. Ну вот еще рекурсия на AL:
Lisp
1
2
3
4
5
6
7
(defun Sum (n)
  (if (= n 0)
      0
      (+ n (Sum (1- n)))))
 
(Sum 5)
; 15
1
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
05.05.2014, 22:39 24
Lambdik, Выход без использования костылей. Как Вы сразу и указали.
Lisp
1
2
3
4
5
(defun foo (n / local-fun)
  (setq local-fun (lambda (x)
                    (if (= x 0) 0
                      (+ x (local-fun (- x 1))))))
  (local-fun n))
1
VH
428 / 256 / 23
Регистрация: 23.11.2010
Сообщений: 278
07.05.2014, 14:10 25
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(defun DIJKSTRA (Net_name Net_dist Init Term &optional (Tmp nil) (Fix (list (cons Init 0))))
 ((lambda (fix_label fix_value)
   (if (equal fix_label Term)
    (cons
     fix_value
     (SHORTEST_CHAIN (mapcar 'cons Net_name (apply 'mapcar (cons 'LIST Net_dist))) Init Term Fix))
    (apply 
     #'(lambda (newTmp newFix)
      (if (equal newFix Fix)
       nil ; unresolvable situation
       (DIJKSTRA Net_name Net_dist Init Term newTmp newFix)))
     (TRANSFER_MIN
      (UPDATE_Tmp
       Tmp
       Fix
       (mapcar 'cons
        Net_name
        (cdr
         (assoc
          fix_label
          (mapcar 'cons Net_name Net_dist)
          :test 'EQUAL))))
      Fix))))
  (caar Fix)
  (cdar Fix)))
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(defun UPDATE_Tmp (Tmp Fix Links)
 (if Links
  ((lambda (link_label link_value)
    (UPDATE_Tmp
     (if link_value
      (if (assoc link_label Fix :test 'EQUAL) Tmp
       ((lambda (link mark)
         (if link
          (subst (cons link_label (min mark (cdr link))) link Tmp :test 'EQUAL)
          (cons (cons link_label mark) Tmp)))
        (assoc link_label Tmp :test 'EQUAL)
        (+ link_value (cdar Fix))))
      Tmp)
     Fix
     (cdr Links)))
   (caar Links)
   (cdar Links))
  Tmp))
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(defun TRANSFER_MIN (Tmp Fix)
 (if Tmp
  (if (cdr Tmp)
   (apply
    #'(lambda (elem newTmp newFix)
     (if (< (cdr elem) (cdar newFix))
      (list
       (cons (car newFix) newTmp)
       (cons elem (cdr newFix)))
      (list
       (cons elem newTmp)
       newFix)))
    (cons (car Tmp) (TRANSFER_MIN (cdr Tmp) Fix)))
   (list
    (cdr Tmp)
    (cons (car Tmp) Fix)))
  (list Tmp Fix)))
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(defun SHORTEST_CHAIN (Net_link Init Term Fix &optional (Routes (list (list Term))))
 (if Routes
  ((lambda (route result)
    ((lambda (head)
      (if (equal head Init)
       (cons route result)
       (append
        (SHORTEST_CHAIN
         Net_link
         Init
         Term
         Fix
         (mapcar
          #'(lambda (node) (cons node route))
          (apply 'append
           (mapcar
            #'(lambda (node)
             ((lambda (name dist)
               (if dist
                ((lambda (head_mark name_mark)
                  (if (and head_mark name_mark)
                   (if (= (- (cdr head_mark) (cdr name_mark)) dist)
                    (cons name nil))))
                 (assoc head Fix :test 'EQUAL)
                 (assoc name Fix :test 'EQUAL))))
              (car node)
              (cdr node)))
            (mapcar 'cons
             (mapcar 'car Net_link)
             (cdr (assoc head Net_link :test 'EQUAL)))))))
        result)))
     (car route)))
   (car Routes)
   (SHORTEST_CHAIN Net_link Init Term Fix (cdr Routes)))))
Сеть представлена формальными параметрами Net_name (список наименований узлов) и Net_dist (список списков расстояний между узлами)
Например, сеть
Lisp
1
2
3
4
5
6
7
8
(setq Net_name '("1" "2" "3" "4" "5" "6"))
(setq Net_dist
'((nil 3 7 nil nil nil)
  (1 nil 2 nil nil 1)
  (nil 1 nil 2 4 nil)
  (nil nil nil nil 1 5)
  (nil nil 1 nil nil 3)
  (nil nil nil 2 nil nil)))
Формальные параметры Init и Term связываются при вызове с наименованиями начального и конечного узла искомой кратчайшей цепи, соответственно.
Вызов функции DIJKSTRA возвращает список вида
(длина_кратчайшей_цепи список_узлов_кратчайшей_цепи_вариант_1...)
или NIL, если цепь между заданными узлами не существует.
Например, вызов
Lisp
1
(DIJKSTRA Net_name Net_dist "1" "5")
возвращает
(7 ("1" "2" "6" "4" "5"))
А для сети, представленной
Lisp
1
2
3
4
5
6
(setq Net_name '("A" "B" "C" "D"))
(setq Net_dist
'((nil 5 4 nil)
  (nil nil 1 4)
  (nil 1 nil 5)
  (nil nil nil nil)))
вызов
Lisp
1
(DIJKSTRA Net_name Net_dist "A" "D")
возвращает
(9 ("A" "B" "D") ("A" "C" "B" "D") ("A" "C" "D"))
3
1050 / 944 / 107
Регистрация: 04.11.2012
Сообщений: 974
Записей в блоге: 3
16.04.2015, 17:17 26
Просто оставлю это здесь, а то лежит уже почти год. Улучшать решение мне не хочется, хотя есть куда.
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
;;; Алгоритм Дейкстры для нахождения кратчайших путей.
(defun Dijkstra (net begin end)
  (let* ((current-node begin)
         ;; Make-Queue.
         (HQ (mapcar #'(lambda (x) (list x 'Inf nil))
                    (remove begin (mapcar #'car net) :test #'equalp)))
         (Path (list (list begin 0 nil))))
    ;; Проверка корректности данных.
    (when (set-difference (list begin end) (mapcar #'car net) :test #'equalp)
      (return-from dijkstra "These vertices do not correspond to the net."))
    ;; Вставка меток/уменьшение ключа/удаление вершин в цикле.
    (loop (if (or (null HQ)
                  (equalp current-node end))
              (return (Tracing Path end)))  ; возвращаемое значение
      ;; Insert.
      (let ((curr-num (cadar Path))
            (keys (mapcar #'car (cdr (assoc current-node net :test #'equalp)))))
        (dolist (neighbor keys)
          (let ((neig-struct (assoc neighbor HQ :test #'equalp))
                (neig-number  ;; Selection from net.
                      (cdr (assoc neighbor
                             (cdr (assoc current-node net :test #'equalp))
                             :test #'equalp))))
            (if neig-struct
                (if (or (eq 'Inf (second neig-struct))
                        (< (+ neig-number curr-num) (second neig-struct)))
                    (setf (second neig-struct)
                          (+ neig-number
                             curr-num)
                          (third neig-struct)
                          current-node))))))
      ;; Decrease-Key.
      (let ((del (car (sort (copy-list (remove-if-not #'numberp HQ :key #'second))
                           #'< :key #'second))))
        ;; Delete-Min.
        (setq HQ (remove del HQ :test #'equalp))
        (push del Path)
        (setq current-node (caar path))))))
 
;;; Отследить путь обратно.
(defun Tracing (path end)
  (let* ((order-node (assoc end path :test #'equalp))
         (len (second order-node))
         (next-node (third order-node))
         (way ()))
    (push order-node way)
    (setq path (remove order-node path :test #'equalp))
    (loop
      (cond
        ((not next-node) (return (values (mapcar #'car way) len)))
        ((null path) (return "No solution.")))
      (setq order-node (assoc next-node path :test #'equalp)
            next-node (third order-node))
      (push order-node way)
      (setq path (remove order-node path :test #'equalp)))))
 
;; Сеть, список смежности: (узел (соседний_узел . длина_дуги)
(defparameter  *net*
  '(("1" ("2" .  300) ("6" .  550) ("5" . 1345))
    ("2" ("1" .  300) ("3" . 1400))
    ("3" ("4" .  300) ("2" . 1400))
    ("4" ("3" .  300) ("7" .  550) ("5" . 1345))
    ("5" ("4" . 1345) ("1" . 1345))
    ("6" ("1" .  550) ("7" . 1100))
    ("7" ("4" .  550) ("6" . 1100))))
 
> (Dijkstra *net* "1" "4")
("1" "2" "3" "4")
2000
PS. Узлы не обязательно должны быть строками.
2
16.04.2015, 17:17
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.04.2015, 17:17
Помогаю со студенческими работами здесь

С алгоритмом Дейкстра найти кратчайший путь в графе между парой вершин
С помощью алгоритма Дейкстра найти кратчайший путь в графе между парой вершин V0 и V* .

Определить кратчайший путь между вершинами
Для графа считанного из фала определить кратчайший путь между вершинами, заданными в режиме...

Определить кратчайший путь между 2-мя точками
Народ, помогите пожалуйста. Вручную написана схема того что должно получиться в итоге.

Кратчайший путь между двумя точками на поверхности
Дано уравнение поверхности z=f(x,y) и две точки на поверхности. Требуется изобразить на одном...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru