Лекция 9: Графы. Кратчайшие пути в графах

27
Лекция 9: Кратчайшие пути в графах КурносовМихаил Георгиевич к.т .н. доцент Кафедры вычислительных систем Сибирский государственный университет телекоммуникаций и информатики http://www.mkurnosov.net

Upload: mikhail-kurnosov

Post on 15-Jun-2015

598 views

Category:

Education


3 download

TRANSCRIPT

Page 1: Лекция 9: Графы. Кратчайшие пути в графах

Лекция 9:

Кратчайшие пути в графах

Курносов Михаил Георгиевич

к.т.н. доцент Кафедры вычислительных систем

Сибирский государственный университет

телекоммуникаций и информатики

http://www.mkurnosov.net

Page 2: Лекция 9: Графы. Кратчайшие пути в графах

Контроль

2

1. Какова вычислительная сложность обхода графа в глубину

(DFS), если он представлен матрицей смежности?

2. Какова вычислительная сложность обхода графа в глубину

(DFS), если он представлен списками смежности?

3. Какова вычислительная сложность обхода графа в ширину

(BFS), если он представлен матрицей смежности?

4. Какова вычислительная сложность обхода графа в ширину

(BFS), если он представлен списками смежности?

Page 3: Лекция 9: Графы. Кратчайшие пути в графах

Графы

3

� Граф (graph) – это совокупность непустого

множества V вершин и множества E ребер

G = (V, E),

|V| = n, |E| = m,

V = {1, 2, …, n}, E = {(u1, v1), (u2, v2), …, (um, vm)}

Page 4: Лекция 9: Графы. Кратчайшие пути в графах

Поиск кратчайшего пути в графе

4

� Имеется взвешенный граф G = (V, E)

� Каждому ребру (i, j) ∈ E

назначен вес wij

� Заданы начальная вершина s ∈ V

и конечная d ∈ V

� Требуется найти

кратчайший путь (shortest path)

из вершины s в вершину d

Длина пути (path length,

path cost, path weight) –

это сумма весов ребер, входящих в него.

s

(source)

d (destination)

Page 5: Лекция 9: Графы. Кратчайшие пути в графах

Поиск кратчайшего пути в графе

5

� Длина пути (5, 4, 6, 7) =

4 + 6 + 9 = 19

� Длина пути (5, 3, 8, 7) =

3 + 2 + 16 = 21

� Длина пути (5, 3, 4, 6, 7) =

3 + 3 + 6 + 9 = 21

Существуют другие пути?

� (5, 1, 4, 3, 8, 7)

� (5, 2, 3, 8, 7)

� …

s

(source)

d (destination)

Page 6: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры

6

� Алгоритм Дейкстры (Dijkstra’s algorithm, 1959) –

алгоритм поиска кратчайшего пути в графе. Применим

только для графов без ребер отрицательного веса.

� Эдсгер Дейкстра (Edsger Wybe Dijkstra) – нидерландский

ученый (структурное программирование, язык Алгол,

семафоры)

1. Дейкстра Э. Дисциплина программирования = A discipline of

programming. — 1-е изд. — М.: Мир, 1978. — С. 275.

2. Дал У., Дейкстра Э., Хоор К. Структурное программирование =

Structured Programming. — 1-е изд. — М.: Мир, 1975. — С. 247.

Page 7: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

7

1

2

5

3

4

100

10

30

5010

20

60

Пример: найти кратчайший путь из

вершины 1 в вершину 5.

Введем обозначения:

� H – множество посещенных вершин

� D[i] – текущее известное кратчайшее

расстояние от вершины s до вершины i

� prev[i] – номер вершины,

предшествующей i в пути

Page 8: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

8

1

2

5

3

4

100

10

30

5010

20

60

1. Устанавливаем расстояние D[i]

от начальной вершины s до всех

остальных в ∞.

2. Полагаем D[s] = 0.

3. Помещаем все вершины

в очередь Q с приоритетом.

Приоритет вершины i это значение D[i].

0 ∞ ∞ ∞ ∞D[i]

Page 9: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

9

1

2

5

3

4

100

10

30

5010

20

60

4. Запускаем цикл из n итераций.

1. Извлекаем из очереди Q вершину

с минимальным приоритетом –

текущем расстоянием D[v] до s.

2. Помещаем v во множество H

посещенных вершин.

3. Для каждой вершины u смежной с

вершиной v и не включенной в H

корректируем расстояние D[u]

if D[v] + w(v, u) < D[u] then

D[u] = D[v] + w(v, u)

PQueueDecrease(Q, u, D[u])

prev[u] = v

end if

D[2] = 10

D[4] = 30

D[5] = 100

0 10 ∞ 30 100D[i]

11

Page 10: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

10

1

2

5

3

4

100

10

30

5010

20

60

4. Цикл из n итераций.

1. Извлекаем из очереди Q вершину

с минимальным приоритетом –

текущем расстоянием D[v] до s.

2. Помещаем v во множество H

посещенных вершин.

3. Для каждой вершины u смежной с

вершиной v и не включенной в H

корректируем расстояние D[u]

if D[v] + w(v, u) < D[u] then

D[u] = D[v] + w(v, u)

PQueueDecrease(Q, u, D[u])

prev[u] = v

end if

D[3] = 60

0 10 60 30 100D[i]

2

1

2

Page 11: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

11

1

2

5

3

4

100

10

30

5010

20

60

4. Цикл из n итераций.

1. Извлекаем из очереди Q вершину

с минимальным приоритетом –

текущем расстоянием D[v] до s.

2. Помещаем v во множество H

посещенных вершин.

3. Для каждой вершины u смежной с

вершиной v и не включенной в H

корректируем расстояние D[u]

if D[v] + w(v, u) < D[u] then

D[u] = D[v] + w(v, u)

PQueueDecrease(Q, u, D[u])

prev[u] = v

end if

D[3] = 50

D[5] = 90

0 10 50 30 90D[i]

4

1

4

2

Page 12: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

12

1

2

5

3

4

100

10

30

5010

20

60

4. Цикл из n итераций.

1. Извлекаем из очереди Q вершину

с минимальным приоритетом –

текущем расстоянием D[v] до s.

2. Помещаем v во множество H

посещенных вершин.

3. Для каждой вершины u смежной с

вершиной v и не включенной в H

корректируем расстояние D[u]

if D[v] + w(v, u) < D[u] then

D[u] = D[v] + w(v, u)

PQueueDecrease(Q, u, D[u])

prev[u] = v

end if

D[5] = 60

0 10 50 30 60D[i]

3

1

3

2

4

Page 13: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

13

� В массиве D длины кратчайших путей

из вершины 1 во все остальные

� Кротчайший путь из вершины

1 в вершину 5: (1, 4, 3, 5), длина пути: 60

Как восстановить путь?

0 10 50 30 60D[i]

3

1

2

3

4

1

2

5

3

4

100

10

30

5010

20

60

-1 1 4 1 3prev[i]

Page 14: Лекция 9: Графы. Кратчайшие пути в графах

function Dijkstra(G, s, d)

/* Input: G = (V, E), s, d */

/* Output: path, pathlen */

for each i in V \ {s} do

d[i] = Infinity

prev[i] = -1

PQueueInsert(Q, i, d[i])

end for

d[s] = 0

prev[s] = -1

PQueueInsert(Q, s, d[s])

Алгоритм Дейкстры (Dijkstra)

14

Page 15: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

15

for i = 0 to n – 1 do

v = PQueueRemoveMin(Q)

H = H + {v}

for each u in Adj(v) \ H do

if d[v] + w(v, u) < d[u] then

d[u] = d[v] + w(v, u)

PQueueDecrease(Q, u, d[u])

prev[u] = v

end if

end for

end for

Page 16: Лекция 9: Графы. Кратчайшие пути в графах

/* Сохранение пути из s в d */

i = d

pathlen = 1

while i != s do

pathlen = pathlen + 1

i = prev[i]

end while

j = 0

i = d

while i != s do

path[pathlen – j] = i

i = prev[i]

j = j + 1

end while

end function

Алгоритм Дейкстры (Dijkstra)

16

Page 17: Лекция 9: Графы. Кратчайшие пути в графах

Вычислительная сложность алгоритм Дейкстры

17

� Вычислительная сложность алгоритма зависит от двух

факторов:

1) от выбора структуры данных для хранения графа

(матрица смежности, списки смежных вершин)

2) от способа поиска вершины с минимальным

расстоянием D[i] (очередь с приоритетом, линейный

поиск)

Page 18: Лекция 9: Графы. Кратчайшие пути в графах

O(n(logn))

Алгоритм Дейкстры (Dijkstra)

18

function Dijkstra(G, s, d)

/* Input: G = (V, E), s, d */

/* Output: path, pathlen */

for each i in V \ {s} do

d[i] = Infinity

prev[i] = -1

PQueueInsert(Q, i, d[i])

end for

d[s] = 0

prev[s] = -1

PQueueInsert(Q, s, d[s])

Page 19: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

19

for i = 0 to n – 1 do

v = PQueueRemoveMin(Q)

H = H + {v}

for each u in Adj(v) \ H do

if d[v] + w(v, u) < d[u] then

d[u] = d[v] + w(v, u)

PQueueDecrease(Q, u, d[u])

prev[u] = v

end if

end for

end for

O(nlogn + mlogn)

Page 20: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

20

/* Сохранение пути из s в d */

pathlen = 1

while i != s do

pathlen = pathlen + 1

i = prev[i]

end while

j = 0

i = d

while i != s do

path[pathlen – j] = i

i = prev[i]

j = j + 1

end while

end function

O(n)

O(n)

Page 21: Лекция 9: Графы. Кратчайшие пути в графах

int search_spath_dijkstra(struct graph *g,

int s, int d, int *path, int *pathlen)

{

int *dist, *prev, *color;

int n, i, j, v, distance, dnew;

n = g->nvertices;

dist = malloc(sizeof(*dist) * n);

prev = malloc(sizeof(*prev) * n);

color = malloc(sizeof(*color) * n);

for (i = 0; i < n; i++) {

dist[i] = INT_MAX;

prev[i] = -1;

color[i] = 0;

}

dist[s - 1] = 0;

Алгоритм Дейкстры (Dijkstra)

21

Page 22: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

22

for (i = 0; i < n; i++) {

/* Find v with minimal dist[j] */

v = -1;

for (j = 0; j < n; j++) {

if (color[j] == 0 && (v == -1 ||

dist[j] < dist[v]))

{

v = j;

}

}

color[v] = 1;

Page 23: Лекция 9: Графы. Кратчайшие пути в графах

for (j = 0; j < n; j++) {

if (color[j] > 0 ||

graph_get_edge(g, v + 1, j + 1) == 0)

{

continue;

}

dnew = dist[v] +

graph_get_edge(g, v + 1, j + 1);

if (dnew < dist[j]) {

dist[j] = dnew;

prev[j] = v;

}

}

} /* end for i */

Алгоритм Дейкстры (Dijkstra)

23

Page 24: Лекция 9: Графы. Кратчайшие пути в графах

/* Number of vertices in shortest path */

j = 1;

for (i = d - 1; i != s - 1; i = prev[i])

j++;

*pathlen = j;

/* Copy shortest path */

for (i = d - 1; i != s - 1; i = prev[i])

path[--j] = i + 1;

path[0] = s;

distance = dist[d - 1];

free(color);

free(prev);

free(dist);

return distance;

}

Алгоритм Дейкстры (Dijkstra)

24

Page 25: Лекция 9: Графы. Кратчайшие пути в графах

Алгоритм Дейкстры (Dijkstra)

25

int main()

{

struct graph *g;

int *path, pathlen;

int i, d;

g = graph_create(5);

graph_set_edge(g, 1, 2, 10);

graph_set_edge(g, 1, 4, 30);

graph_set_edge(g, 1, 5, 100);

graph_set_edge(g, 2, 3, 50);

graph_set_edge(g, 3, 4, 20);

graph_set_edge(g, 3, 5, 10);

graph_set_edge(g, 4, 5, 60);

1

2

5

3

4

100

10

30

5010

20

60

Page 26: Лекция 9: Графы. Кратчайшие пути в графах

path = malloc(sizeof(*path) * 5);

d = search_spath_dijkstra(g, 1, 5,

path, &pathlen);

printf("Shortest path %d:\n", d);

for (i = 0; i < pathlen; i++) {

printf("%d\n", path[i]);

}

free(path);

graph_free(g);

return 0;

}

Алгоритм Дейкстры (Dijkstra)

26

Page 27: Лекция 9: Графы. Кратчайшие пути в графах

Задание

27

1. Оценить трудоемкость по памяти алгоритма Дейкстры

в следующих случаях:

o при использовании матрицы смежности

и двоичной кучи;

o при использовании списков смежности

и двоичной кучи

2. Алгоритм Беллмана — Форда

3. Алгоритм Флойда — Уоршелла