Алгоритм "поднять-в-начало" — различия между версиями
Whiplash (обсуждение | вклад) м (→Операция разгрузки (discharge)) |
Whiplash (обсуждение | вклад) (→Допустимые ребра) |
||
| Строка 26: | Строка 26: | ||
Так как каждая вершина циклического пути <tex>p</tex> встречается при суммировании по одному разу это значит то, что <tex>k = 0</tex>, что противоречит первоначальному предположению. Значит, допустимая сеть является ациклической. | Так как каждая вершина циклического пути <tex>p</tex> встречается при суммировании по одному разу это значит то, что <tex>k = 0</tex>, что противоречит первоначальному предположению. Значит, допустимая сеть является ациклической. | ||
| + | }} | ||
| + | |||
| + | |||
| + | {{Лемма | ||
| + | |id = Лемма2 | ||
| + | |about = Об изменении допустимой цепи, с помощью операции проталкивания. | ||
| + | |statement = | ||
| + | Если <tex>G = (V, E)</tex> {{---}} сеть с истоком <tex>s</tex> и стоком <tex>t</tex>, <tex>f</tex> {{---}} предпоток в <tex>G</tex>, а <tex>h</tex> {{---}} функция высоты. Если вершина <tex>u</tex> переполнена и ребро <tex>(u, v)</tex> допустимое, то применяемая операция <tex>push(u, v)</tex> не создает новые допустимые ребра, но может привести к тому, что ребро <tex>(u, v)</tex> станет недопустимым. | ||
| + | |proof = | ||
| + | Так как ребро <tex>(u, v)</tex> допустимое то, по определению допустимого ребра, из <tex>u</tex> в <tex>v</tex> можно протолкнуть поток. Из-за того что <tex>u</tex> {{---}} переполнена, вызываем операцию <tex>push(u, v)</tex>. В результате выполнения операции может быть создано остаточное ребро <tex>(u, v)</tex>. Так ребро <tex>(u, v)</tex> допустимое то, <tex>h[v] = h[u] - 1</tex>, а это значит, что ребро <tex>(v, u)</tex> не может стать допустимым. | ||
| + | |||
| + | Если выполненная операция <tex>push(u, v)</tex> является насыщающим проталкиванием, то после ее выполнения <tex>c_{f}(u, v) = 0</tex> и ребро <tex>(u, v)</tex> становится недопустимым. | ||
}} | }} | ||
Версия 03:24, 27 декабря 2012
Алгоритм "поднять-в-начало" (relabel-to-front) основан на методе проталкивание предпотока, но из-за тщательного выбора порядка выполнения операций проталкивания и подъема, время выполнения данного алгоритма составляет , что асимптотически не хуже, чем .
Содержание
Допустимые ребра
— сеть с истоком и стоком , — предпоток в , — функция высоты.
| Определение: |
| Допустимое ребро (admissible edge) — ребро , у которого и . В противном случае называется недопустимым (inadmissible). |
| Определение: |
| Допустимая сеть (admissible network) — сеть , где — множество допустимых ребер. |
| Лемма (Допустимая сеть является ациклической): |
Если — сеть с истоком и стоком , — предпоток в , а — функция высоты, тогда допустимая сеть является ациклической. |
| Доказательство: |
|
Пусть в существует циклический путь , где . для , так как каждое ребро данного пути допустимое. Просуммировав равенства вдоль циклического пути, получаем: Так как каждая вершина циклического пути встречается при суммировании по одному разу это значит то, что , что противоречит первоначальному предположению. Значит, допустимая сеть является ациклической. |
| Лемма (Об изменении допустимой цепи, с помощью операции проталкивания.): |
Если — сеть с истоком и стоком , — предпоток в , а — функция высоты. Если вершина переполнена и ребро допустимое, то применяемая операция не создает новые допустимые ребра, но может привести к тому, что ребро станет недопустимым. |
| Доказательство: |
|
Так как ребро допустимое то, по определению допустимого ребра, из в можно протолкнуть поток. Из-за того что — переполнена, вызываем операцию . В результате выполнения операции может быть создано остаточное ребро . Так ребро допустимое то, , а это значит, что ребро не может стать допустимым. Если выполненная операция является насыщающим проталкиванием, то после ее выполнения и ребро становится недопустимым. |
Идея
Операция разгрузки (discharge)
Разгрузка (discharge) — операция, которая применяется к переполненной вершине , для того чтобы протолкнуть поток через допустимые ребра в смежные вершины, при необходимости поднимая , делая недопустимые ребра, выходящие из вершины , допустимыми.
Будем хранить для каждой вершины список (список вершин смежных с ней). То есть список содержит каждую вершину такую, что в сети или .
На первую вершину в списке указывает указатель . Для перехода к следующей вершине в списке за , поддерживается указатель . Он равен , если — последняя вершина в списке.
Для каждой вершины указатель — указатель на текущую вершину списка. Изначально .
discharge(u)
while e[u] > 0
v = current[u]
if v = null
relabel(u)
current[u] = head[N[u]]
else
if c(u, v) > 0 and h[u] = h[v] + 1
push(u, v)
else
current[u] = next[v]
Докажем то, что когда операция discharge вызывает операции push и relable, эти операции применимы.
| Лемма: |
Когда операция вызывает в операцию , то для пары вершин применима операция проталкивания. |
| Доказательство: |
| Проверки операции , сделанные до вызова операции проталкивания, гарантируют то, что операция будет вызвана только тогда, когда она применима. То есть , и . |
| Лемма: |
Когда операция вызывает в операцию , то для вершины применим подъем. |
Схема алгоритма
Анализ
Источники
- Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2011. — С. 774—785.
- Алгоритм проталкивания предпотока — Википедия