Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмы / Referat_Algoritm_Floyda

.doc
Скачиваний:
27
Добавлен:
06.07.2016
Размер:
257.36 Кб
Скачать

Реферат на тему «Алгоритм Флойда».

Выполнил Литвинов Михаил.

Алгоритм Флойда — динамический алгоритм поиска кратчайших путей между всеми парами вершин взвешенного ориентированного графа. Разработан в 1962 году Робертом Флойдом (Robert W. Floyd). Задача, выполняемая алгоритмом, звучит так: в ориентированном графе G=(V, E), необходимо найти для каждой упорядоченной пары вершин (v, w) любой путь от вершины v в вершину w, длина которого минимальна среди всех возможных путей от v к w. В общем случае алгоритм работает как для ориентированных, так и для неориентированных графов, не содержащих циклов отрицательного веса. В случае циклов с отрицательным весом алгоритм будет по-прежнему правильно вычислять пути, но только для тех вершин, которые не могут быть соединены через этот цикл.

В алгоритме Флойда исходный граф представляется в виде матрицы C размера (n * n), задающейся согласно следующим правилам:

- На пересечениях столбцов и строк с одинаковым номером (одна и та же вершина) записываем 0.

- На пересечениях столбцов и строк с разными номерами (различные вершины) при наличии прямого пути между данными вершинами записываем вес данного ребра.

- Если между вершинами нет прямого пути — записываем специальное значение.

В алгоритме идёт активная работа с двумя матрицами: матрицей длин путей T размера (n * n), куда заносятся соответствующие значения из исходной матрицы С и матрица путей H размера также (n * n), в которую заносится пункт назначения, если между вершинами есть прямой путь, и специальное значение — в противном случае.

После инициализации матриц путей и длин путей происходят 3 вложенных цикла обработки: фиксируются 2 вершины (например, j и k) и проверяются все остальные вершины i. Если путь из j в k можно сократить, пройдя через I, матрицы изменяются так, чтобы определять кратчайшие пути.

Пример.

Матрица длин путей:

0

1

2

3

4

0

0

19

18

15

1

19

0

11

18

2

18

0

14

3

15

11

0

15

4

18

14

15

0

Матрица путей:

0

1

2

3

4

0

0

1

2

3

-1

1

0

1

-1

3

4

2

0

-1

2

-1

4

3

0

1

-1

3

4

4

-1

1

2

3

4

I=1:

Матрица длин путей:

0

1

2

3

4

0

0

19

18

15

1

19

0

37

11

18

2

18

37

0

33

14

3

15

11

33

0

15

4

18

14

15

0

Матрица путей:

0

1

2

3

4

0

0

1

0

3

4

1

0

1

-1

3

4

2

0

0

2

0

4

3

0

1

0

3

4

4

-1

1

2

3

4

I=2:

Матрица длин путей:

0

1

2

3

4

0

0

19

18

15

37

1

19

0

37

11

18

2

18

37

0

33

14

3

15

11

33

0

15

4

37

18

14

15

0

Матрица путей:

0

1

2

3

4

0

0

1

2

3

1

1

0

1

0

3

4

2

0

0

2

0

4

3

0

1

0

3

4

4

1

1

2

3

4

I=3:

Матрица длин путей:

0

1

2

3

4

0

0

19

18

15

32

1

19

0

37

11

18

2

18

37

0

33

14

3

15

11

33

0

15

4

32

18

14

15

0

Матрица путей:

0

1

2

3

4

0

0

1

2

3

2

1

0

1

0

3

4

2

0

0

2

0

4

3

0

1

0

3

4

4

2

1

2

3

4

I=4:

Матрица длин путей:

0

1

2

3

4

0

0

19

18

15

30

1

19

0

34

11

16

2

18

34

0

33

14

3

15

11

33

0

15

4

30

16

14

15

0

Матрица путей:

0

1

2

3

4

0

0

3

2

3

3

1

3

1

3

3

3

2

0

0

2

0

4

3

0

1

0

3

4

4

3

3

2

3

4

I=4 (после окончания итерации):

Матрица длин путей:

0

1

2

3

4

0

0

19

18

15

30

1

19

0

30

11

18

2

18

30

0

29

14

3

15

11

29

0

15

4

30

18

14

15

0

Матрица путей:

0

1

2

3

4

0

0

1

2

3

2

1

0

1

0

3

4

2

0

4

2

4

4

3

0

1

4

3

4

4

2

1

2

3

4

Реализация алгоритма на языке C++ для заданной матрицы

(5*5)

#include "stdafx.h"

#include "cstdlib"

int _tmain(int argc, _TCHAR* argv[])

{

int c[5][5] = {

{ 0, 9, 8, 5, INT_MAX },

{ 9, 0, INT_MAX, 1, 8 },

{ 8, INT_MAX, 0, INT_MAX, 4 },

{ 5, 1, INT_MAX, 0, 5 },

{ INT_MAX, 8, 4, 5, 0 } };

int t[5][5];

for (int i = 0; i < 5; i++){

for (int j = 0; j < 5; j++){ t[i][j] = c[i][j]; if (t[i][j] == INT_MAX) h[i][j] = -1; else h[i][j] = j;

}

}

for (int i = 0; i < 5; i++){

for (int j = 0; j < 5; j++){

for (int k = 0; k < 5; k++){

if (i != j && t[j][i] != INT_MAX &&

i != k && t[i][k] != INT_MAX &&

(t[j][k] == INT_MAX || t[j][k] > t[j][i] + t[i][k])){ h[j][k] = h[j][i]; t[j][k] = t[j][i] + t[i][k];

}

}

}

}

return 0;

}

Временная сложность:

В алгоритме присутствуют три вложенных цикла с инструкциями, выполняющимися за 0(1), следовательно, временна сложность алгоритма — О(n3). Кроме того, алгоритм требуется хранение исходной матрицы, а так же матриц путей и длин путей, что даёт сложность О(n2) по памяти.