3.2 Задача знаходження найкоротших шляхів
Задачі подібного типу виникають при синтезі алгоритмів багатошляхової маршрутизації, коли повідомлення, що поступають у комп’ютерну мережу розбиваються на окремі пакети.
У цьому випадку приходимо до загальної задачі знаходження найкоротших шляхів, тобто знаходження найкоротших шляхів між всіма парами вершин орієнтованого графа (орграфа). Більш строге формулювання цієї задачі наступне: заданий орієнтований граф , кожному ребру цього графа співставлена невід’ємна вартість (ваги ребер) . Тоді під довжиною шляху будемо розуміти суму всіх ваг ребер орієнтованого графа, які ведуть із вершини до вершини .
Загальна задача знаходження найкоротшого шляху полягає у знаходженні для кожної упорядкованої пари вершин будь-якого шляху від вершини до вершини , довжина якого мінімальна серед всіх можливих шляхів від до . Алгоритм розв’язку сформованої задачі носить назву алгоритму Флойда (R. W. Floyd). Для визначеності допустимо, що всі вершини графа послідовно пронумеровані ві 1 до . Алгоритм Флойда використовує матрицю розміром , в яку заносяться довжини найкоротших шляхів. На початку роботи алгоритму для всіх . Якщо вершини та не з’єднані між собою, то . Кожний діагональний елемент матриці дорівнює нулю, тобто .
Над матрицею виконується ітерацій. Після -ої ітерації елемент матриці набуває значення найменшої довжини шляху із вершини до вершини , який не проходить через вершини з номером більшим за . Іншими словами, між кінцевими вершинами та можуть знаходитись тільки вершини, номери яких не більше .
На -ій ітерації для обчислення значень елементів матриці використовується наступна формула:
, (3.1)
де нижній індекс позначає значення елемента матриці після -ої ітерації. Графічна інтерпретація формули (3.1) показана на рис. 3.3.
Рисунок 3.3 – Включення вершини у шлях від до
Процедура, яка реалізує алгоритм Флойда буде наступною:
FloydPath
n – розмір матриці А
1 for i=1 to n
2 for j=1 to n
3 A(i,j)=C(i,j)
4 end for
5 end for
6 for i=1 to n
7 A(i,j)=0
8 end for
9 for k=1 to n
10 for i=1 to n
11 for j=1 to n
12 if A(i,k)+ A(k,j)< A(i,j)
13 then A(i,j)= A(i,k)+ A(k,j)
14 end if
15 end for
16 end for
17 end for
Час виконання алгоритму FloydPath має порядок , оскільки вона вміщує вкладені один в одного три цикли.
У ситуації, коли необхідно визначити найдешевший шлях із одної вершини до іншої, можна в процедуру FloydPath ввести ще одну матрицю , в якій елемент вміщує вершину , отриману при знаходженні найменшого значення . Якщо , то найкоротший шлях із вершини до вершини утворює тільки одна дуга .
Модифікована версія алгоритму Флойда, яка дає змогу визначати найкоротший шлях наведена нижче.
ModifiedFloydPath
n – розмір матриці А
1 for i=1 to n
2 for j=1 to n
3 A(i,j)=C(i,j)
4 P(i,j)=0
5 end for
6 end for
7 for i=1 to n
8 A(i,j)=0
9 end for
10 for k=1 to n
11 for i=1 to n
12 for j=1 to n
13 if A(i,k)+ A(k,j)< A(i,j)
14 then A(i,j)= A(i,k)+ A(k,j)
15 P(i,j)=k
16 end if
17 end for
18 end for
19 end for
Для індикації послідовності вершин, які визначають найкоротший шлях від вершини до вершини , викликається процедура Path(i,j), псевдокод якої має наступний вигляд
Path(i,j)
1 k=P(i,j)
2 if k=0
3 return
4 path(i,k)
5 writeln(k)
6 path(i,k)
7 end if