Алгоритм Левита — различия между версиями
Никита (обсуждение | вклад) (→Алгоритм) |
Никита (обсуждение | вклад) (→Псевдокод) |
||
| Строка 25: | Строка 25: | ||
== Псевдокод == | == Псевдокод == | ||
| + | |||
| + | '''for''' u <tex>\in</tex> V ''':''' | ||
| + | <tex>d_v \gets</tex> <tex>\infty</tex> | ||
| + | <tex>d_s \gets 0</tex> | ||
| + | |||
| + | <tex>M_1^{''}</tex>.add(s) | ||
| + | '''for''' u <tex>\neq</tex> s <tex>\in</tex> V ''':''' | ||
| + | <tex>M_2</tex>.add(u) | ||
| + | |||
| + | '''while''' <tex>M_1 \neq \varnothing</tex> ''':''' | ||
| + | '''if''' <tex>M_1^{''} \neq \varnothing</tex> ''':''' | ||
| + | u <tex>\gets</tex> <tex>M_1^{''}</tex>.pop() | ||
| + | '''else :''' | ||
| + | u <tex>\gets</tex> <tex>M_1{'}</tex>.pop() | ||
| + | |||
| + | '''for''' uv <tex>\in</tex> E ''':''' | ||
| + | '''if''' v <tex>\in M_2</tex> ''':''' | ||
| + | <tex>M_1^{'}</tex>.push(v) | ||
| + | relax(uv) | ||
| + | '''if''' v <tex>\in M_1</tex> ''':''' | ||
| + | relax(uv) | ||
| + | '''if''' v <tex>\in M_0</tex> '''and''' <tex>d_v > d_u + w_{uv}</tex> ''':''' | ||
| + | relax(uv) | ||
| + | <tex>M_1^{''}</tex>.push(v) | ||
| + | |||
| + | <tex>M_0</tex>.add(u) | ||
== Сложность == | == Сложность == | ||
Версия 14:14, 19 октября 2013
Алгоритм Левита находит расстояние от заданной вершины до всех остальных. Данный алгоритм является модификацией алгоритмы Дейкстры, которая позволяет работать с ребрами отрицательного веса.
Содержание
Алгоритм
Пусть — текущая длина кратчайшего пути до вершины . Изначально, для всех ; .
Разделим вершины на три множества:
- — вершины, расстояние до которых уже вычислено(возможно, не окончательно)
- — вершины, расстояние до которых вычисляется. Это множество в свою очередь делится на два упорядоченных подмножества:
- — основная очередь
- — срочная очередь
- — вершины, расстояние до которых не вычисленно
Изначально все вершины, кроме помещаются в множество . Вершина помещается в множество .
Шаг алгоритма: выбирается вершина из . Если подмножество не пусто, то вершина берется из него, иначе из . Далее, для каждого ребра :
- если , то переводится в конец очереди . При этом
- если , то происходит релаксация ребра
- если и , то происходит релаксация ребра и помещается в
В конце шага помещаем вершину в множество .
Алгоритм заканчивает работу, когда множество становится пустым.
Псевдокод
for u V : .add(s) for u s V : .add(u) while : if : u .pop() else : u .pop() for uv E : if v : .push(v) relax(uv) if v : relax(uv) if v and : relax(uv) .push(v) .add(u)