Схема алгоритма Диница — различия между версиями
(→Определение слоистой сети) |
(→Схема алгоритма) |
||
Строка 13: | Строка 13: | ||
#Для каждого ребра <tex>(u,v)</tex> данной сети <tex>G</tex> зададим <tex>f(u,v) = 0</tex>. | #Для каждого ребра <tex>(u,v)</tex> данной сети <tex>G</tex> зададим <tex>f(u,v) = 0</tex>. | ||
#Построим вспомогательную сеть <tex>G_L</tex> из дополняющей сети <tex>G_f</tex> данного графа <tex>G</tex>. Если <tex>d[t] = \infty</tex>, остановиться и вывести <tex>f</tex>. | #Построим вспомогательную сеть <tex>G_L</tex> из дополняющей сети <tex>G_f</tex> данного графа <tex>G</tex>. Если <tex>d[t] = \infty</tex>, остановиться и вывести <tex>f</tex>. | ||
− | #Найдем блокирующий поток <tex>f'</tex> в <tex>G_L</tex>. | + | #[[Алгоритм поиска блокирующего потока в ациклической сети|Найдем блокирующий поток <tex>f'</tex> в <tex>G_L</tex>.]]. |
#Дополним поток <tex>f</tex> найденным потоком <tex>f'</tex> и перейдем к шагу 2. | #Дополним поток <tex>f</tex> найденным потоком <tex>f'</tex> и перейдем к шагу 2. | ||
Версия 02:16, 6 января 2012
Содержание
Определение слоистой сети
- Дополняющая сеть, дополняющий путь
- Блокирующий поток
- Вспомогательная (слоистая) сеть.
- Для начала определим для каждой вершины обходом в ширину).
В слоистую сеть включаем только те ребра исходной сети, для которых .
данной сети длину кратчайшего пути из истока и обозначим ее (для этого можно воспользоваться - Полученная сеть ациклична, и любой путь во вспомогательной сети является кратчайшим путём в исходной, из свойств обхода в ширину.
- Для начала определим для каждой вершины обходом в ширину).
В примере ребра, обозначенные пунктиром, не входят в слоистую сеть.
Алгоритм
Пусть дана сеть. Требуется найти в этой сети поток из в максимальной величины.
Схема алгоритма
- Для каждого ребра данной сети зададим .
- Построим вспомогательную сеть из дополняющей сети данного графа . Если , остановиться и вывести .
- Найдем блокирующий поток . в .
- Дополним поток найденным потоком и перейдем к шагу 2.
Корректность алгоритма
Покажем, что если алгоритм завершается, то на выходе у него получается поток именно максимальной величины.
В самом деле, предположим, что в какой-то момент во вспомогательной сети, построенной для остаточной сети, не удалось найти блокирующий поток. Это означает, что сток вообще не достижим во вспомогательной сети из истока. Но поскольку она содержит в себе все кратчайшие пути из истока в остаточной сети, это в свою очередь означает, что в остаточной сети нет пути из истока в сток. Следовательно, применяя теорему Форда-Фалкерсона, получаем, что текущий поток в самом деле максимален.
Асимптотика алгоритма
Утверждение: |
Расстояние между истоком и стоком строго увеличивается после каждой фазы алгоритма, т.е. , где — значение, полученное на следующей фазе алгоритма. |
От противного. Рассмотрим кратчайший путь из истока в сток; по предположению, его длина должна сохраниться неизменной. Однако остаточная сеть на следующей фазе содержит только рёбра остаточной сети перед выполнением текущей фазы, либо обратные к ним. Таким образом, пришли к противоречию: нашёлся | путь, который не содержит насыщенных рёбер и имеет ту же длину, что и кратчайший путь. Этот путь должен был быть «заблокирован» блокирующим потоком, чего не произошло, в чём и заключается противоречие, что и требовалось доказать.
Поскольку длина кратчайшего
пути не может превосходить , то, следовательно, алгоритм Диница совершает не более фазы. Таким образом, в зависимости от того, каким алгоритмом нахождения блокирующего потока мы пользовались, весь алгоритм Диница может выполняться за или за . Также возможно достичь асимптотики , если использовать динамические деревья Слетора и Тарьяна.Реализация
bfs()while for ( : ( ) ( ))
makeGl()0 bfs() if ( достижима) return true return false
algorithmDinica()0 while makeGL() findBlockingFlow() вывести поток