Изменения

Перейти к: навигация, поиск

Схема алгоритма Диница

377 байт добавлено, 18:59, 28 февраля 2019
Определение слоистой сети
== Определение слоистой сети ==
Для начала определим для каждой вершины <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> путь в слоистой сети является кратчайшим путём в исходной, из свойств обхода в ширину.
[[Файл:Слоистая_сеть.png|500px |thumb|center| Слоистая сеть с пятью слоями. <tex>s = 0, t = 6</tex>]]<br/> В примере ребрарёбра, обозначенные пунктиром, не входят в слоистую сеть. Слоистую сеть для графа <br/tex>G<br/tex>Слоистую сеть для графа G будем называть '''вспомогательной сетью'''.
== Алгоритм ==
#Для каждого ребра <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>f'</tex> в <tex>G_L</tex>]].#Дополним поток <tex>f</tex> найденным потоком <tex>f'</tex> и перейдем перейдём к шагу 2.
=== Корректность алгоритма ===
Расстояние между истоком и стоком строго увеличивается после каждой фазы алгоритма, т.е. <tex>d'[t] > d[t]</tex>, где <tex>d'[t]</tex> — значение, полученное на следующей фазе алгоритма.
|proof=
Проведём доказательство от противного. Пусть длина кратчайшего пути из истока в сток останется неизменной после очередной фазы алгоритма. Вспомогательная сеть строится по остаточной. Из предположения следует, что в остаточной сети будет будут содержаться только рёбра остаточной сети перед выполнением данной фазы, либо обратные к ним. Из этого получаем, что нашёлся <tex>s \leadsto t</tex> путь, который не содержит насыщенных рёбер и имеет ту же длину, что и кратчайший путь. Но этот путь должен был быть «заблокирован» блокирующим потоком, чего не произошло. Получили противоречие. Значит длина изменилась.
}}
Поскольку длина кратчайшего <tex>s \leadsto t</tex> пути не может превосходить <tex>n - 1</tex>, то, следовательно, алгоритм Диница совершает не более <tex>n - 1</tex> фазы.
<tex>f[u][v]</tex> {{---}} поток через ребро <tex>(uv)</tex>.
 
<tex>p[u]</tex> {{---}} [[Алгоритм_поиска_блокирующего_потока_в_ациклической_сети#.D0.A3.D0.B4.D0.B0.D0.BB.D1.8F.D1.8E.D1.89.D0.B8.D0.B9_.D0.BE.D0.B1.D1.85.D0.BE.D0.B4 | номер первого неудалённого ребра, идущего из u]]
'''bool''' bfs():
заполняем массив d значениями, равными -1<tex>\infty</tex> d[s] = 0
Q.push(s)
'''while''' !Q.isEmpty
u = Q.pop()
'''for''' <tex>(uv) \in E(G)</tex>
'''if''' f[u][v] < c[u][v] '''and ''' d[v] != -1= <tex>\infty</tex>
d[v] = d[u] + 1
Q.push(v)
'''return''' d[t] != -1<tex>\infty</tex>
<font color="darkgreen">//поиск блокирующего потока //v u {{--- }} номер вершины //cf minC {{-- -}} минимальная пропускная способность дополняющей сети на пройденном dfs пути</font> '''int''' dfs(u, cfminC): '''if''' u == t '''or''' cf minC == 0 '''return''' cf <font color="darkgreen">//p[u] - номер вершины на которой завершился обход для вершины u</font>minC
'''for''' v = p[u] '''to''' <tex>|V(G)| - 1</tex>
'''if''' d[v] == d[u] + 1 <font color="darkgreen">//это условие эквивалентно поиску во вспомогательной слоистой сети</font> cfmin delta = dfs(v, min(cfminC, c[u][v] - f[u][v])) '''if''' delta != 0 f[u][v] += cfmindelta <font color="darkgreen">// насыщаем рёбра по пути dfs</font> f[v][u] -= cfmindelta '''return''' cfmindelta
p[u]++
'''return''' 0
'''int''' findMaxFlow():
maxFlow = 0
'''while''' bfs() <font color="darkgreen">//пересчитываем d[i], заодно проверяем достижима ли t из s</font>
заполняем p нулями
flow = dfs(s, <tex>\infty</tex>)
flow = dfs(s, <tex>\infty</tex>)
'''return''' maxFlow
 
== Источники ==
*[http://wwwru.e-maxxwikipedia.ruorg/algowiki/dinic Алгоритм_Диница Википедия {{---}} Алгоритм Диница на e-maxx.ru]*[http://ruwww.wikipediae-maxx.orgru/wikialgo/Алгоритм_Диница dinic MAXimal::algo::Алгоритм Диница на ru.wikipedia.org]
*Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — С. 1296. — ISBN 5-8489-0857-4
[[Категория: Алгоритмы и структуры данных]]
[[Категория: Задача о максимальном потоке ]]
442
правки

Навигация