Использование потенциалов Джонсона при поиске потока минимальной стоимости — различия между версиями
(Добавил описание пересчета потенциалов после добавления потока вдоль кратчайшего пути, раньше здесь был вообще некорректный алгоритм) |
|||
| Строка 10: | Строка 10: | ||
{{Определение | {{Определение | ||
| − | |definition=Пусть дана транспортная сеть <tex>\,G(V,E)</tex>, где <tex>V</tex> — множество вершин графа, а <tex>E</tex> — множество рёбер. Введем в каждой вершине потенциал <tex> | + | |definition=Пусть дана транспортная сеть <tex>\,G(V,E)</tex>, где <tex>V</tex> — множество вершин графа, а <tex>E</tex> — множество рёбер. Введем в каждой вершине потенциал <tex>p(v)</tex>. Тогда потенциальный вес (то есть стоимость) ребра <tex>(u, v)</tex> определяется как |
| − | <tex> | + | <tex>w_p(u, v) = w(u, v) + p(u) - p(v) </tex> |
}} | }} | ||
| − | Заметим, что сумма | + | Заметим, что сумма потенциальных весов ребер вдоль любого пути отличается от суммы стоимостей вдоль того же самого пути на разность между потенциалом первой и последней вершины. |
== Использование потенциалов Джонсона == | == Использование потенциалов Джонсона == | ||
| − | Возьмём значения потенциалов в вершинах равными минимальному | + | Возьмём значения потенциалов в вершинах равными минимальному расстоянию от истока до них, а расстояния найдём с помощью [[Алгоритм Форда-Беллмана|алгоритма Форда-Беллмана]]. Таким образом, нам его придётся запустить всего один раз, а не на каждом шаге алгоритма. Однако, после добавления потока вдоль кратчайшего увеличивающего пути в сети могут появиться новые ребра, равно как и исчезнуть старые, и будет необходимо пересчитать потенциалы, чтобы они оставались корректными, то есть <tex>p(v)</tex> - длина кратчайшего пути от истока в вершину <tex>v</tex> в новой сети. Научимся делать это, не запуская каждый раз Форда-Беллмана. |
| − | |||
| − | Для начала докажем, что в сети с корректными потенциалами <tex>w_p(u, v) = 0</tex> для любого ребра <tex>(u, v)</tex>, лежащего на пути <tex>s \ | + | Для начала докажем, что в сети с корректными потенциалами <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) + \ldots + 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, 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(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>. | ||
| + | |||
| + | Более того, потенциальный вес всех ребер, обратных ребрам из кратчайшего пути, тоже равен <tex>0</tex>. И правда, <tex>w_p(u, v) = w(u, v) + d(s, u) - d(s, v) = 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>s</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> { | '''for''' <tex>e \in E</tex> { | ||
| Строка 30: | Строка 36: | ||
Запустим алгоритм Форда-Беллмана, в результате для каждой вершины: <tex>p[v] </tex> — расстояние <tex>s \leadsto e</tex>, | Запустим алгоритм Форда-Беллмана, в результате для каждой вершины: <tex>p[v] </tex> — расстояние <tex>s \leadsto e</tex>, | ||
если за длину ребра принимается его стоимость. | если за длину ребра принимается его стоимость. | ||
| − | |||
| − | |||
| − | |||
'''while''' (существует путь <tex>s \leadsto t</tex> в остаточной сети <tex>G_f</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>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> | ||
| + | } | ||
} | } | ||
Версия 19:21, 5 мая 2018
Метод интересен прежде всего тем, что задачу о назначениях можно свести к задаче о поиске потока минимальной стоимости, и тогда эффективность решения задачи о назначениях будет определяться именно асимптотикой работы этого алгоритма.
Мотивация
Зачем нужно использовать потенциалы Джонсона?
Идея аналогична идее, использующейся в алгоритме Джонсона.
При поиске потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости нам требуется находить минимальный по стоимости поток из истока в сток. Это реализуется с помощью алгоритмов поиска кратчайшего пути в графе. Поскольку стоимость некоторых рёбер может быть отрицательной, нам приходится использовать алгоритм Форда-Беллмана. Однако гораздо эффективней было бы применить алгоритм Дейкстры для этой же цели, так как у него гораздо лучше асимптотика. Для этого нам надо перевзвесить рёбра графа.
| Определение: |
| Пусть дана транспортная сеть , где — множество вершин графа, а — множество рёбер. Введем в каждой вершине потенциал . Тогда потенциальный вес (то есть стоимость) ребра определяется как |
Заметим, что сумма потенциальных весов ребер вдоль любого пути отличается от суммы стоимостей вдоль того же самого пути на разность между потенциалом первой и последней вершины.
Использование потенциалов Джонсона
Возьмём значения потенциалов в вершинах равными минимальному расстоянию от истока до них, а расстояния найдём с помощью алгоритма Форда-Беллмана. Таким образом, нам его придётся запустить всего один раз, а не на каждом шаге алгоритма. Однако, после добавления потока вдоль кратчайшего увеличивающего пути в сети могут появиться новые ребра, равно как и исчезнуть старые, и будет необходимо пересчитать потенциалы, чтобы они оставались корректными, то есть - длина кратчайшего пути от истока в вершину в новой сети. Научимся делать это, не запуская каждый раз Форда-Беллмана.
Для начала докажем, что в сети с корректными потенциалами для любого ребра , лежащего на кратчайшем пути из в .
Пусть - кратчайший путь из в в исходной сети без потенциалов, и - длина кратчайшего пути между вершинами и . Тогда и . Таким образом, сумма всех потенциальных весов ребер на кратчайшем пути из в равна нулю. Кроме того, для любого ребра . Следственно, для любого ребра , лежащего на кратчайшем пути из в .
Более того, потенциальный вес всех ребер, обратных ребрам из кратчайшего пути, тоже равен . И правда, . Умножив на , получаем
Из доказанных выше фактов следует, что при добавлении потока вдоль кратчайшего пути в сети с корректными потенциалами не появляется ребер с отрицательным весом (однако сами потенциалы уже становятся некорректными). Но так как ребер отрицательного веса нет, то мы можем пустить алгоритм Дейкстры из , чтобы насчитать новые потенциалы. Пусть - кратчайшее расстояние, найденное алгоритмом Дейкстры, из в в сети с появившимися новыми ребрами, но старыми потенциалами, а - кратчайшее расстояние в новой сети без потенциалов. Нетрудно заметить, что , следственно, . Зная настоящие расстояния от истока до каждой вершины, мы теперь можем проставить новые потенциалы. Для каждой вершины .
Кроме того, мы также нашли новый кратчайший путь из истока из сток - а значит, на следующей итерации алгоритма мы можем пустить поток по нему и повторить все заново.
Реализация
Модифицируем псевдокод из статьи про поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости:
for { } Запустим алгоритм Форда-Беллмана, в результате для каждой вершины: — расстояние , если за длину ребра принимается его стоимость. while (существует путь в остаточной сети ) { Восстановить — кратчайший в смысле стоимости путь , найденный на предыдущем шаге дополнить поток вдоль Запустить алгоритм Дейкстры из , чтобы насчитать for { } }
Асимптотика
Пусть все пропускные способности целочисленны. Метод целиком работает за , где — время одной итерации.
Время, затраченное на одну итерацию, определяется скоростью поиска кратчайшего пути. Если для этой цели использовать алгоритм Дейкстры с Фиббоначевыми кучами, то поиск мы осуществим за .
Не стоит так же забывать, что для расчёта потенциалов мы один раз запустили Алгоритм Форда-Беллмана. В результате получим время работы .
Это лучше, чем , что получается при использовании алгоритма Форда-Беллмана для поиска кратчайшего пути на каждой итерации.
В применении к задаче о назначениях: пусть у нас есть назначений. Построим специальным образом граф. Искомый поток в нём имеет имеет мощность . Количество вершин — , рёбер — . Итого получаем асимптотику .
Литература
- Andrew V. Goldberg An Efficient implementation of a scaling minimum-cost flow algorithm - Journal of Algorithms, 1997