Проведите анализ алгоритма Дейкстры: докажите корректность для положительных весов ребёр, укажите ограничения при наличии отрицательных весов и предложите альтернативы (Bellman–Ford, Johnson) с оценкой сложности

11 Ноя в 09:43
4 +2
0
Ответы
1
Коротко и формально.
1) Утверждение корректности (для неотрицательных весов)
- Обозначения: граф с вершинами VVV, рёбра (u,v)(u,v)(u,v) с весами w(u,v)≥0w(u,v)\ge 0w(u,v)0. Исток sss. Пусть δ(s,v)\delta(s,v)δ(s,v) — длина кратчайшего пути s→vs\to vsv. Алгоритм хранит оценки d[v]d[v]d[v], и множество уже «закреплённых» вершин SSS. Инициализация: d[s]=0d[s]=0d[s]=0, остальные d=∞d=\inftyd=. На каждом шаге выбирается u∉Su\notin Su/S с минимальным d[u]d[u]d[u], добавляется в SSS и выполняется релаксация всех исходящих рёбер.
- Инвариант (для доказательства по индукции): при любом моменте для всех x∈Sx\in SxS выполнено d[x]=δ(s,x)d[x]=\delta(s,x)d[x]=δ(s,x). Кроме того, для всех vvv всегда d[v]≥δ(s,v)d[v]\ge\delta(s,v)d[v]δ(s,v) (оценка не меньше истинной длины, т.к. d[v]d[v]d[v] — длина некоторого обнаруженного пути).
- Базовый шаг: S={s}S=\{s\}S={s}, d[s]=0=δ(s,s)d[s]=0=\delta(s,s)d[s]=0=δ(s,s).
- Индукционный переход: пусть инвариант верен для множества SSS. Пусть uuu — вершина вне SSS с минимальным d[u]d[u]d[u]. Рассмотрим некоторый кратчайший путь PPP от sss до uuu. Пусть yyy — первая на PPP вершина, не лежащая в SSS, а xxx — её предшественник на PPP (тогда x∈Sx\in SxS). По индукции d[x]=δ(s,x)d[x]=\delta(s,x)d[x]=δ(s,x). Когда xxx был добавлен в SSS, ребро (x,y)(x,y)(x,y) было релаксировано, значит после обработки xxx выполнено
d[y]≤d[x]+w(x,y)=δ(s,x)+w(x,y)=δ(s,y). d[y]\le d[x]+w(x,y)=\delta(s,x)+w(x,y)=\delta(s,y).
d[y]d[x]+w(x,y)=δ(s,x)+w(x,y)=δ(s,y).
Так как uuu выбран с минимальным ddd среди вершин вне SSS, имеем d[u]≤d[y]d[u]\le d[y]d[u]d[y]. Отсюда
d[u]≤d[y]≤δ(s,y)≤δ(s,u), d[u]\le d[y]\le\delta(s,y)\le\delta(s,u),
d[u]d[y]δ(s,y)δ(s,u),
причём всегда d[u]≥δ(s,u)d[u]\ge\delta(s,u)d[u]δ(s,u). Следует d[u]=δ(s,u)d[u]=\delta(s,u)d[u]=δ(s,u). То есть инвариант сохраняется при добавлении uuu.
- Заключение: после завершения все d[v]=δ(s,v)d[v]=\delta(s,v)d[v]=δ(s,v). Ключевой момент — неотрицательность весов w(u,v)≥0w(u,v)\ge0w(u,v)0, которая обеспечивает монотонность оценок и справедливость выбора вершины с минимальным ddd.
2) Ограничения при наличии отрицательных весов
- Если существуют ребра с отрицательным весом, жадный выбор вершины с наименьшим ddd может дать неверный окончательный результат: может существовать путь к уже «закреплённой» вершине через ещё не обработанные вершины с суммарным отрицательным вкладом, делающим этот путь короче. Пример:
вершины s,a,b,cs,a,b,cs,a,b,c, рёбра: s→as\to asa вес 000, s→bs\to bsb вес 222, b→cb\to cbc вес −5-55, c→ac\to aca вес 222. Кратчайший путь s→b→c→as\to b\to c\to asbca имеет длину −1-11, но Dijkstra сначала закрепит aaa с d[a]=0d[a]=0d[a]=0 и не учтёт более короткий маршрут.
- Следствие: для гарантированной корректности алгоритма Dijkstra требуется неотрицательность всех весов на всех рёбрах, доступных из достижимых вершин. При отрицательных рёбрах никаких простых «локальных» исправлений не дают гарантию корректности во всех случаях.
- Дополнительно: если присутствуют отрицательные циклы, задача о кратчайшем пути в классическом смысле не определена (короче пути можно сделать сколь угодно).
3) Альтернативы для графов с отрицательными весами
- Bellman–Ford (одиночный источник):
- Работает при произвольных весах (позволяет отрицательные), обнаруживает отрицательные циклы (если после V−1V-1V1 итераций можно ещё релаксировать — есть отрицательный цикл).
- Сложность: O(VE)O(VE)O(VE).
- Подход: релаксировать все рёбра последовательно V−1V-1V1 раз; если после этого возможно улучшение — негативный цикл.
- Johnson (все-пары кратчайших путей, для разреженных графов):
- Сначала запускает Bellman–Ford от дополнительной вершины, чтобы получить потенциалы h(v)h(v)h(v). Затем переопределяет веса:
w′(u,v)=w(u,v)+h(u)−h(v), w'(u,v)=w(u,v)+h(u)-h(v),
w(u,v)=w(u,v)+h(u)h(v),
что гарантирует w′(u,v)≥0w'(u,v)\ge 0w(u,v)0 и сохраняет относительные расстояния между парами вершин.
- После этого запускает Dijkstra от каждой вершины на графе с весами w′w'w и восстанавливает оригинальные расстояния:
δ(u,v)=δ′(u,v)−h(u)+h(v). \delta(u,v)=\delta'(u,v)-h(u)+h(v).
δ(u,v)=δ(u,v)h(u)+h(v).
- Сложность: одна итерация Bellman–Ford O(VE)O(VE)O(VE) + VVV запусков Dijkstra. Итог:
- с бинарной кучей для Dijkstra: O(VE+V(E+V)log⁡V)O(VE + V(E+V)\log V)O(VE+V(E+V)logV),
- с фибоначчиевой кучей: O(VE+V2log⁡V)O(VE + V^2\log V)O(VE+V2logV) (т.к. один запуск Dijkstra — O(E+Vlog⁡V)O(E+V\log V)O(E+VlogV)).
- Johnson эффективен на разреженных графах (E≪V2E\ll V^2EV2). Требует отсутствия отрицательных циклов.
- Floyd–Warshall (все-пары, простой матричный метод):
- Работает для произвольных весов (может обнаружить негативные циклы по отрицательным диагоналям).
- Сложность: O(V3)O(V^3)O(V3). Удобен для плотных графов или когда VVV невелик.
- Выбор алгоритма:
- Если все веса неотрицательны и нужен single-source — Dijkstra (структура куч решает константы).
- Если возможны отрицательные веса и нужен single-source — Bellman–Ford.
- Если нужны все-пары и граф разрежен — Johnson.
- Если все-пары и граф плотный или VVV невелик — Floyd–Warshall.
Краткие сложности (итог):
- Dijkstra: массив — O(V2)O(V^2)O(V2), бинарная куча — O((E+V)log⁡V)O((E+V)\log V)O((E+V)logV), фибоначчиева куча — O(E+Vlog⁡V)O(E+V\log V)O(E+VlogV).
- Bellman–Ford: O(VE)O(VE)O(VE).
- Johnson: O(VE+V⋅TDijkstra)O(VE + V\cdot T_{Dijkstra})O(VE+VTDijkstra ) → с фиб. кучей O(VE+V2log⁡V)O(VE + V^2\log V)O(VE+V2logV).
- Floyd–Warshall: O(V3)O(V^3)O(V3).
Если нужно, могу привести формализованное доказательство с шагами релаксации и полным псевдокодом и/или примеры сравнения на конкретных графах.
11 Ноя в 14:36
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир