Алгоритм Форда-Беллмана — различия между версиями
(→Корректность) |
|||
| Строка 1: | Строка 1: | ||
| − | Для заданного взвешенного графа <tex>G = (V, E)</tex> | + | {{Задача |
| − | В | + | |definition=Для заданного взвешенного графа <tex>G = (V, E)</tex> найти кратчайшие пути из заданной вершины <tex> s </tex> до всех остальных вершин. |
| + | В случае, когда в графе <tex>G</tex> содержатся отрицательные циклы, достижимые из <tex>s</tex>, сообщить, что кратчайших путей не существует. | ||
| + | }} | ||
==Введение== | ==Введение== | ||
| Строка 7: | Строка 9: | ||
Теперь перепишем ее для пути кратчайшей длины. <tex>s</tex> {{---}} стартовая вершина. | Теперь перепишем ее для пути кратчайшей длины. <tex>s</tex> {{---}} стартовая вершина. | ||
<tex> d[k][u] = \min\limits_{v : vu \; \in E}(d[k-1][v] \: + \: \omega[uv])</tex>, при этом <tex>d[0][s] = 0</tex>, а <tex>d[0][u] = +\infty </tex> | <tex> d[k][u] = \min\limits_{v : vu \; \in E}(d[k-1][v] \: + \: \omega[uv])</tex>, при этом <tex>d[0][s] = 0</tex>, а <tex>d[0][u] = +\infty </tex> | ||
| − | |||
{{Лемма | {{Лемма | ||
|statement=Если существует кратчайший путь от <tex>s</tex> до <tex>t</tex>, то <tex> \rho(s, \, t) \: = \: \min\limits_{k = 0..n-1} d[k][t]</tex> | |statement=Если существует кратчайший путь от <tex>s</tex> до <tex>t</tex>, то <tex> \rho(s, \, t) \: = \: \min\limits_{k = 0..n-1} d[k][t]</tex> | ||
| Строка 28: | Строка 29: | ||
{{Лемма | {{Лемма | ||
|statement=Пусть <tex>G = (V, E)</tex> — взвешенный ориентированный граф, <tex> s </tex> — стартовая вершина. | |statement=Пусть <tex>G = (V, E)</tex> — взвешенный ориентированный граф, <tex> s </tex> — стартовая вершина. | ||
| − | Тогда после завершения <tex>k</tex> итераций цикла <tex>for(k)</tex> выполняется неравенство <tex> \rho(s, u) \leqslant d'[u] \leqslant \min\limits_{i = 0..k} d[i][u]</tex>. | + | Тогда после завершения <tex>k</tex> итераций цикла <tex>\mathrm{for(k)}</tex> выполняется неравенство <tex> \rho(s, u) \leqslant d'[u] \leqslant \min\limits_{i = 0..k} d[i][u]</tex>. |
|proof=Воспользуемся индукцией по <tex>k</tex>: | |proof=Воспользуемся индукцией по <tex>k</tex>: | ||
| Строка 71: | Строка 72: | ||
В этом алгоритме используется релаксация, в результате которой <tex>d[v]</tex> уменьшается до тех пор, пока не станет равным <tex>\delta(s, v)</tex>. | В этом алгоритме используется релаксация, в результате которой <tex>d[v]</tex> уменьшается до тех пор, пока не станет равным <tex>\delta(s, v)</tex>. | ||
| − | <tex>d[v]</tex> - оценка веса кратчайшего пути из вершины <tex>s</tex> в каждую вершину <tex>v \in V</tex>.<br> | + | <tex>d[v]</tex> {{---}} оценка веса кратчайшего пути из вершины <tex>s</tex> в каждую вершину <tex>v \in V</tex>.<br> |
| − | <tex>\delta(s, v)</tex> - фактический вес кратчайшего пути из <tex>s</tex> в вершину <tex>v</tex>. | + | <tex>\delta(s, v)</tex> {{---}} фактический вес кратчайшего пути из <tex>s</tex> в вершину <tex>v</tex>. |
{{Лемма | {{Лемма | ||
| − | |statement=Пусть <tex>G = (V, E) </tex> | + | |statement=Пусть <tex>G = (V, E) </tex> {{---}} взвешенный ориентированный граф, <tex> s </tex> {{---}} стартовая вершина. Тогда после завершения <tex> |V| - 1 </tex> итераций цикла для всех вершин, достижимых из <tex>s</tex>, выполняется равенство <tex> d[v] = \delta (s, v) </tex>. |
|proof=Рассмотрим произвольную вершину <tex>v</tex>, достижимую из <tex>s</tex>. | |proof=Рассмотрим произвольную вершину <tex>v</tex>, достижимую из <tex>s</tex>. | ||
| − | Пусть <tex>p = \langle v_0,..., v_{k} \rangle </tex>, где <tex>v_0 = s</tex>, <tex>v_{k} = v</tex> | + | Пусть <tex>p = \langle v_0,..., v_{k} \rangle </tex>, где <tex>v_0 = s</tex>, <tex>v_{k} = v</tex> {{---}} кратчайший ациклический путь из <tex> s </tex> в <tex> v </tex>. Путь <tex> p </tex> содержит не более <tex> |V| - 1 </tex> ребер. Поэтому <tex>k \le |V| - 1</tex>. |
Докажем следующее утверждение: | Докажем следующее утверждение: | ||
| Строка 96: | Строка 97: | ||
{{Теорема | {{Теорема | ||
| − | |statement=Пусть <tex>G = (V, E) </tex> - взвешенный ориентированный граф, <tex> s </tex> | + | |statement=Пусть <tex>G = (V, E) </tex> - взвешенный ориентированный граф, <tex> s </tex> {{---}} стартовая вершина. Если граф <tex> G </tex> не содержит отрицательных циклов, достижимых из вершины <tex> s </tex>, то алгоритм возвращает <tex> true </tex> и для всех <tex> v \in V \ d[v] = \delta (s, v)</tex>. Если граф <tex> G </tex> содержит отрицательные циклы, достижимые из вершины <tex> s </tex>, то алгоритм возвращает <tex> false </tex>. |
|proof=Пусть граф <tex> G </tex> не содержит отрицательных циклов, достижимых из вершины <tex> s </tex>. | |proof=Пусть граф <tex> G </tex> не содержит отрицательных циклов, достижимых из вершины <tex> s </tex>. | ||
Версия 22:39, 18 декабря 2015
| Задача: |
| Для заданного взвешенного графа найти кратчайшие пути из заданной вершины до всех остальных вершин. В случае, когда в графе содержатся отрицательные циклы, достижимые из , сообщить, что кратчайших путей не существует. |
Содержание
Введение
Сначала стоит вспомнить формулу для количества путей длины . Теперь перепишем ее для пути кратчайшей длины. — стартовая вершина. , при этом , а
| Лемма: |
Если существует кратчайший путь от до , то |
| Доказательство: |
| Пусть кратчайший путь состоит из ребер, тогда корректность формулы следует из динамики, приведенной ниже. |
Псевдокод
Используя приведенные формулы, алгоритм можно реализовать методом динамического программирования.
for for for
Также релаксацию можно свести к одномерному случаю (одномерный массив будем обозначать ):
Корректность
| Лемма: |
Пусть — взвешенный ориентированный граф, — стартовая вершина.
Тогда после завершения итераций цикла выполняется неравенство . |
| Доказательство: |
|
Воспользуемся индукцией по : База индукции
Индукционный переход
|
Реализация алгоритма и ее корректность
Bellman_Ford(G, s) for для каждой for to for для каждого ребра if then for для каждого ребра if then return return
В этом алгоритме используется релаксация, в результате которой уменьшается до тех пор, пока не станет равным .
— оценка веса кратчайшего пути из вершины в каждую вершину .
— фактический вес кратчайшего пути из в вершину .
| Лемма: |
Пусть — взвешенный ориентированный граф, — стартовая вершина. Тогда после завершения итераций цикла для всех вершин, достижимых из , выполняется равенство . |
| Доказательство: |
|
Рассмотрим произвольную вершину , достижимую из . Пусть , где , — кратчайший ациклический путь из в . Путь содержит не более ребер. Поэтому . Докажем следующее утверждение:
Воспользуемся индукцией по : База индукции
Индукционный переход
|
| Теорема: |
Пусть - взвешенный ориентированный граф, — стартовая вершина. Если граф не содержит отрицательных циклов, достижимых из вершины , то алгоритм возвращает и для всех . Если граф содержит отрицательные циклы, достижимые из вершины , то алгоритм возвращает . |
| Доказательство: |
|
Пусть граф не содержит отрицательных циклов, достижимых из вершины . Тогда если вершина достижима из , то по лемме . Если вершина не достижима из , то из несуществования пути. Теперь докажем, что алгоритм вернет значение . После выполнения алгоритма верно, что для всех , значит ни одна из проверок не вернет значения . Пусть граф содержит отрицательный цикл , где , достижимый из вершины . Тогда . Предположим, что алгоритм возвращает , тогда для выполняется . Просуммируем эти неравенства по всему циклу: . Из того, что следует, что . Получили, что , что противоречит отрицательности цикла . |
Сложность
Инициализация занимает времени, каждый из проходов требует времени, обход по всем ребрам для проверки наличия отрицательного цикла занимает времени. Значит алгоритм Беллмана-Форда работает за времени.
Нахождение отрицательного цикла
Приведенная выше реализация позволяет определить наличие в графе цикла отрицательного веса. Чтобы найти сам цикл, достаточно хранить вершины, из которых производится релаксация.
Если после итерации найдется вершина , расстояние до которой можно уменьшить, то эта вершина либо лежит на каком-нибудь цикле отрицательного веса, либо достижима из него. Чтобы найти вершину, которая лежит на цикле, можно раз пройти назад по предкам из вершины . Так как наибольшая длина пути в графе из вершин равна , то полученная вершина будет гарантированно лежать на отрицательном цикле.
Зная, что вершина лежит на цикле отрицательного веса, можно восстанавливать путь по сохраненным вершинам до тех пор, пока не встретится та же вершина . Это обязательно произойдет, так как в цикле отрицательного веса релаксации происходят по кругу.
Neg_Cycle(G, s) for для каждой for to for для каждого ребра if then for для каждого ребра if then for to while break return
Источники
- Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Алгоритмы: построение и анализ / пер. с англ. — изд. 2-е — М.: Издательский дом «Вильямс», 2009. — с.672 — 676. — ISBN 978-5-8459-0857-5.
- Алгоритм Форда-Беллмана