Алгоритм Левита — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Источники)
(Источники)
Строка 65: Строка 65:
  
 
== Источники ==
 
== Источники ==
* [http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B5%D0%B2%D0%B8%D1%82%D0%B0: Алгоритм Левита - Википедия, свободная энциклопедия]
+
* [http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B5%D0%B2%D0%B8%D1%82%D0%B0 Алгоритм Левита - Википедия, свободная энциклопедия]
* [http://e-maxx.ru/algo/levit_algorithm: Алгоритм Левита - MAXimal::algo]
+
* [http://e-maxx.ru/algo/levit_algorithm Алгоритм Левита - MAXimal::algo]
* И. В. Романовский, '''Дискретный анализ''', ISBN 5-7940-0138-0; 2008 г., стр. 228-234.
+
* И. В. Романовский, Дискретный анализ, ISBN 5-7940-0138-0; 2008 г., стр. 228-234.

Версия 14:28, 19 октября 2013

Алгоритм Левита находит расстояние от заданной вершины [math]s[/math] до всех остальных. Данный алгоритм является модификацией алгоритмы Дейкстры, которая позволяет работать с ребрами отрицательного веса.

Алгоритм

Пусть [math]d_i[/math] — текущая длина кратчайшего пути до вершины [math]i[/math]. Изначально, для всех [math]i \neq s : d_i \gets \infty[/math]; [math]d_s \gets 0[/math].

Разделим вершины на три множества:

  • [math]M_0[/math] — вершины, расстояние до которых уже вычислено(возможно, не окончательно)
  • [math]M_1[/math] — вершины, расстояние до которых вычисляется. Это множество в свою очередь делится на два упорядоченных подмножества:
  1. [math]M_1^{'}[/math] — основная очередь
  2. [math]M_1^{''}[/math] — срочная очередь
  • [math]M_2[/math] — вершины, расстояние до которых не вычисленно

Изначально все вершины, кроме [math]s[/math] помещаются в множество [math]M_2[/math]. Вершина [math]s[/math] помещается в множество [math]M_1[/math].


Шаг алгоритма: выбирается вершина [math]u[/math] из [math]M_1[/math]. Если подмножество [math]M_1^{''}[/math] не пусто, то вершина берется из него, иначе из [math]M_1^{'}[/math]. Далее, для каждого ребра [math]uv \in E[/math]:

  • если [math]v \in M_2[/math], то [math]v[/math] переводится в конец очереди [math]M_1^{'}[/math]. При этом [math]d_v \gets d_u + w_{uv}[/math]
  • если [math]v \in M_1[/math], то происходит релаксация ребра [math]uv[/math]
  • если [math]v \in M_0[/math] и [math]d_v \gt d_u + w_{uv}[/math], то происходит релаксация ребра [math]uv[/math] и [math]v[/math] помещается в [math]M_1^{''}[/math]

В конце шага помещаем вершину [math]u[/math] в множество [math]M_0[/math].


Алгоритм заканчивает работу, когда множество [math]M_1[/math] становится пустым.

Псевдокод

for u [math]\in[/math] V :
   [math]d_v \gets[/math] [math]\infty[/math]
[math]d_s \gets 0[/math]

[math]M_1^{''}[/math].add(s)
for u [math]\neq[/math] s [math]\in[/math] V :
   [math]M_2[/math].add(u)

while [math]M_1 \neq \varnothing[/math] :
   if [math]M_1^{''} \neq \varnothing[/math] :
      u [math]\gets[/math] [math]M_1^{''}[/math].pop()
   else :
      u [math]\gets[/math] [math]M_1{'}[/math].pop()

   for uv [math]\in[/math] E :
      if v [math]\in M_2[/math] :
         [math]M_1^{'}[/math].push(v)
         relax(uv)
      if v [math]\in M_1[/math] :
         relax(uv)
      if v [math]\in M_0[/math] and [math]d_v \gt  d_u + w_{uv}[/math] :
         relax(uv)
         [math]M_1^{''}[/math].push(v)

   [math]M_0[/math].add(u)

Корректность

Сложность

См. также

Источники