Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры ОАиП(теория).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
151.01 Кб
Скачать

45.Алгоритм Флойда поиска кратчайших расстояний в графе.

Алгоритм Флойда — Уоршелла — динамический алгоритм для нахождения кратчайших расстояний между всеми вершинами взвешенного ориентированного графа. Разработан в 1962 году Робертом Флойдом и Стивеном Уоршеллом.

Пусть граф задан матрицей смежности A[N][N] по следующему правилу: A[i][j] равно

- 0, если i равно j;

- бесконечности (очень большому числу), если из i в j нет ребра;

- весу ребра между вершинами i и j в остальных случаях.

Алгоритм Флойда делает N итераций, после i-й итерации матрица А будет содержать длины кратчайших путей между любыми двумя парами вершин при условии, что эти пути проходят через вершины от первой до i-й. На каждой итерации перебираются все пары вершин и путь между ними сокращается при помощи i-й вершины. Ниже приведен код основного фрагмента программы и иллюстрация:

Таким образом будет получена матрица длин кратчайших путей из каждой вершины в каждую (заметим, что алгоритм очень похож на алгоритм построения транзитивного замыкания графа). Если между двумя вершинами нет пути, в соответствующей ячейке матрицы A будет стоять бесконечность.

Для определения кратчайших путей (т.е. вершин, через которые проходит кратчайший путь) приходится воспользоваться дополнительным массивом C[N][N]. Существует несколько способов заполнения массива C и определения кратчайшего пути:

1. Изначально C[i][j] = i, при изменении значения

A[j][k] = A[j][i] + A[i][k]

производится также изменение значения C[j][k]:

C[j][k] = C[i][k].

В этом случае значение массива C[j][k] после окончания алгоритма будет указывать вершину, предпоследнюю в пути от j к k, и восстановление пути будет возможно сделать простым циклом;

2. Изначально C[i][j] = -1, при изменении значения

A[j][k] = A[j][i] + A[i][k]

производится также изменение значения C[j][k]:

C[j][k] = i.

В этом случае значение массива C[j][k] после окончания алгоритма будет указывать одну из вершин, через которую проходит путь от j к k, и восстановление пути будет возможно сделать простым циклом либо при помощи рекурсивной функции.

Реализация:

type

Graph = array[1..nn,1..nn] of integer;

Procedure Floyd(var a, p: graph);

var i,j,k: integer;

c: graph;

begin

//A - матрица содержащая кратчайшие пути.

//P - матрица, сохраняющая маршруты.

Randomize;

for i:=1 to nn do

for j:=1 to nn do

c[i,j] := random(100);

for i:=1 to nn do

for j:=1 to nn do

begin

a[i,j]:=c[i,j];

p[i,j]:=0;

end;

for i:=1 to nn do a[i,i]:=0;

for k:=1 to nn do

for i:=1 to nn do

for j:=1 to nn do

if (a[i,k]+a[k,j] < a) then

begin

a[i,j]:=a[i,k]+a[k,j];

p[i,j]:=k;

end;

end;