Алгоритм "поднять-в-начало" — различия между версиями
Whiplash (обсуждение | вклад) м |
Whiplash (обсуждение | вклад) (→Допустимые ребра) |
||
Строка 2: | Строка 2: | ||
== Допустимые ребра == | == Допустимые ребра == | ||
− | <tex>G = (V, E)</tex> - [[Определение сети, потока#Определение сети|сеть]] с истоком <tex>s</tex> и стоком <tex>t</tex>, <tex>f</tex> - [[Метод проталкивания предпотока#Определения|предпоток]] в <tex>G</tex>, <tex>h</tex> - [[Метод проталкивания предпотока#Определения|функция высоты]]. | + | <tex>G = (V, E)</tex> {{---}} [[Определение сети, потока#Определение сети|сеть]] с истоком <tex>s</tex> и стоком <tex>t</tex>, <tex>f</tex> {{---}} [[Метод проталкивания предпотока#Определения|предпоток]] в <tex>G</tex>, <tex>h</tex> {{---}} [[Метод проталкивания предпотока#Определения|функция высоты]]. |
{{Определение | {{Определение | ||
|definition= | |definition= | ||
− | '''Допустимое ребро (admissible edge)''' - ребро <tex>uv</tex>, у которого <tex>c_{f}(u, v) > 0</tex> и <tex>h(u) = h(v) + 1</tex>. В противном случае <tex>uv</tex> называется '''недопустимым (inadmissible)'''. | + | '''Допустимое ребро (admissible edge)''' {{---}} ребро <tex>uv</tex>, у которого <tex>c_{f}(u, v) > 0</tex> и <tex>h(u) = h(v) + 1</tex>. В противном случае <tex>uv</tex> называется '''недопустимым (inadmissible)'''. |
}} | }} | ||
{{Определение | {{Определение | ||
|definition= | |definition= | ||
− | '''Допустимая сеть (admissible network)''' - сеть <tex>G_{f, h} = (V, E_{f, h})</tex>, где <tex>E_{f, h}</tex> - множество допустимых ребер. | + | '''Допустимая сеть (admissible network)''' {{---}} сеть <tex>G_{f, h} = (V, E_{f, h})</tex>, где <tex>E_{f, h}</tex> {{---}} множество допустимых ребер. |
+ | }} | ||
+ | |||
+ | {{Лемма | ||
+ | |id = Лемма1 | ||
+ | |about = Допустимая сеть является ациклической | ||
+ | |statement = | ||
+ | Если <tex>G = (V, E)</tex> {{---}} сеть с истоком <tex>s</tex> и стоком <tex>t</tex>, <tex>f</tex> {{---}} предпоток в <tex>G</tex>, а <tex>h</tex> {{---}} функция высоты, тогда допустимая сеть <tex>G_{f, h} = (V, E_{f, h})</tex> является ациклической. | ||
+ | |proof = | ||
+ | Пусть в <tex>G_{f, h}</tex> существует [[Основные определения теории графов|циклический путь]] <tex>p = \left \langle v_0, v_1, \dots, v_k \right \rangle</tex>, где <tex>k > 0</tex>. | ||
+ | |||
+ | <tex> ~ ~ h(v_{i - 1}) = h(v_{i}) + 1</tex> для <tex>i = 1, 2, \dots, k</tex>, так как каждое ребро данного пути допустимое. Просуммировав равенства вдоль циклического пути, получаем: | ||
+ | |||
+ | <tex>\sum \limits_{i = 1}^{k} h(v_{i - 1}) = \sum \limits_{i = 1}^{k} (h(v_{i}) + 1) = \sum \limits_{i = 1}^{k} h(v_{i}) + k</tex> | ||
+ | |||
+ | Так как каждая вершина циклического пути <tex>p</tex> встречается при суммировании по одному разу это значит то, что <tex>k = 0</tex>, что противоречит первоначальному предположению. Значит, допустимая сеть является ациклической. | ||
}} | }} | ||
Версия 01:57, 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.
- Алгоритм проталкивания предпотока — Википедия