Podstawowe algorytmy grafowe i ich zastosowania Autor projektu: dr Andrzej Mróz (UMK) Projekt pn. Wzmocnienie potencjaªu dydaktycznego UMK w Toruniu w dziedzinach matematyczno-przyrodniczych realizowany w ramach Poddziaªania 4.1.1 Programu Operacyjnego Kapitaª Ludzki 1 / 48
Przeszukiwanie grafu Przeszukiwanie (przegl danie) grafu = systematyczne przechodzenie wzdªu» jego kraw dzi w celu odwiedzenia wszystkich wierzchoªków. Sªu»y m.in. do zbierania informacji o strukturze grafu. Algorytmy grafowe cz sto zaczyna si od przeszukania wej±ciowego grafu. Wiele bardziej zaawansowanych algorytmów grafowych jest modykacj podstawowych algorytmów przeszukiwania. 2 / 48
Przeszukiwanie grafu Dwie metody przeszukiwania grafu: w gª b (ang. depth-rst search, DFS), wszerz (ang. breadth-rst search, BFS). W obu metodach b dziemy iterowa po s siadach danego wierzchoªka. Dlatego najwygodniejsz reprezentacj grafu s listy s siedztwa. Oznaczenia: Adj = tablica list s siedztwa; dla u V, Adj[u] = lista s siadów u w grae G. Uwaga Iteracj po s siadach danego wierzchoªka mo»na ªatwo zrealizowa równie» na macierzy s siedztwa. Jest to jednak bardziej kosztowne w sensie zªo»ono±ci obliczeniowej. 3 / 48
Przeszukiwanie grafu w gª b Ustalmy graf niezorientowany G = (V, E). Z ustalonego wierzchoªka ¹ródªowego w si gamy coraz gª biej w graf, je»eli jest to tylko mo»liwe. badamy wszystkie niezbadane dot d kraw dzie ostatnio odwiedzonego wierzchoªka v, gdy wszystkie kraw dzie v s zbadane, wracamy do wierzchoªka, z którego v zostaª odwiedzony, proces kontynuujemy dopóki wszystkie wierzchoªki osi galne z wierzchoªka ¹ródªowego w nie zostan odwiedzone. Je»eli po powy»szym procesie pozostanie jakikolwiek nie odwiedzony wierzchoªek u, kontynuujemy przeszukiwanie traktuj c go jako nowy wierzchoªek ¹ródªowy. Caªy proces powtarzamy, a» wszystkie wierzchoªki w grae zostan odwiedzone. 4 / 48
Przeszukiwanie grafu w gª b Nale»y zatem zapami tywa stany, w jakich znajduj si w danej chwili wierzchoªki. Do zapisania aktualnego stanu wierzchoªka u»ywamy jednego z trzech kolorów: Uwaga biaªy wszystkie wierzchoªki na pocz tku; wierzchoªek odwiedzany po raz pierwszy kolorujemy na szaro; wierzchoªek przetworzony (= lista jego s siadów jest caªkowicie zbadana) kolorujemy na czarno. Tak naprawd w najprostszej implementacji wystarcz dwa stany: nieodwiedzony i odwiedzony. Jednak dokªadniejsze rozró»nienie stanów pozwala lepiej zrozumie ide DFS oraz jest wykorzystywane w niektórych zastosowaniach. 5 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b DFS-Visit(G, u) 2 kolor(u) := szary; 3 for ka»dy v Adj[u] do 4 if kolor(v) = biaªy then DFS-Visit(G, v); 5 kolor(u) := czarny; 6 end; 5 1 2 3 4 6 6 / 48
Przeszukiwanie grafu w gª b Zauwa»my,»e po wywoªaniu DFS-Visit dla wierzchoªka u wierzchoªki, które nie s osi galne z u pozostan nieodwiedzone (biaªe). Aby zatem przejrze caªy graf, nale»y wywoªywa DFS-Visit dopóki b d biaªe wierzchoªki. Peªen przebieg algorytmu DFS jest realizowany przez poni»sz procedur : DFS(G) 2 for ka»dy u V(G) do 3 kolor(u) := biaªy; 4 for ka»dy u V(G) do 5 if kolor(u) = biaªy then 6 DFS-Visit(G, u); 7 end; 7 / 48
Przeszukiwanie grafu w gª b Zªo»ono± czasowa: O( V + E ): odwiedzamy ka»dy wierzchoªek i (dwukrotnie!) ka»d kraw d¹. Zªo»ono± pami ciowa: O( V ): przechowywanie kolorów, przechowywanie wierzchoªków na stosie rekurencji. 8 / 48
Badanie spójno±ci Podstawowe zastosowania: Sprawdzanie spójno±ci grafu. Wyznaczanie skªadowych spójno±ci grafu. Zauwa»my,»e w procedurze DFS wywoªujemy DFS-Visit dokªadnie tyle razy, ile jest skªadowych spójno±ci w grae G. W szczególno±ci, gdy graf jest spójny, DFS-Visit zostanie wywoªana dokªadnie raz przez procedur DFS. Nietrudno uzupeªni procedur DFS o kod zliczaj cy skªadowe spójno±ci, jak równie» przypisuj cy wierzchoªkom numer skªadowej. 9 / 48
DFS - inne zastosowania Inne zastosowania: Wyznaczanie silnie spójnych skªadowych (w wersji dla grafu skierowanego). Sortowanie topologiczne grafu zorientowanego (bez zorientowanych cykli). Generowanie labiryntów. Znajdowanie drogi w labiryncie. Zainteresowanych odsyªamy do literatury (patrz te» dodatkowe materiaªy do wykªadu i zaj laboratoryjnych). 10 / 48
Przeszukiwanie grafu wszerz Z ustalonego wierzchoªka ¹ródªowego s przegl damy kolejne wierzchoªki z niego osi galne. wierzchoªki w odlegªo±ci (=najmniejszej liczbie kraw dzi) k od ¹ródªa s odwiedzane przed wierzchoªkami w odlegªo±ci k + 1, granica mi dzy wierzchoªkami odwiedzonymi i nieodwiedzonymi jest przekraczana jednocze±nie na caªej jej szeroko±ci. Je»eli po powy»szym procesie pozostanie jakikolwiek nie odwiedzony wierzchoªek u, kontynuujemy przeszukiwanie traktuj c go jako nowy wierzchoªek ¹ródªowy. Caªy proces powtarzamy, a» wszystkie wierzchoªki w grae zostan odwiedzone. 11 / 48
Przeszukiwanie grafu wszerz Ka»dy wierzchoªek posiada jeden z 3 kolorów: biaªy, szary lub czarny (podobnie jak w DFS). Na pocz tku wszystkie wierzchoªki s biaªe. Wierzchoªki szare s przechowywane w kolejce FIFO. Po jej opuszczeniu kolorujemy je na czarno. 12 / 48
Kolejka FIFO Kolejka FIFO Q jest dynamiczn struktur danych w formie ci gu, do której mo»na doª czy skªadnik tylko w jednym ko«cu (na ko«cu kolejki - tail), a usun tylko w drugim ko«cu (na pocz tku kolejki - head). Mamy zatem dwie podstawowe operacje: Enqueue(Q, v) = dodanie elementu v na ko«cu kolejki, Dequeue(Q) = usuni cie elementu z pocz tku kolejki. Dodatkowo wykorzystamy operacj Uwaga Head(Q) = zwrócenie elementu z pocz tku kolejki (bez usuwania go). Kolejk implementujemy przy u»yciu struktur wska¹nikowych. Mo»na te» zasymulowa jej dziaªanie na zwykªej (statycznej) tablicy, albo wykorzysta gotowe struktury biblioteczne, np. queue biblioteki STL w C++: http://www.cplusplus.com/reference/queue/queue/. 13 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 14 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 6 Q: 14 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 1 6 15 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 1 2 6 16 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 1 2 5 6 17 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 1 2 5 4 6 18 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 2 5 4 6 19 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 5 4 6 20 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 5 4 3 6 21 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 5 4 3 6 6 22 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 4 3 6 6 23 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 3 6 6 24 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 Q: 6 6 25 / 48
Przeszukiwanie grafu wszerz BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 Enqueue(Q, v) 10 end; 11 Dequeue(Q); 12 kolor(u) := czarny 13 end 14 end 1 2 3 4 5 6 Q: 26 / 48
Przeszukiwanie grafu wszerz Zauwa»my,»e po wywoªaniu BFS-Visit dla wierzchoªka u wierzchoªki, które nie s osi galne z u pozostan nieodwiedzone (biaªe). Aby zatem przejrze caªy graf, nale»y wywoªywa BFS-Visit dopóki b d biaªe wierzchoªki. Peªen przebieg algorytmu BFS jest realizowany przez poni»sz procedur : BFS(G) 2 for ka»dy u V(G) do 3 kolor(u) := biaªy; 4 for ka»dy u V(G) do 5 if kolor(u) = biaªy then 6 BFS-Visit(G, u); 7 end; 27 / 48
Przeszukiwanie grafu wszerz Zªo»ono± czasowa: O( V + E ) (analogicznie jak dla DFS). Zªo»ono± pami ciowa: O( V ) (przechowywanie kolorów, kolejka). 28 / 48
Najkrótsza droga Zastosowanie: znajdowanie najkrótszej drogi pomi dzy wierzchoªkami s i v. Modykacja procedury BFS-Visit: przechowywanie wektora poprzedników π. Tj. poprzednikiem wierzchoªka v na najkrótszej drodze z s do v jest wierzchoªek π[v]; poprzednikiem wierzchoªka π[v] jest wierzchoªek π[π[v]]... 29 / 48
Najkrótsza droga Przygotowanie: for ka»dy u V(G) do begin kolor(u) := biaªy; π[u] := end; 30 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end 31 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 3 4 5 6 1 2 3 4 5 6 Q: 31 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 3 4 5 6 1 2 3 4 5 Q: 1 6 32 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 4 5 6 1 2 3 4 5 Q: 1 2 6 33 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 4 5 1 6 1 2 3 4 5 Q: 1 2 5 6 34 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 4 1 5 1 6 1 2 3 4 5 Q: 1 2 5 4 6 35 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 4 1 5 1 6 1 2 3 4 5 Q: 2 5 4 6 36 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 4 1 5 1 6 1 2 3 4 5 Q: 5 4 6 37 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 5 4 1 5 1 6 1 2 3 4 5 Q: 5 4 3 6 38 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 5 4 1 5 1 6 5 1 2 3 4 5 Q: 5 4 3 6 6 39 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 5 4 1 5 1 6 5 1 2 3 4 5 Q: 4 3 6 6 40 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 5 4 1 5 1 6 5 1 2 3 4 5 Q: 3 6 6 41 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 5 4 1 5 1 6 5 1 2 3 4 5 Q: 6 6 42 / 48
Zmodykowany BFS BFS-Visit(G, s) 2 kolor(s) := szary; 3 Q := {s}; 4 while Q <> do begin 5 u := Head(Q); 6 for ka»dy v Adj[u] do 7 if kolor(v) = biaªy then begin 8 kolor(v) := szary; 9 π[v] := u; 10 Enqueue(Q, v) 11 end; 12 Dequeue(Q); 13 kolor(u) := czarny 14 end 15 end w π[w] 1 2 1 3 5 4 1 5 1 6 5 1 2 3 4 5 6 Q: 43 / 48
Odczytanie dróg Po wykonaniu BFS-Visit(G, s) w wektorze π zakodowane s najkrótsze drogi z wierzchoªka ¹ródªowego s do wszystkich wierzchoªków w osi galnych z s. W naszym przykªadzie s = 1: w π[w] 1 2 1 3 5 4 1 5 1 6 5 Np. najkrótsza droga z s = 1 do 6 to: 6 π[6] π[π[6]], czyli 6 5 1. A najkrótsza droga z s = 1 do 3 to: 3 π[3] π[π[3]], czyli 3 5 1. 1 2 3 4 5 6 44 / 48
Odczytanie dróg Odczytanie i wypisanie drogi z s do v od ko«ca mo»e by zrealizowane przez poni»szy pseudokod: PrintPathRev(s, v) 2 if s = v then wypisz(v) 3 else if π[v] = then wypisz('nie ma drogi') 4 else begin 5 while v <> s do begin 6 wypisz(v); 7 v := π[v] 8 end; 9 wypisz(s) 10 end 11 end; 45 / 48
Odczytanie dróg Jednak bardziej naturalnym byªoby wypisanie drogi z s do v od pocz tku. Do tego mo»e posªu»y poni»sza elegancka procedura rekurencyjna: PrintPath(s, v) 2 if s = v then wypisz(v) 3 else if π[v] = then wypisz('nie ma drogi') 4 else begin 5 PrintPath(s, π[v]); 6 wypisz(v) 7 end 8 end; 46 / 48
Podsumowanie Je»eli interesuje nas najkrótsza droga pomi dzy dwoma ustalonymi wierzchoªkami s i t, to: uruchamiamy BFS-Visit dla wierzchoªka s, odczytujemy drog z s do t z wektora π. Wektor π b dzie zawieraª, jako skutek uboczny, najkrótsze drogi z s do wszystkich wierzchoªków osi galnych z s (nie tylko t!). Wyliczania tej nadmiarowej informacji nie da si tu unikn. 47 / 48
Podsumowanie Zauwa»my,»e tu przez najkrótsz drog rozumieli±my drog o najmniejszej liczbie kraw dzi. Mo»na rozwa»a grafy, w których kraw dzie maj dªugo± (lub inny koszt) i poszukiwa najkrótszych dróg wzgl dem tego parametru. Tym zagadnieniem zajmiemy si na nast pnym wykªadzie. 48 / 48