Алгоритм масштабирования потока — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Суть)
Строка 3: Строка 3:
 
== Суть ==
 
== Суть ==
  
Этот алгоритм работает в предположении, что все пропускные способности ребер целые. Пусть у нас есть граф <tex>G</tex>, <tex>\forall (u,v)\in E: u_{(u,v)}\in\mathbb N</tex>. Пусть <tex>U</tex> - максимальная пропускная способность. Тогда запишем пропускную способность каждого ребра в двоичной записи, выделив для каждого ребра <tex>n:=\lfloor\log U\rfloor+1</tex> памяти. Занумеруем биты с младшего (0-ой) по старший (n-ный). Тогда <br>
+
Этот алгоритм работает в предположении, что все пропускные способности ребер целые. Пусть есть граф <tex>G</tex>, <tex>\forall (u,v)\in E\colon u_{(u,v)}\in\mathbb N</tex>. Пусть <tex>U</tex> - максимальная пропускная способность. Введем параметр <tex>\Delta</tex>. Это большое число, к примеру, равное <tex>U</tex>. На каждом шаге будем искать в остаточном графе увеличивающие пути с пропускной способностью не меньше <tex>\Delta</tex> и увеличивать поток вдоль этих путей. В конце шага будем уменьшать <tex>\Delta</tex> в два раза, и на следующем шаге будем искать увеличивающий путь с новым <tex>\Delta</tex>. При <tex>\Delta == 1</tex> алгоритм масштабирования идентичен алгоритму Эдмондса - Карпа, поэтому алгоритм масштабирования корректен.
 
 
<tex>\forall (u,v)\in E:c(u,v)=2^n*a_n(u,v)+...+2*a_1(u,v)+a_0(u,v); a_i(u,v)\in\{0,1\}</tex>
 
 
 
Будем решать задачу методом Форда-Фалкерсона сначала для графа с урезанными пропускными способностями <tex>c_0(u,v):=a_n(u,v)</tex>. Решив ее и получив поток <tex>f_0</tex>, добавим следующий бит и вычтем грубое приближение. То есть <tex>\forall (u,v)\in E:c_1(u,v):=2*a_n(u,v)+a_{n-1}(u,v)-2*f_0(u,v)</tex>. Далее наше приближение становится точнее и точнее, пока не станет решением для исходной задачи.
 
  
 
== Оценка сложности ==
 
== Оценка сложности ==
 +
На каждом шаге алгорит выполняет <tex>O(E)</tex> увеличений потока в худшем случае (т.к. минимальный разрез на каждом шаге меньше, чем <tex>2E\Delta</tex>). Дополняющий путь можно найти за <tex>O(E)</tex> используя BFS. Количество шагов <tex>O(log_2U)</tex>. Итоговая сложность <tex>O(E^2log_2U)</tex>.
  
Сложность этого алгоритма <tex>O(E^2\log U)</tex>, где <tex>\log U</tex> - количество итераций. Докажем, что сложность каждой итерации <tex>O(E^2)</tex>.
+
== Псевдокод ==
 
+
'''Capacity-Scaling'''
На первой итерации мы имеем только ребра веса 1. Это значит, что <tex>|f|\le V</tex>. Значит количество итераций (дополняющих путей) не превосходит <tex>V</tex>, поиск доп. пути занимает <tex>O(E)</tex>. Получаем сложность <tex>O(VE)\le O(E^2)</tex>.
+
    <tex>f\leftarrow 0</tex>
 
+
    <tex>\Delta\leftarrow 2^{\lfloor\log_2U\rfloor}</tex>
Теперь рассмотрим переход ко второй итерации. Граф <tex>G_{f_0}</tex> несвязен. Рассмотрим разрез <tex>(S,T)</tex>, где <tex>S</tex> и <tex>T</tex> - компоненты связности. <tex>(c_0)_{f_0}(S,T)=0</tex>. Значит в новом графе с пропускными способностями <tex>c_1</tex>: <tex>\forall u\in S, v\in T:c_1(u,v)\le1</tex>. Так как <tex>(S,T)</tex> - разрез, то <tex>|f'_1|=f'_1(S,T)\le c(S,T)\le E</tex>. Здесь <tex>f'_1</tex> - максимальный поток в <tex>G_1</tex> с пропускными способностями <tex>c_1</tex>, а <tex>f_1=f_0+f'_1</tex>. Так как пропускная способность каждого дополняющего пути не меньше 1, мы получили оценку на количество итераций. Дополняющий путь же мы можем найти за <tex>O(E)</tex>.
+
    '''while''' <tex>\Delta>0</tex>
 +
        '''while''' в <tex>G_f</tex> существует <tex>s-t</tex> путь
 +
            найти путь <tex>P</tex>
 +
            <tex>\delta\leftarrow\min{r_{ij}\colon(i,j)\in P}</tex>
 +
            увеличить поток по ребрам <tex>P</tex> на <tex>\delta</tex>
 +
            обновить <tex>G_f</tex>
 +
    <tex>\Delta\leftarrow\Delta/2</tex>
 +
'''return''' f

Версия 22:51, 14 января 2011

Алгоритм масштабирования потока - алгоритм поиска максимального потока путем регулирования пропускной способности ребер.

Суть

Этот алгоритм работает в предположении, что все пропускные способности ребер целые. Пусть есть граф [math]G[/math], [math]\forall (u,v)\in E\colon u_{(u,v)}\in\mathbb N[/math]. Пусть [math]U[/math] - максимальная пропускная способность. Введем параметр [math]\Delta[/math]. Это большое число, к примеру, равное [math]U[/math]. На каждом шаге будем искать в остаточном графе увеличивающие пути с пропускной способностью не меньше [math]\Delta[/math] и увеличивать поток вдоль этих путей. В конце шага будем уменьшать [math]\Delta[/math] в два раза, и на следующем шаге будем искать увеличивающий путь с новым [math]\Delta[/math]. При [math]\Delta == 1[/math] алгоритм масштабирования идентичен алгоритму Эдмондса - Карпа, поэтому алгоритм масштабирования корректен.

Оценка сложности

На каждом шаге алгорит выполняет [math]O(E)[/math] увеличений потока в худшем случае (т.к. минимальный разрез на каждом шаге меньше, чем [math]2E\Delta[/math]). Дополняющий путь можно найти за [math]O(E)[/math] используя BFS. Количество шагов [math]O(log_2U)[/math]. Итоговая сложность [math]O(E^2log_2U)[/math].

Псевдокод

Capacity-Scaling
    [math]f\leftarrow 0[/math]
    [math]\Delta\leftarrow 2^{\lfloor\log_2U\rfloor}[/math]
    while [math]\Delta\gt 0[/math]
        while в [math]G_f[/math] существует [math]s-t[/math] путь
           найти путь [math]P[/math]
           [math]\delta\leftarrow\min{r_{ij}\colon(i,j)\in P}[/math]
           увеличить поток по ребрам [math]P[/math] на [math]\delta[/math]
           обновить [math]G_f[/math]
    [math]\Delta\leftarrow\Delta/2[/math]
return f