Алгоритм Левита — различия между версиями
(→Доказательство) |
(→Доказательство) |
||
Строка 58: | Строка 58: | ||
{{Лемма | {{Лемма | ||
|statement= Алгоритм отработает за конечное время | |statement= Алгоритм отработает за конечное время | ||
− | |proof= Не теряя общности, будем считать, что граф связен. Тогда | + | |proof= Не теряя общности, будем считать, что граф связен. Тогда алгоритм завершит работу, когда в <tex>M_0</tex> окажутся все вершины. Так как в исходном графе нет отрицательных циклов, то для каждой вершины существует кратчайший путь. Тогда расстояние до каждой вершины может уменьшится только конечное число раз и, как следствие, вершина будет переведена из <tex>M_0</tex> в <tex>M_1</tex> тоже конечное число раз. С другой стороны, на каждом шаге текущая вершина гарантированно помещается в <tex>M_0</tex>. Тогда за конечное число шагов все вершины окажутся в <tex>M_0</tex>. |
}} | }} | ||
Строка 66: | Строка 66: | ||
|proof= Предположим обратное. Тогда рассмотрим 2 случая: | |proof= Предположим обратное. Тогда рассмотрим 2 случая: | ||
# Вершина <tex>u</tex> попала в <tex>M_0</tex> позже <tex>v</tex>. Тогда должна была произойти релаксация ребра <tex>uv</tex> и она была неуспешной. Значит, такого варианта не может быть | # Вершина <tex>u</tex> попала в <tex>M_0</tex> позже <tex>v</tex>. Тогда должна была произойти релаксация ребра <tex>uv</tex> и она была неуспешной. Значит, такого варианта не может быть | ||
− | # Вершина <tex>u</tex> попала в <tex> | + | # Вершина <tex>u</tex> попала в <tex>M_0</tex> раньше <tex>v</tex>. Заметим, что с момента последнего попадания <tex>u</tex> в <tex>M_0</tex> расстояние до нее не менялось (иначе, вершина была бы извлечена из <tex>M_0</tex>). Вес ребра <tex>uv</tex> тоже не меняется. Значит, и релаксация ребра <tex>uv</tex> ничего не даст |
Противоречие. | Противоречие. | ||
}} | }} |
Версия 00:00, 10 января 2014
Алгоритм Левита (Levit algorithm) находит расстояние от заданной вершины
до всех остальных. Позволяет работать с ребрами отрицательного веса при отсутствии отрицательных циклов.Содержание
Алгоритм
Пусть
— текущая длина кратчайшего пути до вершины . Изначально, все элементы , кроме -го равны бесконечности; .Разделим вершины на три множества:
- — вершины, расстояние до которых уже вычислено (возможно, не окончательно)
- — вершины, расстояние до которых вычисляется. Это множество в свою очередь делится на две очереди:
- — основная очередь
- — срочная очередь
- — вершины, расстояние до которых еще не вычислено
Изначально все вершины, кроме
помещаются в множество . Вершина помещается в множество (в любую из очередей).
Шаг алгоритма: выбирается вершина из . Если очередь не пуста, то вершина берется из нее, иначе из . Далее, для каждого ребра :
- если , то переводится в конец очереди . При этом (производится релаксация ребра )
- если , то происходит релаксация ребра
- если и , то происходит релаксация ребра и помещается в
В конце шага помещаем вершину
в множество .
Алгоритм заканчивает работу, когда множество становится пустым.
Псевдокод
for uV : .add(s) for u s V : .add(u) while and : if : u .pop() else : u .pop() for uv E : if v : .push(v) .remove(v) relax(uv, d) if v : relax(uv, d) if v and : .push(v) .remove(v) relax(uv, d) .add(u)
Доказательство
Лемма: |
Алгоритм отработает за конечное время |
Доказательство: |
Не теряя общности, будем считать, что граф связен. Тогда алгоритм завершит работу, когда в | окажутся все вершины. Так как в исходном графе нет отрицательных циклов, то для каждой вершины существует кратчайший путь. Тогда расстояние до каждой вершины может уменьшится только конечное число раз и, как следствие, вершина будет переведена из в тоже конечное число раз. С другой стороны, на каждом шаге текущая вершина гарантированно помещается в . Тогда за конечное число шагов все вершины окажутся в .
Лемма: |
В конце работы алгоритма не найдется такое ребро , что его релаксация будет успешной |
Доказательство: |
Предположим обратное. Тогда рассмотрим 2 случая:
|
Из двух предыдущих лемм напрямую следует корректность алгоритма.
Сложность
В худшем случае алгоритм Левита работает за экспоненциальное время. Однако, на реальных графах алгоритм Левита работает быстрее, чем алгоритм Форда Беллмана и не многим хуже алгоритма Дейкстры.
Источники
- Алгоритм Левита - Википедия, свободная энциклопедия
- Алгоритм Левита - MAXimal::algo
- И. В. Романовский, Дискретный анализ, ISBN 5-7940-0138-0; 2008 г., стр. 228-234.