Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Алгоритм Дейкстры - поиск кратчайшего пути - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: _Boroda_, китин  
Алгоритм Дейкстры - поиск кратчайшего пути
Rioran Дата: Четверг, 23.07.2015, 18:15 | Сообщение № 1
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
Всем привет и хорошего настроения!

Предлагаю Вашему вниманию реализацию алгоритма Дейкстры (Дийкстры) в Excel. Позволяет найти кратчайший (или самый дешёвый) путь между множеством точек.

На ту же тему на форуме есть задача Коммивояжера, однако в отличие от неё - здесь НЕ требуется обойти все возможные точки.

Эта реализация вдохновлена алгоритмом с форума по Au3, но в отличие от частного решения, там представленного, я дополнил реализацию возможностью автоматического расширения на разное число точек (узлов).

Исходные данные должны быть представлены в виде квадратной матрицы. По столбцу слева указаны объекты, откуда происходит переход. По строке сверху - точки, куда идёт переход. На пересечении - стоимость перехода. При этом в разные стороны между одними и теми же точками сумма может отличаться. Если сумма перехода равна нолю - считается, что переход невозможен.

Код программы:

[vba]
Код
Option Explicit
Option Base 1

Sub Rio_Dij()
     Dim StartX As Long
     Dim FinishX As Long
     Dim BasE, NamS
     Dim nCost, nBack, nBack_tmp
     Dim i As Long
     Dim j As Long
     Dim k As Long
     Dim l As Long
     Dim SumX As Double
     Dim MinX As Double
     Dim MinID
     Dim Result() As String
     Dim RowA As Long
     Dim RowB As Long
     RowA = Cells(5, 1).End(xlDown).Row - 4
     RowB = RowA + 1
     Range(Cells(4, RowA + 3), Cells(4, RowA + 3).End(xlToRight).End(xlDown)).Clear
     MinX = 999999999999999#
     BasE = Range("B5").Resize(RowA, RowA)
     NamS = Range("A5").Resize(RowA, 1)
     For i = 1 To RowA
         If Range("B2").Value = NamS(i, 1) Then StartX = i
         If Range("E2").Value = NamS(i, 1) Then FinishX = i
     Next i
     ReDim nCost(RowA)
     ReDim nBack(RowA)
     ReDim nBack_tmp(RowA)
     For i = 1 To UBound(NamS, 1)
         nCost(i) = MinX
         nBack(i) = RowB
         nBack_tmp(i) = RowB
     Next i
     nCost(StartX) = 0
     nBack(StartX) = 0
     Do While nBack(FinishX) = RowB
         For i = 1 To RowA
             If nBack(i) < RowB Then
                 For j = 1 To RowA
                     If BasE(i, j) > 0 Then
                         SumX = nCost(i) + BasE(i, j)
                         If nCost(j) > SumX Then
                             nCost(j) = SumX
                             nBack_tmp(j) = i
                         End If
                     End If
                 Next j
             End If
         Next i
         MinX = 999999999999999#
         For i = 1 To RowA
             If nBack(i) <> nBack_tmp(i) Then
                 If nCost(i) < MinX Then
                     MinX = nCost(i)
                     MinID = i
                 End If
             End If
         Next i
         nBack(MinID) = nBack_tmp(MinID)
     Loop
     i = FinishX
     j = 0
     Do
         j = j + 1
         ReDim Preserve Result(4, j)
         Result(1, j) = NamS(nBack(i), 1) 'Откуда
         Result(2, j) = NamS(i, 1) 'Куда
         Result(3, j) = BasE(nBack(i), i) 'Сколько стоило
         Result(4, j) = nCost(i) 'Стоимость накопительно
         i = nBack(i)
     Loop While i <> StartX
     Range("A4").Offset(0, RowA + 2).Resize(1, 5).Value = Array("Шаг", "Откуда", "Куда", "Сумма", "Накопительно")
     For k = j To 1 Step -1
         Cells(5 + (j - k), RowA + 3).Value = j - k + 1
         For l = 1 To 4
             Cells(5 + (j - k), RowA + 3 + l).Value = Result(l, k)
         Next l
     Next k
End Sub
[/vba]
К сообщению приложен файл: Dijkstra_1.xlsb (24.0 Kb)


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
СообщениеВсем привет и хорошего настроения!

Предлагаю Вашему вниманию реализацию алгоритма Дейкстры (Дийкстры) в Excel. Позволяет найти кратчайший (или самый дешёвый) путь между множеством точек.

На ту же тему на форуме есть задача Коммивояжера, однако в отличие от неё - здесь НЕ требуется обойти все возможные точки.

Эта реализация вдохновлена алгоритмом с форума по Au3, но в отличие от частного решения, там представленного, я дополнил реализацию возможностью автоматического расширения на разное число точек (узлов).

Исходные данные должны быть представлены в виде квадратной матрицы. По столбцу слева указаны объекты, откуда происходит переход. По строке сверху - точки, куда идёт переход. На пересечении - стоимость перехода. При этом в разные стороны между одними и теми же точками сумма может отличаться. Если сумма перехода равна нолю - считается, что переход невозможен.

Код программы:

[vba]
Код
Option Explicit
Option Base 1

Sub Rio_Dij()
     Dim StartX As Long
     Dim FinishX As Long
     Dim BasE, NamS
     Dim nCost, nBack, nBack_tmp
     Dim i As Long
     Dim j As Long
     Dim k As Long
     Dim l As Long
     Dim SumX As Double
     Dim MinX As Double
     Dim MinID
     Dim Result() As String
     Dim RowA As Long
     Dim RowB As Long
     RowA = Cells(5, 1).End(xlDown).Row - 4
     RowB = RowA + 1
     Range(Cells(4, RowA + 3), Cells(4, RowA + 3).End(xlToRight).End(xlDown)).Clear
     MinX = 999999999999999#
     BasE = Range("B5").Resize(RowA, RowA)
     NamS = Range("A5").Resize(RowA, 1)
     For i = 1 To RowA
         If Range("B2").Value = NamS(i, 1) Then StartX = i
         If Range("E2").Value = NamS(i, 1) Then FinishX = i
     Next i
     ReDim nCost(RowA)
     ReDim nBack(RowA)
     ReDim nBack_tmp(RowA)
     For i = 1 To UBound(NamS, 1)
         nCost(i) = MinX
         nBack(i) = RowB
         nBack_tmp(i) = RowB
     Next i
     nCost(StartX) = 0
     nBack(StartX) = 0
     Do While nBack(FinishX) = RowB
         For i = 1 To RowA
             If nBack(i) < RowB Then
                 For j = 1 To RowA
                     If BasE(i, j) > 0 Then
                         SumX = nCost(i) + BasE(i, j)
                         If nCost(j) > SumX Then
                             nCost(j) = SumX
                             nBack_tmp(j) = i
                         End If
                     End If
                 Next j
             End If
         Next i
         MinX = 999999999999999#
         For i = 1 To RowA
             If nBack(i) <> nBack_tmp(i) Then
                 If nCost(i) < MinX Then
                     MinX = nCost(i)
                     MinID = i
                 End If
             End If
         Next i
         nBack(MinID) = nBack_tmp(MinID)
     Loop
     i = FinishX
     j = 0
     Do
         j = j + 1
         ReDim Preserve Result(4, j)
         Result(1, j) = NamS(nBack(i), 1) 'Откуда
         Result(2, j) = NamS(i, 1) 'Куда
         Result(3, j) = BasE(nBack(i), i) 'Сколько стоило
         Result(4, j) = nCost(i) 'Стоимость накопительно
         i = nBack(i)
     Loop While i <> StartX
     Range("A4").Offset(0, RowA + 2).Resize(1, 5).Value = Array("Шаг", "Откуда", "Куда", "Сумма", "Накопительно")
     For k = j To 1 Step -1
         Cells(5 + (j - k), RowA + 3).Value = j - k + 1
         For l = 1 To 4
             Cells(5 + (j - k), RowA + 3 + l).Value = Result(l, k)
         Next l
     Next k
End Sub
[/vba]

Автор - Rioran
Дата добавления - 23.07.2015 в 18:15
SLAVICK Дата: Четверг, 23.07.2015, 18:30 | Сообщение № 2
Группа: Модераторы
Ранг: Старожил
Сообщений: 2290
Репутация: 766 ±
Замечаний: 0% ±

2019
По приложенному примеру выдало 4--2 -- 1 -- 6 = 35
а почему не 4--7--6 = 25
Или я чего -то не понял %)


Иногда все проще чем кажется с первого взгляда.
 
Ответить
СообщениеПо приложенному примеру выдало 4--2 -- 1 -- 6 = 35
а почему не 4--7--6 = 25
Или я чего -то не понял %)

Автор - SLAVICK
Дата добавления - 23.07.2015 в 18:30
Rioran Дата: Четверг, 23.07.2015, 18:34 | Сообщение № 3
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
SLAVICK, привет!

Потому что переход из 4 в 7 стоит 40 баллов:

По столбцу слева указаны объекты, откуда происходит переход

Таблица в файле - это исходные данные. Стоимости каждого ОТДЕЛЬНОГО перехода между всеми объектами. Именно на их основе происходят расчёты.


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279


Сообщение отредактировал Rioran - Четверг, 23.07.2015, 18:35
 
Ответить
СообщениеSLAVICK, привет!

Потому что переход из 4 в 7 стоит 40 баллов:

По столбцу слева указаны объекты, откуда происходит переход

Таблица в файле - это исходные данные. Стоимости каждого ОТДЕЛЬНОГО перехода между всеми объектами. Именно на их основе происходят расчёты.

Автор - Rioran
Дата добавления - 23.07.2015 в 18:34
MCH Дата: Четверг, 23.07.2015, 19:19 | Сообщение № 4
Группа: Админы
Ранг: Старожил
Сообщений: 2004
Репутация: 752 ±
Замечаний: ±

Роман, твой файл пока не смотрел (посмотрю).
Ты эту тему видел?
 
Ответить
СообщениеРоман, твой файл пока не смотрел (посмотрю).
Ты эту тему видел?

Автор - MCH
Дата добавления - 23.07.2015 в 19:19
Rioran Дата: Четверг, 23.07.2015, 20:31 | Сообщение № 5
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
Спасибо за ссылку. Нет, ту тему не видел и, что странно, когда искал по форуму по названию алгоритма - не нашел.


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
СообщениеСпасибо за ссылку. Нет, ту тему не видел и, что странно, когда искал по форуму по названию алгоритма - не нашел.

Автор - Rioran
Дата добавления - 23.07.2015 в 20:31
SLAVICK Дата: Четверг, 23.07.2015, 21:49 | Сообщение № 6
Группа: Модераторы
Ранг: Старожил
Сообщений: 2290
Репутация: 766 ±
Замечаний: 0% ±

2019
Rioran, здравствуй.
Странная таблица. Т.е из 4→7=40 баллов
А из 7→4=10 баллов?
Дальше и не смотрел пока- таблица сбила с толку. :-)


Иногда все проще чем кажется с первого взгляда.

Сообщение отредактировал SLAVICK - Четверг, 23.07.2015, 21:58
 
Ответить
СообщениеRioran, здравствуй.
Странная таблица. Т.е из 4→7=40 баллов
А из 7→4=10 баллов?
Дальше и не смотрел пока- таблица сбила с толку. :-)

Автор - SLAVICK
Дата добавления - 23.07.2015 в 21:49
AndreTM Дата: Четверг, 23.07.2015, 22:49 | Сообщение № 7
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 501 ±
Замечаний: 0% ±

2003 & 2010
Т.е из 4→7=40 баллов А из 7→4=10 баллов?
А почему нет? :)
Например (в приложении к физике реальности) - скажем, это кусок пути из одного города (4) в другой (7) пролегает по реке с бешеным течением, и указана стоимость затрат в каждом направлении...


Skype: andre.tm.007
Donate: Qiwi: 9517375010


Сообщение отредактировал AndreTM - Пятница, 24.07.2015, 19:48
 
Ответить
Сообщение
Т.е из 4→7=40 баллов А из 7→4=10 баллов?
А почему нет? :)
Например (в приложении к физике реальности) - скажем, это кусок пути из одного города (4) в другой (7) пролегает по реке с бешеным течением, и указана стоимость затрат в каждом направлении...

Автор - AndreTM
Дата добавления - 23.07.2015 в 22:49
Gustav Дата: Четверг, 23.07.2015, 23:14 | Сообщение № 8
Группа: Админы
Ранг: Участник клуба
Сообщений: 2793
Репутация: 1160 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
скажем, это путь из одного города в другой по реке с бешеным течением, и указана стоимость затрат в каждом направлении
...или просто сложная схема улиц с односторонним движением внутри города...


МОИ: Ник, Tip box: 41001663842605
 
Ответить
Сообщение
скажем, это путь из одного города в другой по реке с бешеным течением, и указана стоимость затрат в каждом направлении
...или просто сложная схема улиц с односторонним движением внутри города...

Автор - Gustav
Дата добавления - 23.07.2015 в 23:14
SLAVICK Дата: Пятница, 24.07.2015, 08:48 | Сообщение № 9
Группа: Модераторы
Ранг: Старожил
Сообщений: 2290
Репутация: 766 ±
Замечаний: 0% ±

2019
А почему нет?

Так я и не спорю, просто :
таблица сбила с толку.

Там не подписаны столбцы и строки, и я вместо 4--7=40 посмотрел на 7--4=10 :)


Иногда все проще чем кажется с первого взгляда.
 
Ответить
Сообщение
А почему нет?

Так я и не спорю, просто :
таблица сбила с толку.

Там не подписаны столбцы и строки, и я вместо 4--7=40 посмотрел на 7--4=10 :)

Автор - SLAVICK
Дата добавления - 24.07.2015 в 08:48
Rioran Дата: Пятница, 24.07.2015, 10:27 | Сообщение № 10
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
Там не подписаны столбцы и строки

Да, есть такое дело, каюсь =)

Выкладываю более наглядный пример по мотивам MMO RPG LineAge2. Матрицу стоимости и названия городов взял ЗДЕСЬ. Позволяет найти самый дешёвый по стоимости путь между выбранными городами. Код как и в первом посте, изменены только исходные данные.
К сообщению приложен файл: Dijkstra_L2.xlsb (23.9 Kb)


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
Сообщение
Там не подписаны столбцы и строки

Да, есть такое дело, каюсь =)

Выкладываю более наглядный пример по мотивам MMO RPG LineAge2. Матрицу стоимости и названия городов взял ЗДЕСЬ. Позволяет найти самый дешёвый по стоимости путь между выбранными городами. Код как и в первом посте, изменены только исходные данные.

Автор - Rioran
Дата добавления - 24.07.2015 в 10:27
nerv Дата: Четверг, 30.07.2015, 19:52 | Сообщение № 11
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

Визуализация работы A*, IDA*, Breadth-First-Search, Best-First-Search, Dijkstra, etc.
можно менять расположение точек, выставлять препятствия, управлять эвристиками и т.п.

к слову, я в своем решении использовал самописный Best-First-Search

Предлагаю Вашему вниманию

мои глаза %)


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba


Сообщение отредактировал nerv - Четверг, 30.07.2015, 19:59
 
Ответить
СообщениеВизуализация работы A*, IDA*, Breadth-First-Search, Best-First-Search, Dijkstra, etc.
можно менять расположение точек, выставлять препятствия, управлять эвристиками и т.п.

к слову, я в своем решении использовал самописный Best-First-Search

Предлагаю Вашему вниманию

мои глаза %)

Автор - nerv
Дата добавления - 30.07.2015 в 19:52
Rioran Дата: Пятница, 31.07.2015, 09:46 | Сообщение № 12
Группа: Авторы
Ранг: Ветеран
Сообщений: 903
Репутация: 290 ±
Замечаний: 0% ±

Excel 2013
nerv, первая ссылка просто восхитительна, сижу и медитирую =)

А про глаза что имеешь в виду?


Роман, Москва, voronov_rv@mail.ru
Яндекс-Деньги: 41001312674279
 
Ответить
Сообщениеnerv, первая ссылка просто восхитительна, сижу и медитирую =)

А про глаза что имеешь в виду?

Автор - Rioran
Дата добавления - 31.07.2015 в 09:46
MCH Дата: Суббота, 01.08.2015, 14:38 | Сообщение № 13
Группа: Админы
Ранг: Старожил
Сообщений: 2004
Репутация: 752 ±
Замечаний: ±

Делал как то поиск выхода из лабиринта волновым алгоритмом
https://yadi.sk/i/f0RrVpP5cpFYg

исходная тема
Также данный алгоритм использовал здесь
 
Ответить
СообщениеДелал как то поиск выхода из лабиринта волновым алгоритмом
https://yadi.sk/i/f0RrVpP5cpFYg

исходная тема
Также данный алгоритм использовал здесь

Автор - MCH
Дата добавления - 01.08.2015 в 14:38
MCH Дата: Понедельник, 10.08.2015, 21:53 | Сообщение № 14
Группа: Админы
Ранг: Старожил
Сообщений: 2004
Репутация: 752 ±
Замечаний: ±

Делал поиск кратчайшего пути в лабиринте используя алгоритм Дейкстры по разреженному графу.
Исходная тема: http://www.sql.ru/forum....2%f0%e0
По исходному лабиринту построен граф. При указании начальной и конечной точки строится кратчайший путь "на лету"
К сообщению приложен файл: Graph4SQL2.xlsm (54.0 Kb)
 
Ответить
СообщениеДелал поиск кратчайшего пути в лабиринте используя алгоритм Дейкстры по разреженному графу.
Исходная тема: http://www.sql.ru/forum....2%f0%e0
По исходному лабиринту построен граф. При указании начальной и конечной точки строится кратчайший путь "на лету"

Автор - MCH
Дата добавления - 10.08.2015 в 21:53
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!