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

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

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

Асимптотика

Если информация о входящих и исходящих дугах будет храниться в виде связных списков, то для того, чтобы пропустить поток, на каждой итерации будет выполнено [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]. Модификация алгоритма Диница, основанная на этом алгоритме, называется алгоритмом Карзанова.

Источники