Appearance
Потоки в сетях
1. Сеть, пропускная способность, поток
Раньше вес ребра означал длину или время. Теперь представим, что ребро — это труба, по которой течет жидкость (газ, нефть; в интернете — пакеты данных). У каждой трубы есть пропускная способность: больше определенного количества она пропустить не может. Как у дороги: если четырехполосная дорога превращается в трехполосную, возникает узкое горлышко, и четвертую полосу учитывать бессмысленно.
Сеть
— множество вершин, — множество дуг; - выделены две вершины: исток
(откуда поток вытекает) и сток (куда поток втекает); - остальные вершины — промежуточные;
- на дугах задана функция
— пропускная способность дуги («ширина трубы»).
Поток — функция
Если у дуги пропускная способность 3, поток 4 по ней пустить нельзя.
2. Разрез сети
Разрез — разбиение всех вершин на два множества
Дуги, пересекающие границу разреза, бывают двух видов:
- попутные — идут из части с истоком в часть со стоком (
); - встречные — идут обратно (
).
Величина разреза — сумма пропускных способностей только попутных дуг. Встречные не учитываем.
Пример: через границу идут попутные дуги с пропускными способностями
Разрезов в сети конечное число:
и зафиксированы, каждая из остальных вершин лежит в одной из двух частей, всего вариантов. Среди них есть разрез минимальной величины.
Основная теорема
Интуиция: поток не может превысить величину любого разреза, ведь все, что течет из
- все попутные дуги заполнены на 100% (
); - все встречные дуги пусты (
).
Поэтому из
Следствие: встречные дуги через минимальный разрез можно добавлять сколько угодно и с любой пропускной способностью, максимальный поток от этого не изменится.
3. Алгоритм Форда — Фалкерсона
Идея: пока можно, искать увеличивающий путь из
- Запускаем DFS из
, ищем путь до по «открытым» дугам (о том, какие дуги открыты, ниже). - На пути находим узкое место, то есть минимум остаточных пропускных способностей. Ровно на эту величину увеличиваем поток вдоль всего пути.
- Дуга, у которой
, становится закрытой. - Повторяем, пока путь находится. Когда DFS больше не доходит до
, поток максимален.
4. Дивергенция вершины
Для вершины
Для любой вершины, кроме истока и стока, в идеальной модели
то есть сколько пришло, столько и ушло.
Пример: в вершину пришло
Из истока поток только выходит, в сток только входит, поэтому
Условие
5. Движение против ребра
Возьмем сеть, где все пропускные способности равны
Оказывается, надо разрешить идти против ребра, по которому уже течет поток, и уменьшать его.
Для трубы с пропускной способностью
| Куда идем | Когда дуга «открыта» | Что делаем с потоком |
|---|---|---|
| вдоль дуги | увеличиваем, не больше чем на | |
| против дуги | уменьшаем, не больше чем на |
Увеличивающий путь теперь может содержать и те и другие дуги. Узкое место — минимум из всех этих «запасов»:
Почему инвариант не ломается
Пусть путь входит в вершину
- пришли вдоль дуги (
к притоку), ушли вдоль дуги ( к оттоку): приток и отток выросли поровну; - пришли вдоль дуги (
к притоку), ушли против дуги, которая входит в ( к притоку): приток вырос на и тут же уменьшился на , баланс не изменился; - остальные комбинации разбираются так же.
Образно: у вершины был один вход и один выход, мы заменили один из них другим. Вершине все равно, по какой именно дуге пришло и по какой ушло, главное, что сколько вошло, столько и вышло. Поэтому
Связь с «обратными ребрами»
В учебниках обычно пишут иначе: если по дуге
6. Асимптотика
Вещественные пропускные способности
Алгоритм плохо работает с нецелыми числами: можно построить сеть, в которой увеличивающие пути дают все меньшие приращения (например, убывающие как корень из чего-то), и поток растет бесконечно долго. Поэтому:
- работаем в основном с целыми пропускными способностями;
- для вещественных вводят
: если приращение меньше , останавливаемся.
Худший случай
DFS находит какой-то путь, и ничего, кроме того, что он найдет путь, если тот существует, не гарантируется.
Возьмем 4 вершины
- Первый путь
дает приращение 1 (узкое место — перемычка). - Второй путь
идет против перемычки и тоже дает всего 1. - Дальше пути «качаются» через перемычку туда-обратно, каждый раз добавляя по единице.
Всего будет порядка
где
7. Сравнение алгоритмов
| Алгоритм | Как ищем увеличивающий путь | Асимптотика |
|---|---|---|
| Форд — Фалкерсон | DFS | |
| Эдмондс — Карп | BFS, то есть кратчайший по числу ребер путь | |
| Диниц | строит слоистую сеть и DFS-ом проталкивает поток по ней | идея объединяет DFS и BFS, оценка не зависит от |
Эдмондс — Карп выбирает путь с наименьшим числом дуг. То есть идет сортировка по удаленности от истока.
Алгоритм Диница разберем на следующей лекции вместе с кодом:
- BFS от истока строит слоистую сеть: слои определяются удаленностью вершины от
; - вдоль слоистой сети DFS аккуратно проталкивает поток, пока это возможно;
- затем слоистая сеть строится заново, и все повторяется, пока
достижим.
Известная оценка для Диница (на лекции ее не выводили, показываем для справки):