Кратчайший путь в ациклическом графе — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 8: Строка 8:
  
 
==Реализация==
 
==Реализация==
Реализуем данный алгоритм:
+
Реализуем данный алгоритм следующим образом: рассмотрим вершину i. Будем пересчитывать d для всех вершин, выходящих из i:
 
   //w - матрицы как в описании, d - массив как в описании, p - массив индексов вершин графа в порядке топологической сортировки, i, j - счетчики <br />
 
   //w - матрицы как в описании, d - массив как в описании, p - массив индексов вершин графа в порядке топологической сортировки, i, j - счетчики <br />
 
   inputData() //считывание данных <br />
 
   inputData() //считывание данных <br />
Строка 27: Строка 27:
 
| || '''1''' || '''2''' || '''3''' || '''4''' || '''5''' || '''6''' || '''7''' || '''8'''
 
| || '''1''' || '''2''' || '''3''' || '''4''' || '''5''' || '''6''' || '''7''' || '''8'''
 
|-
 
|-
| '''1''' ||  0 ||  -  ||  -  ||  5  ||  -  ||  -  ||  -  ||  -  
+
| '''1''' ||  - ||  -  ||  -  ||  5  ||  -  ||  -  ||  -  ||  -  
 
|-
 
|-
| '''2''' ||  1  ||  0 ||  1  ||  -  ||  4  ||  3  ||  -  ||  -  
+
| '''2''' ||  1  ||  - ||  1  ||  -  ||  4  ||  3  ||  -  ||  -  
 
|-
 
|-
| '''3''' ||  -  ||  -  ||  0 ||  -  ||  -  ||  1  ||  -  ||  -  
+
| '''3''' ||  -  ||  -  ||  - ||  -  ||  -  ||  1  ||  -  ||  -  
 
|-
 
|-
| '''4''' ||  -  ||  -  ||  -  ||  0 ||  -  ||  -  ||  -  ||  -  
+
| '''4''' ||  -  ||  -  ||  -  ||  - ||  -  ||  -  ||  -  ||  -  
 
|-
 
|-
| '''5''' ||  -  ||  -  ||  -  ||  3  ||  0 ||  -  ||  -  ||  1  
+
| '''5''' ||  -  ||  -  ||  -  ||  3  ||  - ||  -  ||  -  ||  1  
 
|-
 
|-
| '''6''' ||  -  ||  -  ||  -  ||  5  ||  -  ||  0 ||  2  ||  -  
+
| '''6''' ||  -  ||  -  ||  -  ||  5  ||  -  ||  - ||  2  ||  -  
 
|-
 
|-
| '''7''' ||  -  ||  -  ||  -  ||  2  ||  -  ||  -  ||  0 ||  -  
+
| '''7''' ||  -  ||  -  ||  -  ||  2  ||  -  ||  -  ||  - ||  -  
 
|-
 
|-
| '''8''' ||  -  ||  -  ||  -  ||  1  ||  -  ||  -  ||  -  ||  0
+
| '''8''' ||  -  ||  -  ||  -  ||  1  ||  -  ||  -  ||  -  ||  -
 
|}
 
|}
 
Требуется найти путь из '''2''' в '''4'''. <br />
 
Требуется найти путь из '''2''' в '''4'''. <br />
Строка 63: Строка 63:
 
==Источники==
 
==Источники==
 
*[http://www.ics.uci.edu/~eppstein/161/960208.html Алгоритмы поиска кратчайшего пути в графе]
 
*[http://www.ics.uci.edu/~eppstein/161/960208.html Алгоритмы поиска кратчайшего пути в графе]
*[http://neerc.ifmo.ru/mediawiki/index.php/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BD%D0%B0_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%B5 Принцип оптимальности на префиксе]
+
*[[Динамическое_программирование#.D0.9F.D1.80.D0.B8.D0.BD.D1.86.D0.B8.D0.BF_.D0.BE.D0.BF.D1.82.D0.B8.D0.BC.D0.B0.D0.BB.D1.8C.D0.BD.D0.BE.D1.81.D1.82.D0.B8_.D0.BD.D0.B0_.D0.BF.D1.80.D0.B5.D1.84.D0.B8.D0.BA.D1.81.D0.B5|Принцип оптимальности на префиксе]]
 
* [http://en.wikipedia.org/wiki/Optimal_substructure Принцип оптимальности на подзадаче (в качестве примера разбирается задача поиска кратчайшего пути в ациклическом графе)(англ.)]
 
* [http://en.wikipedia.org/wiki/Optimal_substructure Принцип оптимальности на подзадаче (в качестве примера разбирается задача поиска кратчайшего пути в ациклическом графе)(англ.)]
 
[[Категория: Динамическое программирование]] [[Категория: Дискретная математика и алгоритмы]]
 
[[Категория: Динамическое программирование]] [[Категория: Дискретная математика и алгоритмы]]

Версия 08:45, 16 января 2012

Пусть дан ациклический ориентированный взвешенный граф. Требуется найти вес кратчайшего пути из u в v

Определение:
Кратчайший путь из u в v – это такой путь из u в v, что его сумарный вес входящих в него ребер минимален

Решение

Пусть d — массив, где d[i] — вес кратчайшего пути из u в i. Изначально значения d равны бесконечности, кроме d[u], который равен 0. Пусть w[i][j] - вес ребра из i в j. Будем обходить граф в порядке топологической сортировки. Получаем следующие соотношения:

[math] d[i] = \min\limits_{\mathop{j:j \rightsquigarrow i}} (d[j] + w[j][i]) [/math]

Так как мы обходим граф в порядке топологической сортировки, то на i-ом шаге во всех d[j] (j такие, что: существует ребро из j в i) уже записаны оптимальные ответы, и следовательно в d[i] также будет записан оптимальный ответ.

Реализация

Реализуем данный алгоритм следующим образом: рассмотрим вершину i. Будем пересчитывать d для всех вершин, выходящих из i:

 //w - матрицы как в описании, d - массив как в описании, p - массив индексов вершин графа в порядке топологической сортировки, i, j - счетчики 
inputData() //считывание данных
for i = 1 to n d[i] = infinity
p = topSort(w) //топологическая сортировка графа
d[p[u]] = 0
for i = 1 to n for j: есть ребро из p[i] в j d[j] = min(d[j], d[p[i]] + w[p[i]][j])
writeData(); // запись данных

Пример

граф из примера

Пусть дан граф со следующими весами w ребер:

1 2 3 4 5 6 7 8
1 - - - 5 - - - -
2 1 - 1 - 4 3 - -
3 - - - - - 1 - -
4 - - - - - - - -
5 - - - 3 - - - 1
6 - - - 5 - - 2 -
7 - - - 2 - - - -
8 - - - 1 - - - -

Требуется найти путь из 2 в 4.
Массив p будет выглядеть следующим образом:

1 2 3 4 5 6 7 8
2 3 6 7 1 5 8 4

Массив d будет выглядеть следующим образом:

1 2 3 4 5 6 7 8
1 0 3 5 3 2 4 4

Ответ равен 2.

Источники