Изменения

Перейти к: навигация, поиск
Реализация
Метод интересен прежде всего тем, что [[Сведение задачи о назначениях к задаче о потоке минимальной стоимости|задачу о назначениях]] можно свести к задаче о поиске потока минимальной стоимости, и тогда эффективность решения задачи о назначениях будет определяться именно асимптотикой работы этого алгоритма.
 
== Мотивация ==
Зачем нужно использовать потенциалы Джонсона? Идея аналогична идее, использующейся в [[Алгоритм Джонсона|алгоритме Джонсона]]. При [[Поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости|поиске потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости]] нам требуется находить минимальный по стоимости поток из истока в сток. Это реализуется с помощью алгоритмов поиска кратчайшего пути в графе. Поскольку стоимость некоторых рёбер может быть отрицательной, нам приходится использовать [[Алгоритм Форда-Беллмана|алгоритм Форда-Беллмана]] для поиска кратчайшего пути. Однако гораздо эффективней было бы применить [[Алгоритм Дейкстры|алгоритм Дейкстры]]для этой же цели, так как у него гораздо лучше асимптотика. Для этого нам надо перевзвесить рёбра графа.
{{Определение
|definition=Пусть дана транспортная сеть <tex>\,G(V,E)</tex>, где <tex>V</tex> — множество вершин графа, а <tex>E</tex> — множество рёбер. Введем в каждой вершине потенциал <tex>\,P_ip(v)</tex>. Тогда остаточная потенциальный вес (то есть стоимость ) ребра <tex>\(u,C_{P_{ij}}v)</tex> определяется как<tex>\w_p(u,C_{P_{ij}} v) = C_{ij} w(u, v) + P_i p(u) - P_j p(v) </tex>
}}
Заметим , что сумма остаточных стоимостей потенциальных весов ребер вдоль любого пути отличается от суммы стоимостей весов вдоль того же самого пути на разность между потенциалом первой и последней вершины.
== Использование потенциалов Джонсона ==
Возьмём значения потенциалов в вершинах равными минимальному по цене расстоянию от стока истока до них, или а расстояния найдём с помощью [[Алгоритм Форда-Беллмана|алгоритма Форда-Беллмана]]. Таким образом, нам его придётся запустить всего один раз, а не на каждом шаге алгоритма. Однако, после добавления потока вдоль кратчайшего увеличивающего пути в сети могут появиться новые ребра, равно как и исчезнуть старые, и будет необходимо пересчитать потенциалы, чтобы они оставались корректными, то есть <tex>p(v)</tex> - длина кратчайшего пути от истока в вершину <tex>v</tex> в новой сети. Научимся делать это, не запуская каждый раз Форда-Беллмана. Для начала докажем, что в сети с корректными потенциалами <tex>w_p(u, v) = 0</tex> для любого ребра <tex>(u, v)</tex>, лежащего на кратчайшем пути из <tex>s</tex> в <tex>t</tex>. Пусть <tex>s, v_1, v_2, \ldots, v_k, t</tex> - кратчайший путь из <tex>s</tex> в <tex>t</tex>, и <tex>d(u, v)</tex> - длина кратчайшего пути между вершинами <tex>u</tex> и <tex>v</tex> в исходной сети без потенциалов. Тогда <tex>w(s, v_1) + w(v_1, v_2) +\inftyldots + w(v_k, t) = d(s, t)</tex> если она недостижима. Так как и <tex>w_p(s, v_1) + w_p(v_1, v_2) + \ldots + w_p(v_k,C_{ij} t) = p(s) + w(s, v_1) + w(v_1, v_2) + \ldots + w(v_k, t) - p(t) = p(s) + d(s, t) - p(t) = p(s) + P_ip(t) - p(t) = p(s) = 0</tex> это длина какого-то . Таким образом, сумма всех потенциальных весов ребер на кратчайшем пути до вершины из <tex>s</tex> в <tex>t</tex> равна нулю. Кроме того, для любого ребра <tex>(u, v)</tex> <tex>w_p(u, v) \geq 0</tex>. Следственно, <tex>w_p(u, v) = 0</tex> для любого ребра <tex>(u, v)</tex>, лежащего на кратчайшем пути из <tex>s</tex> в <tex>t</tex>.  Более того, потенциальный вес всех ребер, обратных ребрам из кратчайшего пути,jтоже равен <tex>0</tex>. И правда, а <tex>\w_p(u, v) = w(u, v) + d(s, u) - d(s,P_jv) = 0</tex>. Умножив на <tex>-1</tex> , получаем <tex>0 = -w(u, v) - d(s, u) + d(s, v) = w(v, u) + d(s, v) - длина минимального d(s, u) = w_p(v, u)</tex> Из доказанных выше фактов следует, что при добавлении потока вдоль кратчайшего путив сети с корректными потенциалами не появляется ребер с отрицательным весом (однако сами потенциалы уже становятся некорректными). Но так как ребер отрицательного веса нет, то мы можем пустить алгоритм Дейкстры из <tex>C_{P_{ij}} \geqslant 0s</tex>, чтобы насчитать новые потенциалы. Пусть <tex>d_1(u, v)</tex> - кратчайшее расстояние, найденное алгоритмом Дейкстры, из <tex>u</tex> в <tex>v</tex> в сети с появившимися новыми ребрами, но старыми потенциалами, а <tex>d(u, v)</tex>- кратчайшее расстояние в новой сети без потенциалов. Нетрудно заметить, что <tex>d_1(s, v) = d(s, v) - p(v)</tex>, следственно, <tex>d(s, v) = d_1(s, v) + p(v)</tex>. Зная настоящие расстояния от нас истока до каждой вершины, мы теперь можем проставить новые потенциалы. Для каждой вершины <tex>v</tex> <tex>p(v) \gets d(s, v) = d_1(s, v) + p(v)</tex>. Кроме того, мы также нашли новый кратчайший путь из истока из сток - а значит, на следующей итерации алгоритма мы можем пустить поток по нему и требовалосьповторить все заново.Значения потенциалов найдём с помощью ==Реализация==Модифицируем псевдокод из статьи про [[Алгоритм Форда-БеллманаПоиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости|алгоритма поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости]]:  '''for''' <tex>e \in E</tex> { <tex>f[e] \leftarrow 0</tex> } Запустим алгоритм Форда-Беллмана, в результате для каждой вершины: <tex>p[v]]. Таким образом</tex> — кратчайшее расстояние <tex>s \leadsto v</tex>, нам если за длину ребра принимается его придётся запустить всего один разстоимость. '''while''' (существует путь <tex>s \leadsto t</tex> в остаточной сети <tex>G_f</tex>) { Восстановить <tex>P </tex> — кратчайший в смысле стоимости путь <tex>s \leadsto t</tex>, а не найденный на каждом предыдущем шаге алгоритма. дополнить поток <tex>f</tex> вдоль <tex>P</tex> Запустить алгоритм Дейкстры из <tex>s</tex>, чтобы насчитать <tex>d_1</tex> '''for''' <tex>v \in V</tex> { <tex>p[v] \leftarrow p[v] + d_1[v]</tex> } }
==Асимптотика==
Обозначим время работы поиска кратчайшего пути <tex>F(V, E)</tex>Пусть все пропускные способности целочисленны.[[Поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости|Поиске потока минимальной стоимости методом дополнения вдоль путей минимальной стоимостиМетод целиком]] работает за <tex>O(F(V, E) \cdot |f|)</tex>, где <tex>F(V, E)</tex> — время одной итерации. Время, затраченное на одну итерацию, определяется скоростью поиска кратчайшего пути.Если для этой цели использовать [[Алгоритм Дейкстры|алгоритм Дейкстры]] с Фиббоначевыми кучами, то поиск мы осуществим за <tex>FO(V, E)= V \log V + E)</tex>.  Не стоит так же забывать, что для расчёта потенциалов мы один раз запустили Алгоритм Форда-Беллмана.В результате получим время работы <tex>O((V \log V + E) \cdot |f|+ V E)</tex>. Это лучше, чем <tex>O((V E) \cdot |f|)</tex>, что получается при использовании [[Алгоритм Форда-Беллмана|алгоритма Форда-Беллмана]] для поиска кратчайшего пути на каждой итерации.  В применении к [[Сведение задачи о назначениях к задаче о потоке минимальной стоимости|задаче о назначениях]]: пусть у нас есть <tex>N</tex> назначений. Построим специальным образом граф. Искомый поток в нём имеет имеет мощность <tex>N</tex>. Количество вершин — <tex>O(N)</tex>, рёбер — <tex>O(N^2)</tex>. Итого получаем асимптотику <tex>O(N^2 \log N + 2N^3) = O(N^3)</tex>. == Литература ==* ''Andrew V. Goldberg'' An Efficient implementation of a scaling minimum-cost flow algorithm - Journal of Algorithms, 1997
== См. также ==
* [[Алгоритм Дейкстры]]
* [[Алгоритм Форда-Беллмана]]
* [[Поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости]]
* [[Алгоритм Джонсона]]
[[Категория:Алгоритмы и структуры данных]]
[[Категория: Задача о потоке минимальной стоимости]]
Анонимный участник

Навигация