Алгоритм Флойда
Формулировка задачи. Дан непустой взвешенный граф с произвольными весами ребер. Требуется найти кратчайшие длины путей между всеми парами вершин графа, если в графе нет циклов отрицательной длины или обнаружить наличие таких циклов.
Алгоритм
Инициализация
структур данных
Построим матрицу D0 размерности |V| x |V|, элементы которой (обозначим из v) определяются по правилу:
Основная
часть алгоритма:
§ Выполнять цикл, завершение которого наступает по выполнению одного из двух условий: либо количество шагов цикла равно V, либо был обнаружен цикл отрицательной длины. Шаги цикла нумеруются с нуля. Шаг цикла будем обозначать переменной m.
o Строится матрица с индексом равным номеру шага, обозначим его через
m, в которой элементы определяются через элементы матрицы
предыдущего шага по следующим формулам: dijm+1=min{dijm, di(m+1)m + d(m+1)jm}, где i<>j; diim+1=0.
o Если
dimm + dmim < 0 для какого-то i, то в графе
существует цикл (контур) отрицательной длины, проходящий через вершину vi;
По завершению работы данного алгоритма, элементы матрицы равны длинам кратчайших путей между соответствующими вершинами.
Поиск путей
Если требует найти сами пути, то перед началом работы алгоритма построим матрицу P с начальными значениями элементов pij=i. Каждый раз, когда на шаге (1) значение dijm+1 будет уменьшаться в соответствии с (*) (т.е. когда di(m+1)m + d(m+1)jm<dijm), выполним присваивание pij:=p(m+1)j. В конце работы алгоритма матрица P будет определять кратчайшие пути между всеми парами вершин: значение pij будет равно номеру предпоследней вершины в пути между i и j (либо pij=i, если путь не существует).
Примечаниe: если граф - неориентированный, то все матрицы Dm являются симметричными, поэтому достаточно вычислять элементы, находящиеся только выше (либо только ниже) главной диагонали.