Алгоритм поиска блокирующего потока в ациклической сети — различия между версиями
(→Источники) |
(→Источники) |
||
Строка 78: | Строка 78: | ||
==Источники== | ==Источники== | ||
− | [http://e-maxx.ru/algo/dinic#8 e-maxx] | + | *[http://e-maxx.ru/algo/dinic#8 e-maxx] |
− | [http://www.facweb.iitkgp.ernet.in/~arijit/courses/autumn2006/cs60001/lec-flow-4.pdf] | + | *[http://www.facweb.iitkgp.ernet.in/~arijit/courses/autumn2006/cs60001/lec-flow-4.pdf] |
− | [http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BB%D1%85%D0%BE%D1%82%D1%80%D1%8B_%E2%80%94_%D0%9A%D1%83%D0%BC%D0%B0%D1%80%D0%B0_%E2%80%94_%D0%9C%D0%B0%D1%85%D0%B5%D1%88%D0%B2%D0%B0%D1%80%D0%B8 Алгоритм Малхотры — Кумара — Махешвари] | + | *[http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%B0%D0%BB%D1%85%D0%BE%D1%82%D1%80%D1%8B_%E2%80%94_%D0%9A%D1%83%D0%BC%D0%B0%D1%80%D0%B0_%E2%80%94_%D0%9C%D0%B0%D1%85%D0%B5%D1%88%D0%B2%D0%B0%D1%80%D0%B8 Алгоритм Малхотры — Кумара — Махешвари] |
Версия 01:33, 25 декабря 2011
Содержание
Жадный Алгоритм
Идея
Идея заключается в том, чтобы по одному находить пути из
в , пока это возможно.Корректность
Данная идея корректна, поскольку
найдёт все пути из в , если из достижима , а пропускная способность каждого ребра поэтому, насыщая рёбра, мы хотя бы единожды достигнем стока , следовательно блокирующий поток всегда найдётся.Асимптотика
Используя
каждый путь находится за . Поскольку каждый путь насыщает как минимум одно ребро, всего будет путей. Итого общая асимптотика составляет .Удаляющий обход
Идея
По-прежнему по одному находятся пути из
в , но применяется следующая оптимизация: в процессе обхода в глубину удаляются все ребра, вдоль которых нельзя дойти до стока. То есть, если для текущей вершины выполнено , нужно удалить из графа эту вершину и все инцидентные ей ребра. С точки зрения реализации, надо просто поддерживать в списке смежности каждой вершины указатель на первое неудалённое ребро, и увеличивать этот указатель в цикле внутри обхода в глубину.int dfs (int v, int flow) { if (!flow) return 0; if (v == t) return flow; for (int & to=ptr[v]; to<n; ++to) { if (d[to] != d[v] + 1) continue; int pushed = dfs (to, min (flow, c[v][to] - f[v][to])); if (pushed) { f[v][to] += pushed; return pushed; } } return 0; } ..................................... while (pushed = dfs(s, INF)) flow += pushed;
Корректность
Аналогично предыдущему пункту.
Асимптотика
Если обход в глубину достигает стока, насыщается как минимум одно ребро, иначе как минимум один указатель продвигается вперед. Значит один запуск обхода в глубину работает за блокирующего потока будет , где — число рёбер, насыщенных этим блокирующим потоком, то весь алгоритм поиска блокирующего потока отработает за , что, учитывая, что все указатели в сумме прошли расстояние , дает асимптотику . В худшем случае, когда блокирующий поток насыщает все ребра, асимптотика получается .
, где - число продвижения указателей. Учитывая, что всего запусков обхода в глубину в рамках поиска одногоЗамечание Если в алгоритме Диница искать блокирующий поток удаляющим обходом, то его эффективность составит , что уже лучше эффективности алгоритма Эдмондса-Карпа .
Алгоритм узкого места
Идея
Для каждой вершины вводится потенциал потока, равный максимальному дополнительному потоку, который может пройти через эту вершину. Далее следует цикл. На каждой его итерации определяется вершина
с минимальным потенциалом . Затем пускается поток величины из истока в сток, проходящий через эту вершину. При этом если остаточная пропускная способность ребра равна нулю, то это ребро удаляется. Также, удаляются все вершины, у которых не остаётся ни одного входящего и/или ни одного выходящего ребра. При удалении вершины все смежные ребра удаляются.Подробное описание
Для каждой вершины вычислим входящий и исходящий потенциал вершин — сумму пропускных способностей дуг сети Диница, входящих и исходящих из вершины соответственно. Входящий потенциал истока и исходящий потенциал стока положим равными бесконечности. Определим потенциал или пропускную способность вершины в сети как минимум из ее входящего и исходящего потенциалов. Таким образом, потенциал вершины определяет максимально возможное количество потока, который может через нее проходить. Ясно, что через вершины с нулевым потенциалом поток проходить не может. Следовательно, их можно удалить из вспомогательной сети. Удалим эти вершины и дуги, им инцидентные, обновив должным образом потенциалы вершин, смежных с удаленными. Если в результате появятся новые вершины с нулевым потенциалом, удалим рекурсивно и их. В результате во вспомогательной сети останутся только вершины с ненулевым потенциалом.
После этого приступим к построению блокирующего потока. Пусть вершина
принадлежит -ому слою. Протолкнем единиц потока из вершины с минимальным потенциалом в смежные с ней вершины по исходящим дугам с ненулевой остаточной пропускной способностью. Попутно будем переносить проталкиваемый поток в исходную сеть, а также корректировать потенциалы вершин, отправляющих и принимающих избыток потока. В результате, весь (в виду минимальности потенциала вершины ) проталкиваемый поток соберется в вершинах -го слоя. Повторим процесс отправки потока из вершин -го слоя, содержащих избыток потока, в смежные им вершины -го слоя. И так до тех пор, пока весь поток не соберется в последнем слое. Заметим, что в этом слое содержится только сток, ибо все остальные вершины, ранее ему принадлежащие, были удалены из сети Диница, как вершины, имеющие нулевой потенциал. Следовательно, весь поток величины , отправленный из вершины с минимальным потенциалом полностью соберется в стоке. На втором этапе вновь, начиная с вершины , осуществляется подвод потока уже по входящим дугам. В результате на первом шаге недостаток потока переадресуется к узлам -го слоя, затем -го. И так до тех пор, пока весь потока величины , отправленные из вершины с минимальным потенциалом, не соберется в истоке. Таким образом, поток и во вспомогательной и в основной сети увеличится на величину .
= 0; Вычисляем остаточную сеть ; Найдём вспомогательный граф для ; ( достижима из в ) найдём с миниальной пропускной способностью ; проталкиваем единиц потока из в ; проталкиваем единиц потока из в ; изменяем , и ; вычисляем новый вспомогательный граф из ;
Асимптотика
Если информация о входящих и исходящих дугах будет храниться в виде связных списков, то для того, чтобы пропустить поток, на каждой итерации будет выполнено
действий, где соответствует числу рёбер, для которых остаточная пропускная способность уменьшилась, но осталась положительной, а — числу удалённых ребер. Таким образом, для поиска блокирующего потока будет выполнено действий.Замечание Алгоритм Малхотры — Кумара — Махешвари для поиска блокирующего потока использует алгоритм узкого места.
Волновой алгоритм
Используя предпотоки, позволяет найти блокирующий поток за
. Модификация алгоритма Диница, основанная на этом алгоритме, называется алгоритмом Карзанова.