Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика_и_Пр_Бизнес_лекции.doc
Скачиваний:
84
Добавлен:
10.05.2015
Размер:
1.21 Mб
Скачать

10.3.4. Поиск кратчайших путей. Алгоритм Дейкстры

Постановка задачи

Дан взвешенный граф без петель и дуг с отрицательным весом. Найти кратчайшие пути от некоторой вершины с номером k до всех остальных вершин этого графа.

Каждой вершине из массива вершин V сопоставим метку – минимальное известное расстояние от источника (вершины с номером k) до этой вершины. Алгоритм работает пошагово – на каждом шаге алгоритм посещает одну вершину и пытается уменьшить метки. Работа алгоритма завершается, когда все вершины посещены.

Рассмотрим выполнение алгоритма на примере графа, показанного на рис. 5. Пусть требуется найти расстояния от вершины 1 до всех остальных. Все вершины графа помечаются как необработанные: кратчайшие расстояния от вершины 1 до других вершин полагаются равными бесконечности. Расстояние от вершины 1 до самой себя полагается равной 0. На рис. 82 показано начальное состояние графа.

Рис. 8. Начальное состояние графа

На каждом шаге алгоритма используется массив D, в который записываются минимальные известные расстояния от источника до каждой вершины графа. В алгоритме используется также массив S, в котором на каждом шаге отмечаются обработанные вершины. Начальные состояния массивов для графа, изображенного на рис. 8:

Массив D: 0, ∞, ∞, ∞, ∞, ∞

Массив S: false, false, false, false, false, false

В алгоритме используется матрица стоимости, элемент которой c[i][j] равен стоимости дуги: если дуги из вершины i в вершину j не существует, то c[i][j]= ∞, если существует, то c[i][j]=a[i][j]. Здесь a[i][j] элемент матрицы смежности.

На каждом шаге алгоритма посещается вершина, которая не обработана (она отмечена в массиве S как false) и расстояние до которой от источника минимально (на основе данных массива D). Эта вершина помечается в массиве S как обработанная. Далее алгоритм пытается уменьшить метки смежных с выбранной вершиной вершин в массиве D, оценивая для каждой смежной вершины путь от источника через текущую вершину. Если длина нового пути через текущую вершину меньше расстояния, зафиксированного для смежной вершины в массиве D, то соответсвующее значение в массиве D изменяется. Алгоритм заканчивается, когда все вершины помечены как обработанные. В табл. 8 приведены последовательности значений массивов D и S после каждой итерации цикла алгоритма Дейкстры для графа, изображенного на рис. 5.

Таблица 8

Последовательности значений массивов D и S

Итерация

S

D[1]

D[2]

D[3]

D[4]

D[5]

D[6]

1

tfffff

0

7

9

14

2

ttffff

0

7

9

22

14

3

tttfff

0

7

9

20

11

4

tttfft

0

7

9

20

20

11

5

ttttft

0

7

9

20

20

11

6

tttttt

0

7

9

20

20

11

Текст фукции, реализующей алгоритм Дейкстры:

void Dijkstra(int d[ ], int a[][size], int n, int k)

/* d - массив кратчайших путей от к-вершины до каждой вершины, a - матрица смежности, n - количество вершин графа,

k - вершина-источник, size - глобальная константа */

{

int c[size][size]; //матрица стоимости

bool s[size]; //массив обработанных вершин

int dmin, imin; //минимальное расстояние от источника до

//необработанной вершины и номер этой вершины

int i, j; //номера вершин

int m; //количество обработанных вершин

//Заполнение матрицы стоимости

for (i=0; i<=n-1; i++)

for (j=0; j<=n-1; j++)

if (a[i][j]==0 && i!=j)

c[i][j]=1000;

else

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

//Начальное заполнение массива обработанных вершин

for (i=0; i<=n-1; i++)

s[i]=false; //все вершины не посещались

m=0; //нет обработанных вершин

//Начальное заполнение массива известных кратчайших путей

// от k-вершины до других вершин

for (i=1; i<=n-1; i++)

d[i]=100000; //100000 равносильно бесконечному расстоянию

d[k]=0; //источник имеет минимальную метку, с него начинать

//Главный цикл

dmin=0; //чтобы войти в цикл

while (m!=n && dmin!=100000) //цикл закончится когда все

//вершины обработаны (m==n) или нет

// путей к необработанным вершинам

{ //поиск необработанной вершины, расстояние до которой

//минимально

dmin=1000;

for(i=0; i<=n-1; i++)

if(d[i]<dmin && s[i]==false)

{dmin=d[i]; imin=i; }

if(dmin!=100000) //есть пути к необработанным вершинам

{

s[imin]=true; //добавление найденной вершины в s

m++;

//Вычисление кратчайших расстояний от источника

//(вершины k) до смежных с imin вершин

for (j=0; j<=n-1; j++)

if(a[imin][j]!=0&& s[j]==false) //j-смежная и не обработана

if(c[imin][j]+d[imin]<d[j]) //расстояние от источника до j-//вершины через imin-вершину

d[j]=c[imin][j]+d[imin];//замена метки вершины в массиве d

}

}

}