46
1 Wyklad 9 Znajdowanie najlepszej drogi

9 znajdowanie drogi - kolos.math.uni.lodz.plkolos.math.uni.lodz.pl/~archive/Algorytmy i struktury danych 2... · Algorytm Dijkstry – uogólnienie BFS. 15 Algorytm Bellmana-Forda

Embed Size (px)

Citation preview

1

Wykład 9

Znajdowanie

najlepszej drogi

2

Algorytmy znajdowania najkrótszych ścieżek

� Właściwości najkrótszych ścieżek

� Algorytm Bellmana-Forda

� Algorytm Dijsktry

Literatura

– Cormen, Leiserson, Rivest, “Wprowadzenie do algorytmów”, rozdz. 25

3

Grafy z wagami - powtórzenie

� Grafem z wagami nazywamy graf, dla którego każdej krawędzi

przypisana jest waga (koszt): w(vi, vj) > 0.

� Każdy graf może być traktowany jako graf z wagami – jeśli przyjąć wagę

1 dla każdej krawędzi. Dodatkowo jeśli wierzchołki nie są połączone to

można przyjąć, że krawędź łącząca je (nieistniejąca) ma wagę ∞.

7

1 2 3

4 5 6

4

2

8

1 5 Koszt ścieżki = suma kosztów

krawędzi ją tworzących:

( ) ( )∑k

1=ii1i v,vw=pw

4

Przykład grafu z wagami

1

2

10

5

2 3

4 6

9

7

s

a b

c d

5

Dwie podstawowe własności dla najkrótszych ścieżek

Nierówność trójkąta

niech G=(V,E) będzie skierowanym grafem z wagami, w: E ���� R funkcją

kosztu, a s∈∈∈∈V wierzchołkiem początkowym. Wtedy dla każdej krawędzi

e=(u,v)∈∈∈∈E:

δ(s,v) ≤ δ(s,u) + w(u,v)

Struktura optymalnej ścieżki

niech p = <v1, .. vk> będzie najkrótszą ścieżką pomiędzy v1 i vk. Wtedy jej

podścieżka pij = <vi, .. vj>, dla 1 ≤ i,j ≤ k, jest najkrótszą ścieżka pomiędzy vi

i vj.

6

Krawędzie o ujemnych wagach

� W niektórych zadaniach mogą pojawić się koszty ujemne.

Najkrótsze ścieżki są dobrze zdefiniowane tylko dla zadań z

nieujemnymi kosztami ścieżek – jeśli dopuścimy koszty ujemne

każda droga może być pomniejszona poprzez dodanie cyklu o

wartości ujemnej

� Można dopuścić ujemne wagi, ale nie można cykli o koszcie

ujemnym (w przykładzie a->b->c->a ma koszt -1)!

-5

1 3

a b c

10

c

-1

7

Najkrótsze drogi, a cykle

� Najkrótsza ścieżka pomiędzy dwoma dowolnymi węzłami nie zawiera

cykli.

� Reprezentacja najkrótszych ścieżek pomiędzy wybranym węzłem, a

wszystkimi pozostałymi jest taka sama jak dla drzewa (podgrafu

poprzedników) w BFS (breath-first tree):

= (Vπ

,Eπ) takie, że V

π= {v∈∈∈∈V: π[v] ≠ null}∪∪∪∪{s}

i Eπ

= {(π[v],v), v∈∈∈∈V –{s}}

� Udowodnimy, że drzewo BFS jest drzewem najkrótszych ścieżek z

korzeniem w wybranym węźle.

8

Przykład drzewa najkrótszych ścieżek – 1

6

6

3

5

2 1

2 7

4

3

s

a b

c d

3 9

0

5 11

9

Przykład drzewa najkrótszych ścieżek – 2

6

6

3

5

2 1

2 7

4

3

s

a b

c d

3 9

0

5 11

10

Metoda kolejnych przybliżeń

� Podobnie, jak dla BFS (dla grafów bez wag) przechowujemy etykietę,

która jest kolejnym przybliżeniem kosztu najlepszej drogi z s do v.

� Początkowo, dist[s] = 0 oraz dist[v] = ∞ dla wszystkich v ≠ s, π[v] = null.

� Dla kolejnych iteracji algorytmu: dist[v] ≥ δ(s,v).

� I na koniec: dist[v] = δ(s,v) i (π[v],v) ∈∈∈∈ Eπ

11

Relaksacja

� Proces relaksacji krawędzi (inaczej osłabiania ograniczeń) (u,v)

polega na sprawdzaniu, czy możemy poprawić najlepszą ścieżkę z s

do v jeśli droga będzie wiodła przez wierzchołek u.

Relax(u,v)

if dist[v] > dist[u] + w(u,v)

then dist[v] dist[u] + w(u,v)

π[v] u

12

Własności relaksacji

Nierówność trójkąta

∀e = (u,v)∈∈∈∈E: δ(s,v) ≤ δ(s,u) + w(u,v)

Własność ograniczenia górnego

∀v∈∈∈∈V: dist[v] ≥ δ(s,v)

Własność braku drogi

jeżeli nie istnieje droga z s do v, to: dist[v]= δ(s,v) = ∞

13

Własności relaksacji

Własność zbieżności

jeżeli s ����u����v jest najkrótszą ścieżką w G dla pewnego u i v, oraz dist[u]=

δ(s,u) zawsze przed wykonaniem relaksacji krawędzi (u,v), to również

dist[v]= δ(s,v) zawsze po relaksacji.

Własność relaksacji ścieżki

niech p = <v0, .. vk> będzie najkrótszą ścieżką pomiędzy v0 i vk. Jeżeli

relaksacja krawędzi jest przeprowadzana w kolejności (v0, v1), (v1, v2), …

(vk-1, vk), to dist[vk]= δ(s,vk).

.

14

Algorytmy wyznaczania najkrótszych ścieżek

1. Algorytm Bellmanna-Forda

2. Algorytm Dijkstry – uogólnienie BFS

15

Algorytm Bellmana-Forda – przegląd

� Dopuszcza ujemne wagi. Jeśli napotkany zostaje cykl o wadze ujemnej

zwracane jest “negative cycle”.

� Idea:

– Istnieje najlepsza droga od s do każdego innego wierzchołka nie

zawierająca cykli dodatnich (cykle muszą zostać wyeliminowane).

– Maksymalna ilość krawędzi w takiej ścieżce wynosi |V|–1, ponieważ

w ścieżce bez cykli może być co najwyżej |V| wierzchołków.

⇒ wystarczy sprawdzać ścieżki do |V|–1 wierzchołków.

16

Algorytm Bellmana-Forda

( )

( )

( )

[ ] [ ] ( ) cycle"negative"return,if

,każdegofor

][

),(][][

,dist[u]dist[v]ifdo

,każdegofor

1to1for

),(Initialize

),Ford(-Bellman

vuwudvdist

Evu

uv

vuwudistvdist

vuw

Evu

|V|i

sG

sG

+>

+

+>

−←

π

17

Przykład: algorytm Bellmana-Forda (1)

5

9

6

7

8

-3

2

s

a b

c d

0

∞ ∞

∞ ∞

-2

7-4

(a,b)

(a,c)

(a,d)

(b,a)

(c,b)

(c,d)

(d,s)

(d,b)

(s,a)

(s,b)

18

Przykład: algorytm Bellmana-Forda (2)

5

9

6

7

8

-3

2

s

a b

c d

0

6 ∞

7 ∞

-2

7-4

(a,b)

(a,c)

(a,d)

(b,a)

(c,b)

(c,d)

(d,s)

(d,b)

(s,a)

(s,c)

19

Przykład: algorytm Bellmana-Forda (3)

5

9

6

7

8

-3

2

s

a b

c d

0

6 4

7 2

-2

7-4

(a,b)

(a,c)

(a,d)

(b,a)

(c,b)

(c,d)

(d,s)

(d,b)

(s,a)

(s,c)

11

20

Przykład: algorytm Bellmana-Forda (4)

5

9

6

7

8

-3

2

s

a b

c d

0

2 4

7 2

-2

7-4

(a,b)

(a,c)

(a,d)

(b,a)

(c,b)

(c,d)

(d,s)

(d,b)

(s,a)

(s,b)

6

21

Przykład: algorytm Bellmana-Forda (5)

5

9

6

7

8

-3

2

s

a b

c d

0

2 4

7 -2

-2

7-4

(a,b)

(a,c)

(a,d)

(b,a)

(c,b)

(c,d)

(d,s)

(d,b)

(s,a)

(s,b)

2

22

Własności algorytmu Bellmana-Forda

� Przy pierwszym przejściu krawędzi – tylko sąsiedzi s są rozpatrywani

(ścieżki o długości 1). Znajdujemy wszystkie najlepsze ścieżki do tych

węzłów.

� Przy drugim przejściu – znajdujemy najlepsze drogi o długości 2.

� Po |V|-1 przejściach, sprawdzone zostały wszystkie możliwości.

� Cel: staramy się poprawić ścieżkę z poprzedniego przebiegu jeśli jest

to możliwe, bez tworzenia ujemnego cyklu.

23

Złożoność algorytmu Bellmana-Forda

� odwiedzenie |V|–1 wierzchołków ���� O(|V|)

� Przeprowadzanie relaksacji dla wszystkich krawędzi ���� O(|E|)

� Łącznie, O(|V|.|E|) dla czasu i O(|V|+|E|) dla pamięci.

24

Algorytm Bellmana-Forda dla DAG

Dla skierowanych grafów acyklicznych (Directed Acyclic Graphs - DAG),

wystarczające jest relaksacji O(|V|+|E|) – jeśli wierzchołki są

odwiedzane w porządku topologicznym (jeśli graf zawiera krawędź

(u,v) to wierzchołek u występuje przed wierzchołkiem v):

DAG-Shortest-Path(G)

1. Posortuj topologicznie wierzchołki grafu G

2. Inicjuj G (dist[v] i π(v)) z wierzchołkiem s jako źródłem.

3. for każdego wierzchołka u do

4. for każdego wierzchołka v połączonego z u do

5. Relax(u,v)

25

Przykład: algorytm Bellmana-Forda dla DAG (1)

5a s

0 ∞

2b

7c

-1d

-2e

6 1

34

2

Wierzchołki są posortowane od lewej do prawej

26

Przykład: algorytm Bellmana-Forda dla DAG (2)

5a s

0 ∞

2b

7c

-1d

-2e

6 1

34

2

27

Przykład: algorytm Bellmana-Forda dla DAG (3)

5a s

0 ∞

2b

27

c

6

-1d

-2e

6 1

34

2

28

Przykład: algorytm Bellmana-Forda dla DAG(4)

5a s

0 ∞

2b

27

c

6

-1d

6

-2e

4

6 1

34

2

29

Przykład: algorytm Bellmana-Forda dla DAG (5)

5a s

0 ∞

2b

27

c

6

-1d

5

-2e

4

6 1

34

2

30

Przykład: algorytm Bellmana-Forda dla DAG (6)

5a s

0 ∞

2b

27

c

6

-1d

5

-2e

3

6 1

34

2

31

Przykład: algorytm Bellmana-Forda dla DAG (7)

5a s

0 ∞

2b

27

c

6

-1d

5

-2e

3

6 1

34

2

32

Poprawność algorytmu Bellmana-Forda dla DAG

Własność relaksacji ścieżki

niech p = <v0, .. vk> będzie najkrótszą ścieżką pomiędzy v0 i vk. Jeżeli

relaksacja ścieżek jest przeprowadzana w kolejności

(v0, v1), (v1, v2), … (vk-1, vk), to dist[vk]= δ(s,vk).

Dla DAG, mamy dobry porządek wierzchołków!

Stąd złożoność: O(|V|+|E|).

33

Algorytm Dijkstry - przegląd

Idea: robimy to samo co przy BFS dla grafów bez wag, z 2 różnicami:

– Korzystamy z funkcji kosztu jako odległości

– Korzystamy z kolejki priorytetowej zamiast zwykłej kolejki.

34

Algorytm BFS

BFS(G, s)

dist[s] = 0; π[s] = null

for dla wszystkich wierzchołków u z V – {s} do

label[u] not_visited; dist[u] = ∞; π[u] = null

EnQueue(Q,s)

while Q is not empty do

u DeQueue(Q)

for każdego v, który jest sąsiadem u do

if label[v] = not_visited then

dist[v] dist[u] + 1; π[v] u

EnQueue(Q,v)

label[u] visited

35

Przykład: algorytm BFS

s

a b

c d

36

Przykład: algorytm Dijkstry

1

2

10

5

9

7

s

a b

c d

0

642 3

37

Algorytm Dijkstry

Dijkstra(G, s)

dist[s] = 0; π[u] = null

for dla wszystkich wierzchołków u w V – {s} do

label[u] not_visited; dist[u] = ∞; π[u] = null

Q s

while Q is not empty do

u Extract-Min(Q)

for każdego v, sąsiada of u do

if label[v] = not_visited then

if d[v] > d[u] + w(u,v)

then d[v] d[u] + w(u,v); π[v] = u

Insert-Queue(Q,v)

label[u] = visited

38

Przykład: algorytm Dijkstry (1)

1

2

10

5

9

7

s

a b

c d

0

∞ ∞

∞ ∞

642 3

39

Przykład: algorytm Dijkstry (2)

1

2

10

5

9

7

s

a b

c d

0

10 ∞

5 ∞

642 3

40

Przykład: algorytm Dijkstry (3)

1

2

10

5

9

7

s

a b

c d

0

8 14

5 7

642 3

41

Przykład: algorytm Dijkstry (4)

1

2

10

5

9

7

s

a b

c d

0

8 13

5 7

642 3

42

Przykład: algorytm Dijkstry (5)

1

2

10

5

9

7

s

a b

c d

0

8 9

5 7

642 3

43

Przykład: algorytm Dijkstry (6)

1

2

10

5

9

7

s

a b

c d

0

8 9

5 7

642 3

44

Poprawność algorytmu Dijkstry

Twierdzenie: po zakończeniu algorytmu Dijkstry, dla każdego

wierzchołka v∈∈∈∈V, mamy dist[v] = δ(s,v).

Definicja: ścieżkę z s do v będziemy nazywać specjalną jeśli jest to

najkrótsza ścieżka, dla której wszystkie wierzchołki (być może poza

v) należą do S – zbiór wierzchołków, dla których obliczono już

najlepsze ścieżki z s.

Lemmat: na koniec każdej iteracji pętli while, zachodzą dwie własności:

1. Dla każdego w∈S, dist[w] jest długością najkrótszej ścieżki z s do w.

2. Dla każdego w∈V–S, dist(w) jest długością najkrótszej specjalnej

ścieżki z s do w.

Twierdzenie zachodzi, gdy S = V.

45

Złożoność algorytmu Dijkstry

� Algorytm przeprowadza |V| operacji Get-Min oraz |E| operacji EnQueue.

� Jeśli kolejka priorytetowa jest implementowana jako kopiec (heap),

wstawianie zabiera O(lg|V|) a Get-Min – O(lg(|V|). Całkowity czas:

O(|V|lg|V |) + O(|E|lg|V|) = O(|E|lg|V|)

� Jeśli |E| = O(|V|2), nie dostajemy optymalności. W tym wypadku,

przeprowadzamy wielokrotnie więcej operacji wstawiania, niż

wyjmowania.

� Rozwiązanie: implementacja tablicowa! Wstawianie zajmujeO(1)

i Get-Min O(|V|) ����O(|V|2) + O(|E|) = O(|V|2)

co jest lepsze niż dla niż dla kopca póki |E| jest O(|V|2/lg (|V|)).

46

Podsumowanie

� Rozwiązanie problemu najkrótszych ścieżek dla grafu odbywa się za

pomocą relaksacji, opartej na nierówności trójkąta: dla każdej

krawędzi e=(u,v)∈∈∈∈E:

δ(s,v) ≤ δ(s,u) + w(u,v)

� Mamy dwa algorytmy rozwiązujące ten problem:

– Bellmana-Forda: dla każdego wierzchołka, relaksacja po wierzchołkach.

Zajmuje to czas O(|E|.|V|). Działa dla grafów bez cykli ujemnych.

– Dijkstry: podobny do BFS, działa w czasie O(|E|lg|V|).