Использование потенциалов Джонсона при поиске потока минимальной стоимости — различия между версиями
(→Реализация) |
|||
Строка 44: | Строка 44: | ||
} | } | ||
} | } | ||
+ | |||
+ | Стоит заметить, что на практике удобнее использовать <tex> p[v] \leftarrow d_1[v] <\tex>. В таком случае не возникает проблем с убавлением и прибавлением к константе "бесконечность" в коде, при этом потенциалы остаются корректными, то есть сохраняют кратчайшие пути и не создают ребер отрицательного веса, т.к. сами являются кратчайшими расстояниями, только не в настоящей остаточной сети, а в сети с потенциалами, расставленными на предыдущем шаге. | ||
==Асимптотика== | ==Асимптотика== |
Версия 18:07, 22 мая 2018
Метод интересен прежде всего тем, что задачу о назначениях можно свести к задаче о поиске потока минимальной стоимости, и тогда эффективность решения задачи о назначениях будет определяться именно асимптотикой работы этого алгоритма.
Мотивация
Зачем нужно использовать потенциалы Джонсона?
Идея аналогична идее, использующейся в алгоритме Джонсона.
При поиске потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости нам требуется находить минимальный по стоимости поток из истока в сток. Это реализуется с помощью алгоритмов поиска кратчайшего пути в графе. Поскольку стоимость некоторых рёбер может быть отрицательной, нам приходится использовать алгоритм Форда-Беллмана. Однако гораздо эффективней было бы применить алгоритм Дейкстры для этой же цели, так как у него гораздо лучше асимптотика. Для этого нам надо перевзвесить рёбра графа.
Определение: |
Пусть дана транспортная сеть | , где — множество вершин графа, а — множество рёбер. Введем в каждой вершине потенциал . Тогда потенциальный вес (то есть стоимость) ребра определяется как
Заметим, что сумма потенциальных весов ребер вдоль любого пути отличается от суммы весов вдоль того же самого пути на разность между потенциалом первой и последней вершины.
Использование потенциалов Джонсона
Возьмём значения потенциалов в вершинах равными минимальному расстоянию от истока до них, а расстояния найдём с помощью алгоритма Форда-Беллмана. Таким образом, нам его придётся запустить всего один раз, а не на каждом шаге алгоритма. Однако, после добавления потока вдоль кратчайшего увеличивающего пути в сети могут появиться новые ребра, равно как и исчезнуть старые, и будет необходимо пересчитать потенциалы, чтобы они оставались корректными, то есть - длина кратчайшего пути от истока в вершину в новой сети. Научимся делать это, не запуская каждый раз Форда-Беллмана.
Для начала докажем, что в сети с корректными потенциалами
для любого ребра , лежащего на кратчайшем пути из в .Пусть
- кратчайший путь из в , и - длина кратчайшего пути между вершинами и в исходной сети без потенциалов. Тогда и . Таким образом, сумма всех потенциальных весов ребер на кратчайшем пути из в равна нулю. Кроме того, для любого ребра . Следственно, для любого ребра , лежащего на кратчайшем пути из в .Более того, потенциальный вес всех ребер, обратных ребрам из кратчайшего пути, тоже равен
. И правда, . Умножив на , получаемИз доказанных выше фактов следует, что при добавлении потока вдоль кратчайшего пути в сети с корректными потенциалами не появляется ребер с отрицательным весом (однако сами потенциалы уже становятся некорректными). Но так как ребер отрицательного веса нет, то мы можем пустить алгоритм Дейкстры из
, чтобы насчитать новые потенциалы. Пусть - кратчайшее расстояние, найденное алгоритмом Дейкстры, из в в сети с появившимися новыми ребрами, но старыми потенциалами, а - кратчайшее расстояние в новой сети без потенциалов. Нетрудно заметить, что , следственно, . Зная настоящие расстояния от истока до каждой вершины, мы теперь можем проставить новые потенциалы. Для каждой вершины .Кроме того, мы также нашли новый кратчайший путь из истока из сток - а значит, на следующей итерации алгоритма мы можем пустить поток по нему и повторить все заново.
Реализация
Модифицируем псевдокод из статьи про поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости:
for{ } Запустим алгоритм Форда-Беллмана, в результате для каждой вершины: — кратчайшее расстояние , если за длину ребра принимается его стоимость. while (существует путь в остаточной сети ) { Восстановить — кратчайший в смысле стоимости путь , найденный на предыдущем шаге дополнить поток вдоль Запустить алгоритм Дейкстры из , чтобы насчитать for { } }
Стоит заметить, что на практике удобнее использовать
, где — время одной итерации.Время, затраченное на одну итерацию, определяется скоростью поиска кратчайшего пути. Если для этой цели использовать алгоритм Дейкстры с Фиббоначевыми кучами, то поиск мы осуществим за .
Не стоит так же забывать, что для расчёта потенциалов мы один раз запустили Алгоритм Форда-Беллмана. В результате получим время работы
.Это лучше, чем алгоритма Форда-Беллмана для поиска кратчайшего пути на каждой итерации.
, что получается при использовании
В применении к задаче о назначениях: пусть у нас есть назначений. Построим специальным образом граф. Искомый поток в нём имеет имеет мощность . Количество вершин — , рёбер — . Итого получаем асимптотику .
Литература
- Andrew V. Goldberg An Efficient implementation of a scaling minimum-cost flow algorithm - Journal of Algorithms, 1997