Схема алгоритма Диница — различия между версиями
Dimitrova (обсуждение | вклад) |
|||
Строка 1: | Строка 1: | ||
== Определение слоистой сети == | == Определение слоистой сети == | ||
− | [[Файл:Слоистая_сеть.png| | + | [[Файл:Слоистая_сеть.png|300px |thumb|cental| Слоистая сеть с пятью слоямию. s = 0, t = 6]] |
Для начала определим для каждой вершины <tex>v</tex> данной сети <tex>G</tex> длину кратчайшего <tex>s \leadsto v</tex> пути из истока и обозначим ее <tex>d[v]</tex> (для этого можно воспользоваться [[Обход в ширину|обходом в ширину]]).<br/> В слоистую сеть включаем только те ребра <tex>(u,v)</tex> исходной сети, для которых <tex>d[u] + 1 = d[v]</tex>. | Для начала определим для каждой вершины <tex>v</tex> данной сети <tex>G</tex> длину кратчайшего <tex>s \leadsto v</tex> пути из истока и обозначим ее <tex>d[v]</tex> (для этого можно воспользоваться [[Обход в ширину|обходом в ширину]]).<br/> В слоистую сеть включаем только те ребра <tex>(u,v)</tex> исходной сети, для которых <tex>d[u] + 1 = d[v]</tex>. | ||
Полученная сеть ациклична, и любой <tex>s \leadsto t</tex> путь во вспомогательной сети является кратчайшим путём в исходной, из свойств обхода в ширину. | Полученная сеть ациклична, и любой <tex>s \leadsto t</tex> путь во вспомогательной сети является кратчайшим путём в исходной, из свойств обхода в ширину. | ||
Строка 28: | Строка 28: | ||
Таким образом, в зависимости от того, каким алгоритмом нахождения блокирующего потока мы пользовались, весь алгоритм Диница может выполняться за <tex>O(VE^2)</tex> или за <tex>O(V^2E)</tex>. Также возможно достичь асимптотики <tex>O(VE\log V)</tex>, если использовать динамические деревья Слетора и Тарьяна. | Таким образом, в зависимости от того, каким алгоритмом нахождения блокирующего потока мы пользовались, весь алгоритм Диница может выполняться за <tex>O(VE^2)</tex> или за <tex>O(V^2E)</tex>. Также возможно достичь асимптотики <tex>O(VE\log V)</tex>, если использовать динамические деревья Слетора и Тарьяна. | ||
==Реализация== | ==Реализация== | ||
− | bfs() | + | <tex>bfs()</tex> |
<tex>q \leftarrow empty </tex> | <tex>q \leftarrow empty </tex> | ||
<tex> q.push(s) </tex> | <tex> q.push(s) </tex> | ||
− | + | <tex>while !q.isEmty()</tex> | |
− | + | <tex>for (v : (flow(u,v) > 0) and (dist[v] = 0))</tex> | |
<tex>dist[v] \leftarrow dist[u] + 1 </tex> | <tex>dist[v] \leftarrow dist[u] + 1 </tex> | ||
<tex>q.push(v)</tex> | <tex>q.push(v)</tex> | ||
<tex>q.pop()</tex> | <tex>q.pop()</tex> | ||
− | makeGl() | + | <tex>makeGl()</tex> |
<tex>dist \leftarrow </tex>0 | <tex>dist \leftarrow </tex>0 | ||
− | bfs() | + | <tex>bfs()</tex> |
− | + | <tex>if (t</tex> достижима<tex>)</tex> | |
− | return true | + | <tex>return true</tex> |
− | return false | + | <tex>return false</tex> |
− | algorithmDinica() | + | <tex>algorithmDinica()</tex> |
<tex>flow \leftarrow</tex> 0 | <tex>flow \leftarrow</tex> 0 | ||
− | while makeGL() | + | <tex>while makeGL()</tex> |
− | <tex> f' \leftarrow</tex> | + | <tex> f' \leftarrow findBlockingFlow()</tex> |
<tex> f \leftarrow f' </tex> | <tex> f \leftarrow f' </tex> | ||
вывести поток <tex> f </tex> | вывести поток <tex> f </tex> |
Версия 02:02, 17 января 2012
Содержание
Определение слоистой сети
Для начала определим для каждой вершины обходом в ширину).
В слоистую сеть включаем только те ребра исходной сети, для которых .
Полученная сеть ациклична, и любой путь во вспомогательной сети является кратчайшим путём в исходной, из свойств обхода в ширину.
В примере ребра, обозначенные пунктиром, не входят в слоистую сеть.
Алгоритм
Пусть дана сеть. Требуется найти в этой сети поток из в максимальной величины.
Схема алгоритма
- Для каждого ребра данной сети зададим .
- Построим вспомогательную сеть дополняющей сети данного графа . Если , остановиться и вывести . из
- Найдем блокирующий поток . в .
- Дополним поток найденным потоком и перейдем к шагу 2.
Корректность алгоритма
Покажем, что если алгоритм завершается, то на выходе у него получается поток именно максимальной величины.
В самом деле, предположим, что в какой-то момент во вспомогательной сети, построенной для остаточной сети, не удалось найти блокирующий поток. Это означает, что сток вообще не достижим во вспомогательной сети из истока. Но поскольку она содержит в себе все кратчайшие пути из истока в остаточной сети, это в свою очередь означает, что в остаточной сети нет пути из истока в сток. Следовательно, применяя теорему Форда-Фалкерсона, получаем, что текущий поток в самом деле максимален.
Асимптотика алгоритма
Утверждение: |
Расстояние между истоком и стоком строго увеличивается после каждой фазы алгоритма, т.е. , где — значение, полученное на следующей фазе алгоритма. |
От противного. Рассмотрим кратчайший путь из истока в сток; по предположению, его длина должна сохраниться неизменной. Однако остаточная сеть на следующей фазе содержит только рёбра остаточной сети перед выполнением текущей фазы, либо обратные к ним. Таким образом, пришли к противоречию: нашёлся | путь, который не содержит насыщенных рёбер и имеет ту же длину, что и кратчайший путь. Этот путь должен был быть «заблокирован» блокирующим потоком, чего не произошло, в чём и заключается противоречие, что и требовалось доказать.
Поскольку длина кратчайшего
пути не может превосходить , то, следовательно, алгоритм Диница совершает не более фазы. Таким образом, в зависимости от того, каким алгоритмом нахождения блокирующего потока мы пользовались, весь алгоритм Диница может выполняться за или за . Также возможно достичь асимптотики , если использовать динамические деревья Слетора и Тарьяна.Реализация
0 достижима
0 вывести поток
Источники
- Алгоритм Диница на e-maxx.ru
- Алгоритм Диница на ru.wikipedia.org
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — С. 1296. — ISBN 5-8489-0857-4