На вход подаётся ориентированный взвешенный граф с отрицательными весами, но без отрицательных циклов. Предложите и обоснуйте алгоритм поиска кратчайших путей от одной вершины до всех остальных, проанализируйте сложность и ограничения
Решение: алгоритм Беллмана—Форда. Алгоритм (кратко) - Инициализация: для всех вершин vvv положить d[v]=∞d[v]=\inftyd[v]=∞, d[s]=0d[s]=0d[s]=0 (источник sss). - Повторить V−1V-1V−1 раз: для каждой дуги (u→v)(u\to v)(u→v) с весом w(u,v)w(u,v)w(u,v) выполнить релаксацию если d[u]+ w(u,v)<d[v]d[u]+\;w(u,v)<d[v]d[u]+w(u,v)<d[v], то присвоить d[v]=d[u]+w(u,v)d[v]=d[u]+w(u,v)d[v]=d[u]+w(u,v). - Проверка отрицательного цикла: если после ещё одной итерации найдётся дуга с d[u]+w(u,v)<d[v]d[u]+w(u,v)<d[v]d[u]+w(u,v)<d[v], то существует достижимый от sss отрицательный цикл. Обоснование корректности - Любой кратчайший путь без циклов содержит не более V−1V-1V−1 ребра. После kkk-й итерации алгоритма корректно вычислены длины всех кратчайших путей, состоящих не более чем из kkk ребер. Поэтому после V−1V-1V−1 итераций получаем финальные кратчайшие расстояния при отсутствии отрицательных циклов. - Проверка дополнительной релаксации обнаруживает отрицательный цикл, достижимый из sss. Сложность и память - Временная сложность: O(VE)O(VE)O(VE) (в худшем случае выполняется V−1V-1V−1 проход по всем EEE дугам). - Память: O(V+E)O(V+E)O(V+E) для хранения графа и массива расстояний. Оптимизации и альтернативы - Ранний выход: если в проходе не было ни одного обновления, можно прервать раньше — это улучшает время на многих реальных графах. - SPFA (очередь релаксаций) часто быстрее на практике, но не гарантирует лучшей границы в худшем случае и может деградировать (нестабильно для некоторых входов). - Если граф ацикличен (DAG), тогда можно получить все кратчайшие пути за O(V+E)O(V+E)O(V+E) с помощью топологической сортировки и одного прохода релаксаций. - Если нужна многоточечная (all-pairs) задача, можно применить алгоритм Джонсона: сначала Bellman–Ford для потенциалов (удалить отрицательные веса), затем VVV запусков Dijkstra — общая сложность O(VE+V (E+VlogV))O(VE + V\,(E+V\log V))O(VE+V(E+VlogV)) в зависимости от реализации. Ограничения - Беллман–Форд работает корректно при отрицательных весах, но медленнее, чем Dijkstra при неотрицательных весах. - При больших плотных графах (VVV и EEE большие) временные затраты могут быть значительными. - SPFA — практическая альтернатива, но с ненадёжными гарантиями в худшем случае. Краткий вывод: для single-source в ориентированном графе с отрицательными весами и без отрицательных циклов рекомендован и обоснован алгоритм Беллмана—Форда (корректность и обнаружение отрицательных циклов, сложность O(VE)O(VE)O(VE)).
Алгоритм (кратко)
- Инициализация: для всех вершин vvv положить d[v]=∞d[v]=\inftyd[v]=∞, d[s]=0d[s]=0d[s]=0 (источник sss).
- Повторить V−1V-1V−1 раз: для каждой дуги (u→v)(u\to v)(u→v) с весом w(u,v)w(u,v)w(u,v) выполнить релаксацию
если d[u]+ w(u,v)<d[v]d[u]+\;w(u,v)<d[v]d[u]+w(u,v)<d[v], то присвоить d[v]=d[u]+w(u,v)d[v]=d[u]+w(u,v)d[v]=d[u]+w(u,v).
- Проверка отрицательного цикла: если после ещё одной итерации найдётся дуга с d[u]+w(u,v)<d[v]d[u]+w(u,v)<d[v]d[u]+w(u,v)<d[v], то существует достижимый от sss отрицательный цикл.
Обоснование корректности
- Любой кратчайший путь без циклов содержит не более V−1V-1V−1 ребра. После kkk-й итерации алгоритма корректно вычислены длины всех кратчайших путей, состоящих не более чем из kkk ребер. Поэтому после V−1V-1V−1 итераций получаем финальные кратчайшие расстояния при отсутствии отрицательных циклов.
- Проверка дополнительной релаксации обнаруживает отрицательный цикл, достижимый из sss.
Сложность и память
- Временная сложность: O(VE)O(VE)O(VE) (в худшем случае выполняется V−1V-1V−1 проход по всем EEE дугам).
- Память: O(V+E)O(V+E)O(V+E) для хранения графа и массива расстояний.
Оптимизации и альтернативы
- Ранний выход: если в проходе не было ни одного обновления, можно прервать раньше — это улучшает время на многих реальных графах.
- SPFA (очередь релаксаций) часто быстрее на практике, но не гарантирует лучшей границы в худшем случае и может деградировать (нестабильно для некоторых входов).
- Если граф ацикличен (DAG), тогда можно получить все кратчайшие пути за O(V+E)O(V+E)O(V+E) с помощью топологической сортировки и одного прохода релаксаций.
- Если нужна многоточечная (all-pairs) задача, можно применить алгоритм Джонсона: сначала Bellman–Ford для потенциалов (удалить отрицательные веса), затем VVV запусков Dijkstra — общая сложность O(VE+V (E+VlogV))O(VE + V\,(E+V\log V))O(VE+V(E+VlogV)) в зависимости от реализации.
Ограничения
- Беллман–Форд работает корректно при отрицательных весах, но медленнее, чем Dijkstra при неотрицательных весах.
- При больших плотных графах (VVV и EEE большие) временные затраты могут быть значительными.
- SPFA — практическая альтернатива, но с ненадёжными гарантиями в худшем случае.
Краткий вывод: для single-source в ориентированном графе с отрицательными весами и без отрицательных циклов рекомендован и обоснован алгоритм Беллмана—Форда (корректность и обнаружение отрицательных циклов, сложность O(VE)O(VE)O(VE)).