Алгоритм Флойда
Вход: матрица С[1..p,1..p] длин дуг.
Выход: матрица Т[1..p,1..p] длин путей и матрица Н[1..p,1..p] самих путей
for i from 1 to p do
for j from 1 to p do
T[i,j]:=C[i,j] {инициализация}
if C[i,j]=∞ then
H[i,j]:=0 {нет дуги из i в j}
else
H[i,j]:=j {есть дуга из i в j}
end if
end for
end for
for i from 1 to p do
for j from 1 to p do
for k from 1 to p do
if i≠j & T[j,i]≠∞ & i≠k & T[i,k]≠∞ & (T[j,k]=∞VT[j,k]>T[j,i]+T[i,k])
then
H[j,k]:=H[j,i] {запомнить новый путь}
T[j,k]:=T[j,i]+T[i,k] {и его длину}
end if
end for
end for
for j from 1 to p do
if T[j,j]<0 then
stop {нет решения: вершина j входит в цикл отрицательной длины}
end if
end for
end for
Матрица H размера О(р2) хранит информацию обо всех (кратчайших) путях в графе. Заметим, что всего в фафе О(р2) путей, состоящих из О(р) вершин. Таким образом, непосредственное представление всех путей потребовало бы памяти объема О(р3). Экономия памяти достигается за счет интерпретации представления, тоесть динамического вычисления некоторой части информации вместо её хранения в памяти. В данном случае любой конкретный путь <u,v> легко извлекается из матрицы с помощью следующего алгоритма.
w:=u; yield {первая вершина}
while w≠u do
w:=H[w,u]; yield w {следующая вершина}
end while
Если в G есть цикл с отрицательным весом, то решения поставленной задачи не существует, так как можно «накручивать» на этом цикле сколь угодно короткий путь.
Алгоритм Флойда имеет много общего с алгоритмом Уоршала. Покажем по индукции, что после выполнения i-го шага основного цикла по i элементы матриц T[j,k] и H[j,k] содержат, соответственно, длину кратчайшего пути и первую вершину на кратчайшем пути из вершины j в вершину k, проходящем через промежуточные вершины из диапазона 1..i. База: i=0, то есть до начала цикла элементы матриц T и H содержат информацию о кратчайших путях (если таковые есть), не проходящих ни через какие промежуточные вершины. Пусть теперь перед началом выполнения тела цикла на i-том шаге T[j,k] содержит длину кратчайшего пути от j к k, а H[j,k] содержит первую вершину на кратчайшем пути из вершины j в вершину k (если таковой есть). В таком случае, если в результате добавления вершины i к диапазону промежуточных вершин находится более короткий путь (в частности, если это вообще первый найденный путь), то он записывается. Таким образом после окончания цикла, когда i=p, матрицы содержат кратчайшие пути, проходящие через промежуточные вершины 1..p, то есть искомые кратчайшие пути. Алгоритм не всегда выдает решение, поскольку он не всегда существует. Дополнительный цикл по j служит для прекращения работы в случае обнаружения в графе цикла с отрицательным весом.
Алгори́тм Де́йкстры
Алгори́тм Де́йкстры (Dijkstra’s algorithm) — алгоритм на графах, изобретённый нидерландским ученым Э. Дейкстрой в 1959 году. Находит кратчайшее расстояние от одной из вершин графа до всех остальных. Алгоритм работает только для графов без рёбер отрицательного веса. Алгоритм широко применяется в программировании и технологиях, например, его использует протокол OSPF для устранения кольцевых маршрутов. Известен также под названием Сначала Кратчайший Путь (Shortest Path First).