Алгоритм Диница

Материал из testwiki
Перейти к навигации Перейти к поиску

Алгоритм Диница — полиномиальный алгоритм для нахождения максимального потока в транспортной сети, предложенный в 1970 году советским (впоследствии израильским) математиком Шаблон:Нп4. Временная сложность алгоритма составляет O(|V|2|E|). Получить такую оценку позволяет введение понятий вспомогательной сети и блокирующего (псевдомаксимального) потока. В сетях с единичными пропускными способностями существует более сильная оценка временной сложности: O(|E||V|).

Описание

Пусть G=(V,E,c,s,t) — транспортная сеть, в которой c(u,v) и f(u,v) — соответственно пропускная способность и поток через ребро (u,v).

Остаточная пропускная способность — отображение cf:V×V+ определённое как:
  1. Если (u,v)E,
    cf(u,v)=c(u,v)f(u,v)
    cf(v,u)=f(u,v) В других источниках cf(u,v)=c(u,v)f(u,v)+f(v,u)
  2. cf(u,v)=0 иначе.
Остаточная сеть — граф Gf=(V,Ef,cf|Ef,s,t), где
Ef={(u,v)V×Vcf(u,v)>0}.
Дополняющий путь — st путь в остаточном графе Gf.
Пусть dist(v) — длина кратчайшего пути из s в v в графе Gf. Тогда вспомогательная сеть графа Gf — граф GL=(V,EL,cf|EL,s,t), где
EL={(u,v)Efdist(v)=dist(u)+1}.
Блокирующий поток — st поток f такой, что граф G=(V,EL,cf|EL,s,t) с EL={(u,v)f(u,v)<cf|EL(u,v)} не содержит st пути.

Алгоритм

Алгоритм Диница

Вход: Сеть G=(V,E,c,s,t).
Выход: st поток f максимальной величины.
  1. Установить f(e)=0 для каждого eE.
  2. Создать GL из Gf графа G. Если dist(t)=, остановиться и вывести f.
  3. Найти блокирующий поток f в GL.
  4. Дополнить поток f потоком f и перейти к шагу 2.

Анализ

Можно показать, что каждый раз число рёбер в кратчайшем пути из источника в сток увеличивается хотя бы на единицу, поэтому в алгоритме не более n1 блокирующих потоков, где n — число вершин в сети. Вспомогательная сеть GL может быть построена обходом в ширину за время O(|V|+|E|), а блокирующий поток на каждом уровне графа может быть найден за время O(|V||E|). Поэтому время работы алгоритма Диница есть O(|V|)(O(|V|+|E|)+O(|V||E|))=O(|V|2|E|).

Используя структуры данных, называемые динамические деревья, можно находить блокирующий поток на каждой фазе за время O(|E|log|V|), тогда время работы алгоритма Диница может быть улучшено до O(|V||E|log|V|).

Пример

Ниже приведена симуляция алгоритма Диница. Во вспомогательной сети GL вершины с красными метками — значения dist(v). Блокирующий поток помечен синим.

G Gf GL
1.

Блокирующий поток состоит из путей:

  1. {s,1,3,t} с 4 единицами потока,
  2. {s,1,4,t} с 6 единицами потока, и
  3. {s,2,4,t} с 4 единицами потока.

Следовательно, блокирующий поток содержит 14 единиц, а величина потока |f| равна 14. Заметим, что дополняющий путь имеет 3 ребра.

2.

Блокирующий поток состоит из путей:

  1. {s,2,4,3,t} с 5 единицами потока.

Следовательно, блокирующий поток содержит 5 единиц, а величина потока |f| равна 14 + 5 = 19. Заметим, что дополняющий путь имеет 4 ребра.

3.

Сток t не достижим в сети Gf. Поэтому алгоритм останавливается и возвращает максимальный поток величины 19. Заметим, что в каждом блокирующем потоке количество рёбер в дополняющем пути увеличивается хотя бы на одно.

История

Алгоритм Диница был опубликован в 1970 г. бывшим советским учёным Ефимом Диницем, который сейчас является членом факультета вычислительной техники университета Бен-Гурион (Израиль), ранее, чем алгоритм Эдмондса — Карпа, который был опубликован в 1972, но создан ранее. Они независимо показали, что в алгоритме Форда — Фалкерсона в случае, если дополняющий путь является кратчайшим, длина дополняющего пути не уменьшается.

Алгоритм Диница с распространением

Временную сложность алгоритма можно уменьшить, если оптимизировать процесс поиска блокирующего потока. Для этого необходимо ввести понятие потенциала. Потенциал ребра eE есть pot(e)=cf(e), а потенциал вершины vV{s,t} равен pot(v)=min{eδ+(v)pot(e),eδ(v)pot(e)}. По той же логике pot(s)=eδ+(v)pot(e), а pot(t)=eδ(v)pot(e) . Идея улучшения заключается в том, чтобы искать вершину с минимальным положительным потенциалом в вспомогательной сети и строить блокирующий поток через нее, используя очереди.

Вход: Сеть G=(V,E,c,s,t).
Выход: st поток f максимальной величины.
  1. Установить f(e)=0 для каждого eE.
  2. Создать GL из Gf графа G. Если dist(s,t)=, остановиться и вывести f.
  3. Установить f(e)=0 для каждого eE.
  4. Определить потенциал каждой вершины.
  5. Пока существует вершина vV такая, что pot(v)>0:
    1. Определи поток f при помощи прямого распространения из v.
    2. Определи поток f при помощи обратного распространения из v.
    3. Дополни поток f потоками f и f.
  6. Дополнить поток f потоком f и перейти к шагу 2.

Алгоритмы прямого и обратного распространения служат поиску путей из v в t и из s в v соответственно. Пример работы алгоритма прямого распространения с использованием очередей:

Вход: Вспомогательная сеть GL=(V,EL,cf|EL,s,t), вершина vV такая, что pot(v)>0.
Выход: Поток f из источника s в вершину v, являющийся частью блокирующего потока.
  1. Установить для всех wV{v}: U(w)=0.
  2. Установить U(v)=pot(v) и pot(v)=0.
  3. Добавить v в очередь Q.
  4. Пока очередь Q не пуста:
    1. Установить значение v равным последнему элементу очереди.
    2. Пока U(v)>0:
      1. Для каждого ребра e=(v,w)δ+(v):
      2. f(e)=min{pot(e),U(v)}.
      3. Обнови U(v)=U(v)f(e).
      4. Обнови U(w)=U(w)+f(e).
      5. Установи pot(w)=pot(w)pot(e).
      6. Если wt и U(w)=f(e) удалить w из очереди Q.

В связи с тем, что в каждой итерации поиска блокирующего потока «насыщается» минимум одна вершина, он завершается за |V|1 итераций в худшем случае, в каждой из которых рассматриваются максимум |V| вершин. Пусть li — количество «насыщенных» ребер в каждой i-той итерации поиска блокирующего потока. Тогда его асимптотическая сложность равна i=1n1O(n+li)=O(n2+i=1n1li)=O(n2+m), где n — количество вершин и m — количество ребер в графе. Таким образом, асимптотическая сложность алгоритма Диница с распространением равна O(|V|3), так как блокирующий поток может проходить максимум через |V| вершин.

Литература

Ссылки