1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6

# теория · шаг 2 из 6

Алгоритм Джонсона: как сделать веса неотрицательными честно

Коротко

На разреженном графе O(V³) Флойда - расточительство: V запусков Дейкстры стоили бы O(V·E·log V), что заметно дешевле. Мешает одно - отрицательные веса. Джонсон убирает их честно: каждой вершине назначается потенциал h[v] (кратчайшее расстояние от фиктивной вершины, соединённой нулевыми рёбрами со всеми), после чего вес каждого ребра заменяется на w'(u, v) = w(u, v) + h[u] − h[v]. Новые веса неотрицательны - это прямое следствие неравенства треугольника, - а кратчайшие пути остаются ТЕМИ ЖЕ, потому что длина любого пути из u в v меняется на одну и ту же величину h[u] − h[v], независимо от маршрута. Дальше V Дейкстр, и расстояния пересчитываются обратно.

Если ты знаешь, как считаются потенциалы, почему новые веса неотрицательны и почему перевзвешивание не меняет кратчайшие пути, листай до «Теперь сам».

Как думаешь, почему нельзя просто прибавить константу

В главе про Дейкстру мы уже видели: прибавить ко всем весам одно и то же число нельзя - добавка умножается на число рёбер, и путь из двух дешёвых рёбер проигрывает одному дорогому, хотя раньше выигрывал. Прежде чем читать дальше, подумай: какой должна быть добавка, чтобы она НЕ зависела от числа рёбер в пути? Подсказка: пусть у каждой вершины будет своя поправка, и пусть соседние поправки взаимно уничтожаются вдоль пути.

На что это похоже

Высота над уровнем моря на карте маршрутов. Замени «длину участка» на «длину плюс набор высоты»: для любого маршрута между двумя точками суммарный набор высоты одинаков - он равен разнице высот концов, какой бы дорогой ты ни шёл. Промежуточные подъёмы и спуски сокращаются. Потенциалы - это и есть такие «высоты», подобранные так, чтобы ни один участок не оказался «под горку с отрицательной длиной».

Механизм: потенциалы и перевзвешивание

Это описание словами, а не листинг: каждый шаг - вызов алгоритма, который уже разобран.

1) добавить фиктивную вершину q и рёбра q → v весом 0 для каждой вершины v
2) Беллман-Форд из q  →  h[v] = кратчайшее расстояние от q до v
   (если он нашёл отрицательный цикл - на этом всё, задача решения не имеет)
3) перевесить каждое ребро:  w'(u, v) = w(u, v) + h[u] − h[v]
4) V раз запустить Дейкстру по новым весам  →  d'(u, v)
5) вернуть настоящие расстояния:  d(u, v) = d'(u, v) − h[u] + h[v]

Почему новые веса неотрицательны. Величина h - это кратчайшие расстояния от q, а для них выполняется неравенство треугольника: h[v] <= h[u] + w(u, v) (иначе путь до v через u был бы короче, чем «кратчайший»). Переносим: w(u, v) + h[u] − h[v] >= 0. То есть w' >= 0 для каждого ребра - ровно то, что требуется Дейкстре.

Почему кратчайшие пути не меняются. Возьмём любой путь u = v₀ → v₁ → ... → v_k = v и сложим новые веса. Ниже v_i - это i-я вершина ПУТИ (не вершина с номером i в графе), а v_i+1 - следующая за ней, то есть v с индексом i + 1:

Σ w'(v_i, v_i+1) = Σ [ w(v_i, v_i+1) + h[v_i] − h[v_i+1] ]
                 = Σ w(v_i, v_i+1) + (h[v₀] − h[v₁]) + (h[v₁] − h[v₂]) + ... + (h[v_k−1] − h[v_k])
                 = (длина пути) + h[u] − h[v]

Промежуточные потенциалы сокращаются («телескопическая сумма»), и остаётся добавка h[u] − h[v], одна и та же для ВСЕХ путей между этой парой. Значит порядок путей по длине сохраняется: кратчайший остаётся кратчайшим.

Цена: O(V·E) на Беллмана-Форда плюс V Дейкстр - O(V·E·log V) на двоичной куче. Сравни с O(V³) Флойда: на разреженном графе (E ≈ V) это O(V²·log V) против O(V³) - выигрыш в V / log V раз (логарифм, как всюду в курсе, двоичный). В числах при V = 1000: log₂ 1000 ≈ 10, значит Джонсон делает порядка 10⁷ операций против 10⁹ у Флойда - в сотню раз меньше. А вот при V = 100 разрыв уже 15-кратный, и Флойд с его пятью строками часто оказывается разумнее.

Правило

Джонсон: добавить фиктивную вершину с нулевыми рёбрами ко всем, Беллманом-Фордом посчитать потенциалы h[v], перевесить рёбра как w'(u, v) = w(u, v) + h[u] − h[v] (получается неотрицательно по неравенству треугольника), V раз запустить Дейкстру и вернуть расстояния как d = d' − h[u] + h[v]. Кратчайшие пути сохраняются, потому что длина ЛЮБОГО пути из u в v меняется на одну и ту же величину h[u] − h[v] (телескопическая сумма). Цена O(V·E·log V) - выгоднее O(V³) на разреженных графах.

Разбор: считаем потенциалы на маленьком графе

Граф: a→b = 3, b→c = −2, a→c = 4, c→a = 5.

Добавляем q с рёбрами нулевого веса в a, b, c и считаем Беллманом-Фордом: h[a] = 0 (прямое ребро из q), h[b] = 0 (тоже прямое; путь через a дал бы 3 - хуже), h[c] = −2 (путь q → b → c стоит 0 + (−2), это лучше нуля).

Перевешиваем:

w'(a, b) = 3 + h[a] − h[b] = 3 + 0 − 0      = 3
w'(b, c) = −2 + h[b] − h[c] = −2 + 0 + 2    = 0
w'(a, c) = 4 + h[a] − h[c] = 4 + 0 + 2      = 6
w'(c, a) = 5 + h[c] − h[a] = 5 − 2 − 0      = 3

Все новые веса неотрицательны - можно звать Дейкстру. Проверим, что ответ не испортился. По новым весам кратчайший путь из a в c: напрямую 6 или через b: 3 + 0 = 3 - побеждает через b. Пересчитываем обратно: d(a, c) = d'(a, c) − h[a] + h[c] = 3 − 0 + (−2) = 1. По исходным весам путь a → b → c стоит 3 + (−2) = 1 - сходится, и это действительно лучше прямого ребра весом 4.

Разбор: зачем фиктивная вершина

Можно было бы взять h[v] равным расстоянию от какой-нибудь настоящей вершины - но тогда вершины, недостижимые из неё, получили бы h = +∞, и формула перевзвешивания развалилась бы. Фиктивная вершина q соединена нулевыми рёбрами СО ВСЕМИ, поэтому достижимо всё, и все потенциалы конечны.

Заодно она ничего не портит: из q рёбра только выходят, значит в кратчайшие пути между настоящими вершинами она попасть не может. А ещё она даёт полезный побочный эффект - Беллман-Форд из q видит ВСЕ отрицательные циклы графа, а не только достижимые из какой-то одной вершины. Если цикл есть, алгоритм честно останавливается: расстояний не существует, считать нечего.

Обрати внимание на приём в целом: мы не «чинили» отрицательные веса подгонкой, а нашли преобразование, которое одинаково сдвигает все пути между парой вершин. Тот же приём потенциалов встречается в алгоритмах потока минимальной стоимости - там он позволяет заменять Беллмана-Форда Дейкстрой на каждой итерации, и по той же самой причине.

Что ломается без этого

Первое: перевешивать как w + h[v] − h[u] (перепутать знаки) - веса станут отрицательными, и Дейкстра снова окажется неприменима. Второе: забыть пересчитать расстояния обратно и выдать d' как ответ - числа будут неверными везде, кроме пар с равными потенциалами. Третье: брать потенциалы от настоящей вершины вместо фиктивной - у недостижимых получится бесконечность. Четвёртое: применять Джонсона к графу с отрицательным циклом: Беллман-Форд обязан отработать первым и остановить всё. Пятое: тащить Джонсона на плотный граф - там V³ Флойда дешевле, да и проще; Джонсон выигрывает именно на разреженных.

Зачем это в работе

Матрицы расстояний нужны постоянно: логистика (стоимость доставки между всеми парами складов), предподсчёт в маршрутизации, подготовка данных для задач о назначениях и коммивояжёре. Если граф большой и разреженный, а веса бывают отрицательными (скидки, компенсации, субсидии), Джонсон - это и есть рабочий ответ. Но важнее приём: потенциал - способ изменить веса так, чтобы задача стала проще, а ответ остался прежним. Он же лежит в основе A* (следующая глава: эвристика - это потенциал), в потоках минимальной стоимости, в двойственных методах оптимизации. Увидев «отрицательные веса мешают алгоритму», стоит сразу спросить себя: нельзя ли их убрать перевзвешиванием, которое сохраняет порядок путей?

Теперь сам

Граф: x→y = 2, y→z = −3, x→z = 4. Посчитай потенциалы, перевесь рёбра и проверь, что кратчайший путь из x в z не изменился.

Ответ. Потенциалы (Беллман-Форд из фиктивной вершины с нулевыми рёбрами): h[x] = 0, h[y] = 0 (прямое нулевое ребро лучше пути через x, который дал бы 2), h[z] = −3 (путь q → y → z стоит 0 + (−3), лучше нуля).

Перевешиваем: w'(x, y) = 2 + 0 − 0 = 2; w'(y, z) = −3 + 0 − (−3) = 0; w'(x, z) = 4 + 0 − (−3) = 7. Все три неотрицательны ✓.

По новым весам кратчайший путь из x в z: через y стоит 2 + 0 = 2, напрямую - 7. Побеждает через y. Возвращаем: d(x, z) = 2 − h[x] + h[z] = 2 − 0 + (−3) = −1. Проверяем по исходным весам: x → y → z стоит 2 + (−3) = −1, прямое ребро - 4. Тот же маршрут, то же расстояние - перевзвешивание ничего не переставило. И обрати внимание на цифры: оба пути подорожали ровно на h[x] − h[z] = 0 − (−3) = 3 (было −1 и 4, стало 2 и 7) - добавка одинаковая, потому и порядок сохранился.

Главное

Джонсон решает задачу «все пары» на разреженном графе с отрицательными весами: добавить фиктивную вершину с нулевыми рёбрами ко всем, Беллманом-Фордом посчитать потенциалы h[v], перевесить рёбра как w'(u, v) = w(u, v) + h[u] − h[v], V раз запустить Дейкстру и вернуть d = d' − h[u] + h[v]. Неотрицательность новых весов - прямое следствие неравенства треугольника для кратчайших расстояний (h[v] <= h[u] + w). Кратчайшие пути сохраняются, потому что сумма новых весов вдоль ЛЮБОГО пути телескопически сворачивается в «длина плюс h[u] − h[v]»: добавка одна и та же для всех путей между парой, значит порядок путей по длине не меняется. Фиктивная вершина нужна, чтобы все потенциалы были конечны, и заодно ловит ВСЕ отрицательные циклы графа. Цена O(V·E·log V) против O(V³) у Флойда - на разреженных графах выигрыш в V/log V раз, на плотных проще Флойд. Приём с потенциалами шире этой задачи: он же работает в A* и в потоках минимальной стоимости.

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.