Алгоритм масштабирования потока — различия между версиями
(→Псевдокод) |
|||
Строка 2: | Строка 2: | ||
Этот алгоритм работает в предположении, что все пропускные способности рёбер целые. | Этот алгоритм работает в предположении, что все пропускные способности рёбер целые. | ||
− | == | + | == Идея == |
− | + | Суть алгоритма в нахождении сперва путей с высокой пропускной способностью, чтобы сразу сильно увеличивать поток по этим путям, а затем по всем остальным. Пусть <tex>U</tex> - максимальная пропускная способность. Введём параметр <tex>\Delta = 2^{\lfloor\log_2U\rfloor}</tex>. На каждом шаге будем искать в остаточном графе увеличивающие пути с пропускной способностью не меньше, чем <tex>\Delta</tex>, и увеличивать поток вдоль этих путей. В конце шага будем уменьшать <tex>\Delta</tex> в два раза, и на следующем шаге будем искать увеличивающий путь с новым значением параметра. При значении <tex>\Delta</tex>, равном единице, данный алгоритм становится идентичен [[Алоритм_Эдмондса-Карпа | алгоритму Эдмондса — Карпа]]. Из этого следует, что алгоритм корректен. | |
+ | |||
+ | Пусть <tex> G </tex> — граф, <tex> \forall(u, v) \in EG \colon c(u,v) \in \mathbb{Z_+}, U = \max\limits_{(u, v) \in EG} c(u, v) </tex> — максимальная пропускная способность. Запишем пропускную способность каждого ребра в двоичном виде. Тогда каждое число будет занимать <tex> \lceil \log_2 U \rceil = n </tex> бит. | ||
+ | |||
+ | <tex> c(u, v) = \sum\limits_{i = 0}^{n - 1} a_i(u, v) 2^n, a_i(u, v) \in {0, 1} </tex> | ||
== Оценка сложности == | == Оценка сложности == | ||
Строка 11: | Строка 15: | ||
== Псевдокод == | == Псевдокод == | ||
'''Capacity-Scaling''' | '''Capacity-Scaling''' | ||
− | <tex>f\leftarrow 0</tex> | + | <tex> f \leftarrow 0 </tex> |
− | <tex>\Delta\leftarrow 2^{\lfloor\ | + | <tex> \Delta \leftarrow 2^{\lfloor \log_2 U \rfloor}</tex> |
− | '''while''' <tex>\Delta>0</tex> | + | '''while''' <tex> \Delta >0</tex> |
'''do''' '''while''' в <tex>G_f</tex> существует <tex>s-t</tex> путь с пропускной способностью большей <tex>\Delta</tex> | '''do''' '''while''' в <tex>G_f</tex> существует <tex>s-t</tex> путь с пропускной способностью большей <tex>\Delta</tex> | ||
'''do''' <tex>P\leftarrow</tex> путь с пропускной способностью большей <tex>\Delta</tex> | '''do''' <tex>P\leftarrow</tex> путь с пропускной способностью большей <tex>\Delta</tex> |
Версия 22:09, 18 декабря 2011
Алгоритм масштабирования потока — алгоритм поиска максимального потока путём регулирования пропускной способности рёбер. Этот алгоритм работает в предположении, что все пропускные способности рёбер целые.
Содержание
Идея
Суть алгоритма в нахождении сперва путей с высокой пропускной способностью, чтобы сразу сильно увеличивать поток по этим путям, а затем по всем остальным. Пусть алгоритму Эдмондса — Карпа. Из этого следует, что алгоритм корректен.
- максимальная пропускная способность. Введём параметр . На каждом шаге будем искать в остаточном графе увеличивающие пути с пропускной способностью не меньше, чем , и увеличивать поток вдоль этих путей. В конце шага будем уменьшать в два раза, и на следующем шаге будем искать увеличивающий путь с новым значением параметра. При значении , равном единице, данный алгоритм становится идентиченПусть
— граф, — максимальная пропускная способность. Запишем пропускную способность каждого ребра в двоичном виде. Тогда каждое число будет занимать бит.
Оценка сложности
На каждом шаге алгоритм выполняет в худшем случае BFS. Количество шагов . Итоговая сложность .
увеличений потока. Докажем это. Пусть . В конце шага множество вершин графа можно разбить на две части: и . Все рёбра, выходящие из , имеют остаточную пропускную способность менее . Наибольшее количество рёбер между и равно . Следовательно, остаточный поток (поток, который может быть получен на оставшихся шагах) на фазе с текущим значением максимально составляет . Каждый увеличивающий путь при данном имеет пропускную способность как минимум . На предыдущем шаге, с масштабом , остаточный поток ограничен . Значит максимальное число появившихся увеличивающих путей равно . Увеличивающий путь можно найти за , используяПсевдокод
Capacity-Scalingwhile do while в существует путь с пропускной способностью большей do путь с пропускной способностью большей увеличить поток по рёбрам на обновить