Алгоритм поиска блокирующего потока в ациклической сети — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Идея)
(Идея)
Строка 26: Строка 26:
  
 
  MPM algorithm(s, t)
 
  MPM algorithm(s, t)
  for each <tex>(uv) \in E</tex>
+
  <tex>for each (uv) \in E</tex>
   f(uv) = 0;
+
   <tex>f(uv)</tex> = 0;
  Вычисляем остаточную сеть R;
+
  Вычисляем остаточную сеть <tex>R</tex>;
  Найдём вспомогательный граф L для R;
+
  Найдём вспомогательный граф <tex>L</tex> для <tex>R</tex>;
  while (t \in L)
+
  <tex>while (t \in L)</tex>
  begin
+
  <tex>begin</tex>
   while (t достижима из s в L)
+
   <tex>while</tex> (<tex>t</tex> достижима из <tex>s</tex> в <tex>L</tex>)
   begin
+
   <tex>begin</tex>
     найдём v с миниальной пропускной способностью g;
+
     найдём <tex>v</tex> с миниальной пропускной способностью <tex>g</tex>;
     проталкиваем g единиц потока из v в t;
+
     проталкиваем <tex>g</tex> единиц потока из <tex>v</tex> в <tex>t</tex>;
     проталкиваем g единиц потока из s в v;
+
     проталкиваем <tex>g</tex> единиц потока из <tex>s</tex> в <tex>v</tex>;
     изменяем f, L и R;
+
     изменяем <tex>f</tex>, <tex>L</tex> и <tex>R</tex>;
   end
+
   <tex>end</tex>
   вычисляем новый вспомогательный граф L из R;
+
   вычисляем новый вспомогательный граф <tex>L</tex> из <tex>R</tex>;
  end
+
  <tex>end</tex>
  
 
===Асимптотика===
 
===Асимптотика===

Версия 01:03, 25 декабря 2011

Жадный Алгоритм

Идея

Идея заключается в том, чтобы по одному находить пути из [math]s[/math] в [math]t[/math], пока это возможно.

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

Данная идея корректна, поскольку [math]dfs[/math] найдёт все пути из [math]s[/math] в [math]t[/math], если из [math]s[/math] достижима [math]t[/math], а пропускная способность каждого ребра [math]c(u, v)\gt 0[/math] поэтому, насыщая рёбра, мы хотя бы единожды достигнем стока [math]t[/math], следовательно блокирующий поток всегда найдётся.

Асимптотика

Используя [math]dfs[/math] каждый путь находится за [math]O(E)[/math]. Поскольку каждый путь насыщает как минимум одно ребро, всего будет [math]O(E)[/math] путей. Итого общая асимптотика составляет [math]O(E^2)[/math].

Удаляющий обход

Идея

По-прежнему по одному находятся пути из [math]s[/math] в [math]t[/math], но применяется следующая оптимизация: в процессе обхода в глубину удаляются все ребра, вдоль которых нельзя дойти до стока. То есть, если для текущей вершины [math]v[/math] выполнено [math]dfs(v) = false[/math], нужно удалить из графа эту вершину и все инцидентные ей ребра. С точки зрения реализации, надо просто поддерживать в списке смежности каждой вершины указатель на первое неудалённое ребро, и увеличивать этот указатель в цикле внутри обхода в глубину.

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

Аналогично предыдущему пункту.

Асимптотика

Если обход в глубину достигает стока, насыщается как минимум одно ребро, иначе как минимум один указатель продвигается вперед. Значит один запуск обхода в глубину работает за [math]O(V + K)[/math], где [math]K[/math] - число продвижения указателей. Учитывая, что всего запусков обхода в глубину в рамках поиска одного блокирующего потока будет [math]O(P)[/math], где [math]P[/math] — число рёбер, насыщенных этим блокирующим потоком, то весь алгоритм поиска блокирующего потока отработает за [math]O(PV + \sum\limits_i{K_i})[/math], что, учитывая, что все указатели в сумме прошли расстояние [math]O(E)[/math], дает асимптотику [math]O(PV + E)[/math]. В худшем случае, когда блокирующий поток насыщает все ребра, асимптотика получается [math]O(VE)[/math].

Замечание Если в алгоритме Диница искать блокирующий поток удаляющим обходом, то его эффективность составит [math]O(V^2E)[/math], что уже лучше эффективности алгоритма Эдмондса-Карпа [math]O(VE^2)[/math].

Алгоритм узкого места

Идея

Для каждой вершины вводится потенциал потока, равный максимальному дополнительному потоку, который может пройти через эту вершину. Далее следует цикл. На каждой его итерации определяется вершина [math]r[/math] с минимальным потенциалом [math]\rho[/math]. Затем пускается поток величины [math]\rho[/math] из истока в сток, проходящий через эту вершину. При этом если остаточная пропускная способность ребра равна нулю, то это ребро удаляется. Также, удаляются все вершины, у которых не остаётся ни одного входящего и/или ни одного выходящего ребра. При удалении вершины все смежные ребра удаляются.

MPM algorithm(s, t)
[math]for each (uv) \in E[/math]
  [math]f(uv)[/math] = 0;
Вычисляем остаточную сеть [math]R[/math];
Найдём вспомогательный граф [math]L[/math] для [math]R[/math];
[math]while (t \in L)[/math]
[math]begin[/math]
  [math]while[/math] ([math]t[/math] достижима из [math]s[/math] в [math]L[/math])
  [math]begin[/math]
    найдём [math]v[/math] с миниальной пропускной способностью [math]g[/math];
    проталкиваем [math]g[/math] единиц потока из [math]v[/math] в [math]t[/math];
    проталкиваем [math]g[/math] единиц потока из [math]s[/math] в [math]v[/math];
    изменяем [math]f[/math], [math]L[/math] и [math]R[/math];
  [math]end[/math]
  вычисляем новый вспомогательный граф [math]L[/math] из [math]R[/math];
[math]end[/math]

Асимптотика

Если информация о входящих и исходящих дугах будет храниться в виде связных списков, то для того, чтобы пропустить поток, на каждой итерации будет выполнено [math]O(V + E_i)[/math] действий, где [math]V[/math] соответствует числу рёбер, для которых остаточная пропускная способность уменьшилась, но осталась положительной, а [math]E_i[/math] — числу удалённых ребер. Таким образом, для поиска блокирующего потока будет выполнено [math]\sum\limits_i{O(V+E_i)} = O(V^2)[/math] действий.

Замечание Алгоритм Малхотры — Кумара — Махешвари для поиска блокирующего потока использует алгоритм узкого места.

Волновой алгоритм

Используя предпотоки, позволяет найти блокирующий поток за [math]O(V^2)[/math]. Модификация алгоритма Диница, основанная на этом алгоритме, называется алгоритмом Карзанова.

Источники