Изменения

Перейти к: навигация, поиск
Реализация
{{Определение
|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, \inftyldots, 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,c_{ij} t) = p(s) + p_iw(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>. Следственно,j<tex>w_p(u, v) = 0</tex>для любого ребра <tex>(u, а v)</tex>\,p_jлежащего на кратчайшем пути из <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>c_{p_{ij}} \geqslant 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>. Кроме того, мы также нашли новый кратчайший путь из истока из сток - а не значит, на каждом шаге следующей итерации алгоритмамы можем пустить поток по нему и повторить все заново.
==Реализация==
<tex>f[e] \leftarrow 0</tex>
}
Запустим алгоритм Форда-Беллмана, в результате для каждой вершины: <tex>p[v] </tex> — кратчайшее расстояние <tex>s \leadsto ev</tex>,
если за длину ребра принимается его стоимость.
'''for''' <tex>e \in E</tex> {
<tex>c[e] \leftarrow c[e] + p[e.from] - p[e.to]</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>
}
}
Анонимный участник

Навигация