Алгоритм "поднять-в-начало" — различия между версиями
Whiplash (обсуждение | вклад) м (→Допустимые ребра) |
Whiplash (обсуждение | вклад) м (→Допустимые ребра) |
||
Строка 47: | Строка 47: | ||
Если вершина <tex>u</tex> переполнена и не имеется допустимых ребер, выходящих из <tex>u</tex>, то применяется операция <tex>relabel(u)</tex>. После подъема появляется по крайней мере одно допустимое ребро, выходящее из <tex>u</tex>, но нет допустимых ребер, входящих в <tex>u</tex>. | Если вершина <tex>u</tex> переполнена и не имеется допустимых ребер, выходящих из <tex>u</tex>, то применяется операция <tex>relabel(u)</tex>. После подъема появляется по крайней мере одно допустимое ребро, выходящее из <tex>u</tex>, но нет допустимых ребер, входящих в <tex>u</tex>. | ||
|proof = | |proof = | ||
− | Рассмотрим вершину <tex>u</tex>. Если <tex>u</tex> переполнена, то, согласно [[Метод проталкивания предпотока#Лемма2|лемме (2)]], к ней может быть применима либо операция проталкивания, либо операция подъема. А так как не существует допустимых ребер для <tex>u</tex>, то протолкнуть поток не возможно, значит, применяется операция <tex> | + | Рассмотрим вершину <tex>u</tex>. Если <tex>u</tex> переполнена, то, согласно [[Метод проталкивания предпотока#Лемма2|лемме (2)]], к ней может быть применима либо операция проталкивания, либо операция подъема. А так как не существует допустимых ребер для <tex>u</tex>, то протолкнуть поток не возможно, значит, применяется операция <tex>relabel(u)</tex>. После данного подъема <tex>h[u] = 1 + min \{ h[v]: (u, v) \in E_{f} \}</tex>. Значит, если <tex>u</tex> {{---}} вершина указанного множества, в которой реализуется минимум, то <tex>(u, v)</tex> становится допустимым. А это значит, что после подъема существует хотя бы одно допустимое ребро, выходящее из <tex>u</tex>. |
Пусть существует такая вершина <tex>u</tex>, после подъема, что ребро <tex>(u, v)</tex> допустимо. Тогда <tex>h[v] = h[u] + 1</tex>, значит, перед подъемом <tex>h[v] > h[u] + 1</tex>. Но между вершинами, высоты которых отличаются более чем на 1, не существует остаточных сетей. Кроме того, подъем вершины не меняет остаточную сеть. Значит, ребро <tex>(v, u)</tex> не может находится в допустимой сети, так как оно не принадлежит остаточной сети. | Пусть существует такая вершина <tex>u</tex>, после подъема, что ребро <tex>(u, v)</tex> допустимо. Тогда <tex>h[v] = h[u] + 1</tex>, значит, перед подъемом <tex>h[v] > h[u] + 1</tex>. Но между вершинами, высоты которых отличаются более чем на 1, не существует остаточных сетей. Кроме того, подъем вершины не меняет остаточную сеть. Значит, ребро <tex>(v, u)</tex> не может находится в допустимой сети, так как оно не принадлежит остаточной сети. |
Версия 12:33, 27 декабря 2012
Алгоритм "поднять-в-начало" (relabel-to-front) основан на методе проталкивание предпотока, но из-за тщательного выбора порядка выполнения операций проталкивания и подъема, время выполнения данного алгоритма составляет , что асимптотически не хуже, чем .
Содержание
Допустимые ребра
сеть с истоком и стоком , — предпоток в , — функция высоты.
—Определение: |
Допустимое ребро (admissible edge) — ребро | , у которого и . В противном случае называется недопустимым (inadmissible).
Определение: |
Допустимая сеть (admissible network) — сеть | , где — множество допустимых ребер.
Лемма (Допустимая сеть является ациклической): |
Допустимая сеть является ациклической. |
Доказательство: |
Пусть в циклический путь , где . существуетдля , так как каждое ребро данного пути допустимое. Просуммировав равенства вдоль циклического пути, получаем: Так как каждая вершина циклического пути встречается при суммировании по одному разу это значит то, что , что противоречит первоначальному предположению. Значит, допустимая сеть является ациклической. |
Лемма (Об изменении допустимой цепи, с помощью операции проталкивания): |
Если вершина переполнена и ребро допустимое, то применяемая операция не создает новые допустимые ребра, но может привести к тому, что ребро станет недопустимым. |
Доказательство: |
Так как ребро Если выполненная операция допустимое то, по определению допустимого ребра, из в можно протолкнуть поток. Из-за того что — переполнена, вызываем операцию . В результате выполнения операции может быть создано остаточное ребро . Так ребро допустимое то, , а это значит, что ребро не может стать допустимым. является насыщающим проталкиванием, то после ее выполнения и ребро становится недопустимым. |
Лемма (Об изменении допустимой цепи, с помощью операции подъема): |
Если вершина переполнена и не имеется допустимых ребер, выходящих из , то применяется операция . После подъема появляется по крайней мере одно допустимое ребро, выходящее из , но нет допустимых ребер, входящих в . |
Доказательство: |
Рассмотрим вершину лемме (2), к ней может быть применима либо операция проталкивания, либо операция подъема. А так как не существует допустимых ребер для , то протолкнуть поток не возможно, значит, применяется операция . После данного подъема . Значит, если — вершина указанного множества, в которой реализуется минимум, то становится допустимым. А это значит, что после подъема существует хотя бы одно допустимое ребро, выходящее из . Пусть существует такая вершина . Если переполнена, то, согласно , после подъема, что ребро допустимо. Тогда , значит, перед подъемом . Но между вершинами, высоты которых отличаются более чем на 1, не существует остаточных сетей. Кроме того, подъем вершины не меняет остаточную сеть. Значит, ребро не может находится в допустимой сети, так как оно не принадлежит остаточной сети. |
Идея
Операция разгрузки (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.
- Алгоритм проталкивания предпотока — Википедия