Алгоритм Флойда

Вход: матрица С[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).