GRAFY Przykład grafu skierowanego Przykład grafu
Transkrypt
GRAFY Przykład grafu skierowanego Przykład grafu
GRAFY Przykład grafu skierowanego Graf to system G=(V,E), gdzie: V = {1,2,3,4,5,6} V – zbiór (skończony) wierzchołków G E = {(1,2), (2,2), (2,4), (2,5), (4,1), (4,5), (5,4), (6,3)} E – zbiór krawędzi G. W grafie skierowanym (zorientowanym) E jest relacją binarną w V. W grafie nie skierowanym (niezorientowanym) E jest to zbiór nieuporządkowanych par wierzchołków. Zapis (u,v) i (v,u) oznaczają tę samą krawędź. W grafie nie skierowanym nie mogą występować pętle. 1 2 3 4 5 6 2 Przykład grafu nie skierowanego Grafy – pojęcia podstawowe (1) Dla grafu skierowanego mówimy, Ŝe krawędź (u,v) jest wychodząca z wierzchołka u i wchodząca do wierzchołka v. Dla grafu nie skierowanego mówimy, Ŝe krawędź (u,v) jest incydentna z wierzchołkami u i v. V = {1,2,3,4,5,6} E = {(1,2), (1,5), (2,5), (3,6)} 4 – wierzchołek izolowany 1 2 3 4 5 6 3 Pomiędzy wierzchołkami grafu istnieje relacja sąsiedztwa. W grafie nie skierowanym relacja sąsiedztwa jest symetryczna. Jeśli (u,v) jest krawędzią grafu G to wierzchołek v jest sąsiedni do wierzchołka u. 4 Grafy – pojęcia podstawowe (2) Grafy – pojęcia podstawowe (3) Stopniem wierzchołka: •W grafie skierowanym ścieŜka < v0, v1, …, vk> tworzy cykl, jeśli v0 = vk i zawiera co najmniej jedną ścieŜkę czyli k≥1. w grafie nie skierowanym jest liczba incydentnych z nim krawędzi; •Cykl jest prosty, jeśli dodatkowo vi = vs dla i,s=1,..,k oraz i≠s. w grafie skierowanym jest suma stopnia wejściowego (liczba wchodzących do niego krawędzi) i wyjściowego (liczba wychodzących z niego krawędzi). •Pętla jest cyklem o długości 1. •Graf skierowany nie zawierający pętli nazywamy prostym. ŚcieŜka (droga) długości k z wierzchołka v0 do vk jest ciągiem wierzchołków < v0, v1, …, vk> takich, Ŝe (vi,vi+1)∈E dla i=0,1,…,k-1 i krawędzi (v0, v1), (v1, v2), …, (vk-1, vk). •Graf nie zawierający cykli nazywamy acyklicznym. ŚcieŜka jest ścieŜką prostą, jeŜeli wszystkie jej wierzchołki są róŜne czyli nie zawiera ona cykli. 5 1 6 •Graf nie skierowany jest spójny, jeśli kaŜda para wierzchołków jest połączona ścieŜką. Graf pełny to graf nie skierowany, w którym kaŜda para wierzchołków jest połączona krawędzią. 1 Reprezentacje grafów (2) Reprezentacje grafów (1) W reprezentacji grafu za pomocą macierzy sąsiedztwa zakłada się, Ŝe wierzchołki grafu są ponumerowane 1,2,...,|V|. Graf skierowany jest silnie spójny, jeśli kaŜde dwa wierzchołki są osiągalne jeden z drugiego tzn. jeśli istnieje ścieŜka z jednego do drugiego wierzchołka. Macierz sąsiedztwa jest to wtedy macierz: Graf G moŜna reprezentować na dwa sposoby: A=(aik)∈R|V|×|V| taka, Ŝe 1 , gdy (i, k ) ∈ E aik = 0 , gdy (i, k ) ∉ E - lista sąsiedztwa; - macierz sąsiedztwa. Lista sąsiedztwa jest to tablica zawierająca |V| list, po jednej dla kaŜdego wierzchołka. Elementami listy dla wierzchołka v są wierzchołki u∈V takie, Ŝe (v,u)∈E. Porządek wierzchołków na tej liście jest dowolny. Reprezentacja taka ma zastosowanie, gdy graf jest rzadki tj. |E|<<|V|2. 7 Wymagane jest to O(V2) pamięci. Dla grafu nie skierowanego wystarczy pamiętać tylko elementy na i powyŜej głównej przekątnej. Zaletą tej reprezentacji jest szybki dostęp O(1) do informacji czy dana krawędź istnieje w grafie. 8 Graf nie skierowany 1 2 Graf skierowany 3 Macierz sąsiedztwa: 4 1 3 2 4 Macierz sąsiedztwa: 5 5 Lista sąsiedztwa: 1: 2 → 4 2: 1 → 4 → 5 → 3 3: 2 → 5 4: 1 → 2 → 5 5: 4 → 2 → 3 1 1 2 3 4 5 0 1 0 1 0 2 1 0 1 1 1 3 0 1 0 0 1 4 5 1 0 1 1 0 1 0 1 1 0 9 1 2 3 4 5 6 1 0 1 1 0 0 0 2 0 0 1 0 0 0 Lista sąsiedztwa: 3 0 0 0 1 0 0 1: 2 → 3; 2: 3 4 0 1 0 0 1 0 3: 4; 4: 2 → 5 5 0 0 0 0 0 1 5: 6; 6: 6 6 0 0 0 0 0 1 6 10 Przeszukiwane grafu wszerz (1) Przeszukiwane grafu wszerz (2) Podczas przeglądania kaŜdy wierzchołek jest kolorowany na biało, szaro lub czarno. Nowo napotkany wierzchołek staje się odwiedzony, a jego kolor zmienia się na kolor inny niŜ biały. Wierzchołki szare tworzą granicę między odwiedzonymi i nie odwiedzonymi wierzchołkami. Jeśli u znajduje się na ścieŜce prowadzącej od s do v, to u jest przodkiem v i v jest potomkiem u. Pomocnicze struktury: Dane: graf G=(V,E), wyróŜniony wierzchołek początkowy s (źródło). W przeszukiwaniu grafu wszerz systematycznie badane są krawędzie grafu w celu odwiedzenia kaŜdego wierzchołka, który jest osiągalny z s. Obliczane są odległości (najmniejsza liczba krawędzi) od źródła s do wszystkich osiągalnych wierzchołków. W algorytmie tym budowane jest drzewo przeszukiwania wszerz, którego korzeniem jest s. Dla kaŜdego wierzchołka v osiąganego z s ścieŜka w tym drzewie odpowiada najkrótszej ścieŜce od s do v w G. Color[u] – Kolor wierzchołka u; Pi[u]- poprzednik wierzchołka u; Pi[u]=NIL gdy nie ma poprz. D[u] – odległość wierzchołka u od źródła s; Adj[u] – otoczenie wierzchołka u; Q – kolejka, w której pamiętane są szare wierzchołki. 11 12 2 Procedure BFS(G, s); Przykład BFS FOR kaŜdy u∈V[G]\{s} DO r Color[u]=biały; D[u]=∞; Pi[u]=NIL; s ∝ t ∝ 0 V={s,r,v,w,t,x,y,u} ∝ u Q={s} Color[s]=szary; D[s]:=0; Pi[s]:=NIL;Q=∅; Dodaj_Do_Kol(Q,s); WHILE Q≠ ∅ DO {dopóki istnieją szare wierzchołki} v∝ u=Czolo_Kolejki(Q); w ∝ D[s]=0 ∝ y ∝ x FOR kaŜdy v∈Adj[u] DO r IF Color[v]=biały THEN s 1 t ∝ 0 ∝ u Q={w,r} Color[v]=szary; D[v]=D[u]+1; D[w]=1, D[r]=1 Pi[v]=u; Dodaj_Do_Kolejki(Q,v); v∝ Usun_Z_Kolejki(Q); Color[u]=czarny; 13 s 1 ∝ u t 2 0 Przykład BFS – c.d. r w 1 ∝ y 2 x s 1 0 t 2 w 1 x 2 ∝ y D[u]=3 s 0 t 2 3 u Q={v, u, y} w 1 x 2 3 y 3 u Q={x, v, u} D[x]=2, D[v]=2, Q={r, t, x} v 2 D[r]=1, v∝ ∝ y 14 Przykład BFS – c.d. r ∝ x w 1 r D[t]=2, D[x]=2 1 D[v]=2, D[u]=3, r s 1 0 t 2 ∝ u v 2 Q={t, x, v} r D[t]=2, D[x]=2, w 1 v 2 2 x ∝ y Przykład BFS – c.d. s t 2 0 t 2 3 u w 1 x 2 3 y Q={u, y} D[u]=3, D[y]=3, 16 1 0 D[v]=2 15 r s 1 D[y]=3 3 u v 2 Wynik: drzewo przeszukiwania wszerz Q={y} s 0 D[y]=3 r 1 v 2 17 x 2 w 1 v 2 s r 3 y 0 t 2 3 u w 1 x 2 3 y v 2 1 w 1 x 2 2 t Q=∅ y 3 3 u 18 3 Drzewo jako graf Algorytm Dijkstry Drzewo to graf spójny nie zawierający Ŝadnego cyklu (acykliczny). Wierzchołki stopnia jeden nazywamy liśćmi drzewa. Algorytm Dijkstry słuŜy do wyznaczania minimalnych kosztów dojścia od ustalonego wierzchołka grafu skierowanego do wszystkich jego pozostałych wierzchołków. Zakładamy, Ŝe wszystkie krawędzie grafu mają dodatnie koszty. Twierdzenie. Następujące warunki są równowaŜne: Wskazaną reprezentacją grafu są tu listy sąsiedztwa. Wtedy w łatwy sposób jest dostęp do następnika danego wierzchołka i w czasie O(1) moŜna stwierdzić, czy dany wierzchołek został juŜ „zrobiony”. T jest drzewem; kaŜde dwa wierzchołki w T są połączone dokładnie jedną ścieŜką; Oznaczenia zmiennych: T jest minimalnym grafem spójnym, tzn. T jest grafem spójnym, ale graf T\{e} nie jest spójny dla kaŜdego e∈T; 19 20 Zmienne w algorytmie Dijkstry A – tablica n×n, której elementami są rekordy o dwóch polach: węzeł – numer węzła będący jego następnikiem i koszt – koszt krawędzi od danego wierzchołka do następnika. Algorytm Dijkstry w pseudokodzie d – wektor kosztów minimalnych Dla k:=1 to n powtórz: d[k] – koszt (całkowity) dojścia od wybranego wierzchołka do wierzchołka k. Na początku algorytmu wartości tego wektora ustawiamy na ∝ a dla wybranego wierzchołka na 0. 1. Spośród nie zrobionych wierzchołków grafu wybieramy ten, którego koszt jest najmniejszy. 2. Wybrany wierzchołek zaznaczamy jako zrobiony (odpowiadające mu pole w wektorze z ustawiamy na true). z – wektor wartości logicznych Z[k] = TRUE, jeŜeli wierzchołek k został juŜ „zrobiony”. Na początku wszystkie wartości ustawiamy na FALSE. 3. Jeśli koszt i-tego wierzchołka jest skończony, wtedy dla wszystkich następników j wierzchołka i, które jeszcze nie zostały zrobione próbujemy poprowadzić drogę do j przez wierzchołek i tzn. d[j] = min{d[j], d[i]+koszt krawędzi (i,j)} 21 22 Algorytm Dijkstry Function Znajdz_Min(n:integer; z:tablog; d:tabkosz) : integer; Procedure WyznaczKoszty(n : integer; A:macierz; d:tabkoszt; z:tablog); Var i, wynik:Integer; Var i,j,k,p:Integer; Begin Begin wynik:=-1; d[1]:=0; For i:=1 to n do d[i]:=MaxInt; For i:=1 to n do i:=1; While A[1,i].wezel>0 do d[A[1,i].wezel]:=A[1,i].koszt; If Not z[i] Then For i:=1 to n do z[i]:=False; If wynik=-1 Then wynik:=i For k:=1 to n do Else Begin If d[i]<d[wynik] Then wynik:=i; i:=Znajdz_Min(n,z,d); Znajdz_Min:=wynik; 23 End; z[i]:=True; 24 4 Procedure WyznaczKoszty– c.d. Algorytm Dijkstry – przykład If d[i]<MaxInt Then Begin 2 1 p:=1; 13 While A[i,p].wezel>0 do 5 Begin 2 if not z[j] Then d[j]:=Min(d[j],d[i]+A[i,1].koszt); 3 4 1 2 j:=A[i,p].wezel; 3 6 1 5 10 End; {if} d=[0,M,M,M,M,M] Wybrany wierzchołek: 1 End; {for k} 25 End; {WyznaczKoszty} {Wynik jest w tablicy d!} z=[F,F,F,F,F,F] 26 Algorytm Dijkstry – przykład c.d. i=1 (4,6) (6,5) (0,0) (0,0) (0,0) 6 5 End; {while} (2,13) (3,2) ( 4,5) (5,1) A = (4,3) (5,15) (2,1) (5,10) 15 (2,2) (0,0) Algorytm Dijkstry – przykład c.d. i=1, j=2: d = [0, 13, 2, 6, M, M] d[j]=M, d[i]+(i,j)=13 z = [T, F, F, F, F, F] min(M, 13)=13 → d[j]=13 Min. z nie zrobionych czyli min(5, 17) = 5 stąd i = 4 i=4 dla i=1, j=3 i i=1, j=4 tak samo (2,1), (5,10) d = [ 0, 6, 2, 5, 15, M] i=4, j=2: d[j]=min(13,5+1)=6 z = [T, F, T, T, F, F] i=4, j=5: d[j]=min(17,5+10)=15 Min.z nie zrobionych czyli min(13, 2, 6) = 2, stąd i=3 i=3 d = [0, 13, 2, 5, 17, M] d[j]=6, d[i]+(i,j)=2+3=5 z = [T, F, T, F, F, F] min(6, 5)=5 → d[j]=5 i=3, j=5: d[j]=min(M, 2+15)=17 27 i = 2 {min(6, 15)=6} i=3, j=4: (4,5), (5,1), (6,5) d = [ 0, 6, 2, 5, 7, 11] i=2, j=4: d[j]=min(5,6+5)=5 z = [T, T, T, T, F, F] i=2, j=5: d[j]=min(15,6+1)=7 i=2, j=6: d[j]=min(M,6+5)=11 28 Algorytm Prima Algorytm Dijkstry – przykład c.d. DEF. i=5 d = [0, 6, 2, 5, 7, 11] (2,2) Drzewo rozpinające grafu G jest to spójny podgraf, który zawiera wszystkie wierzchołki naleŜące do G i jest drzewem. i=5, j=2: d[j]=min(6,7+1)=6 z = [T, T, T, T, T, F] i=6 Minimalne drzewo rozpinające grafu G posiada najmniejszą wagę. Istnieje ono dla grafu waŜonego tzn. takiego grafu, w którym z kaŜdą krawędzią związana jest pewna waga. nie ma sąsiadów d = [0, 6, 2, 5, 7, 11] !! z = [T, T, T, T, T, T] 29 30 Algorytm Prima wyznacza minimalne drzewo rozpinające A. Najpierw jest ono zbudowane tylko z korzenia, a następnie w kaŜdym kroku dołączana jest do niego krawędź lekka łącząca wierzchołek drzewa A z wierzchołkiem z V(G)\A. Jest to algorytm zachłanny. 5 Algorytm Prima (G, w, r) Algorytm Prima – przykład Q←V[G]; b 4 FOR kaŜdy wierzchołek u∈Q do klucz[u] ← ∝; a Klucz[r] ←0; P[r] ←NIL; WHILE Q≠∅ DO 2 Q = {a, b, c, d, e, f} 2 1 e 2 7 u ←EXT_MIN(Q); c 3 d 6 IF v∈Q and w(u,v)<klucz[v] THEN {[a,e,1], [a,f,2], [a,b,4]} Wybieramy krawędź: P[v] ←u; Koszt klucz[v] ←w(u,v); Q = {b, c, d, e, f,} Lista: f FOR kaŜdy wierzchołek v∈Adj[u] DO Wybieramy wierz. a. 8 (a,e) O(Elg2V) 31 32 Algorytm Prima – przykład c.d. b 4 a Algorytm Prima – przykład c.d. 2 2 1 e 2 7 c 8 3 f d 6 b 4 Q = {b, c, d, f} a Dodajemy krawędzie do listy: 2 Q = {b, c, d} 2 1 e 2 7 { [a,f,2], [e,b,2], [e,d,3], [a,b,4], [d,f,6], [e,f,7]} c 8 3 f d 6 Wybieramy krawędź: { [e,b,2], [e,d,3], [a,b,4], [d,f,6], [e,f,7]} Wybieramy krawędź: (a,f) 33 Dodajemy krawędzie do listy: (e,b) 34 Algorytm Prima – przykład c.d. b 4 a Algorytm Prima – przykład c.d. 2 1 2 e 2 7 f c 8 3 d 6 b 4 Q = {c, d} a Dodajemy krawędzie do listy: 2 Q = {d} 1 2 e 2 7 { [b,c,2], [e,d,3], [a,b,4], [d,f,6], [e,f,7]} f 8 3 d 6 Wybieramy krawędź: (b,c) c Dodajemy krawędzie do listy: { [e,d,3], [a,b,4], [d,f,6], [e,f,7], [c,d,8]} Wybieramy krawędź: (e,d) Q=∅!!! 35 36 6 Drzewo utworzone w alg. Prima 1. W przeciwieństwie do metody programowania dynamicznego nie występuje etap dzielenia na mniejsze realizacje z wykorzystaniem właściwości rekurencyjnej. a 1 2 Właściwości algorytmu zachłannego f 2. Algorytm zachłanny znajduje rozwiązanie w wyniku podjęcia szeregu decyzji, z których kaŜda wydaje się w danym momencie najlepsza. Oznacza to, Ŝe kaŜdy wybór jest optymalny lokalnie. e 3 2 d b 2 3. Takie podejście nie zapewnia, Ŝe rozwiązanie globalne będzie optymalne. 4. Czasem takie rozwiązanie optymalne globalnie istnieje, jednak naleŜy to zawsze dodatkowo wykazać. c 37 38 Ogólna charakterystyka algorytmu zachłannego Przykłady algorytmów zachłannych: 1. Utwórz zbiór pusty. 2. Powtarzaj, aŜ otrzymasz rozwiązanie realizacji problemu: 2.1. Wykonaj procedurę wyboru, która słuŜy do wybrania kolejnego elementu dodawanego do zbioru. Wybór jest wykonywany zgodnie z kryterium zachłannym, który spełnia warunek optymalny lokalnie. 2.2. Wykonaj procedurę sprawdzenia wykonalności, która słuŜy do określenia, czy zbiór jest akceptowalny dzięki sprawdzeniu, czy istnieje moŜliwość uzupełnienia go w taki sposób, który zapewni osiągnięcie realizacji problemu. 2.3. Wykonaj procedurę sprawdzenia rozwiązania, słuŜącą do określenia, czy ów zbiór stanowi rozwiązanie realizacji problemu. 39 Algorytm Dijkstry – problem najkrótszych ścieŜek z jednym źródłem; Algorytm Bellmana-Forda JeŜeli w grafie G pojawiają się krawędzie o ujemnych wagach i jeśli istnieje w nim cykl o ujemnej wadze osiągany ze źródła s, wtedy moŜe nie istnieć najkrótsza ścieŜka poniewaŜ nowa ścieŜka jest powiększona o ten cykl o ujemnej wadze. a 3 5 0 b -4 -1 4 3 6 c 5 d 11 g 8 -∞ -3 2 7 -6 e 41 Algorytm Prima – obliczenie minimalnego drzewa rozpinającego (oraz Algorytm Kruskala); 40 Problemy ujemnych wag: s -∞ -∞ 3 f Algorytm ten słuŜy do wyznaczania najkrótszych ścieŜek z jednego źródła dla grafu, w którym wagi krawędzi mogą być ujemne. Dany jest: • Cykl <c, d, c> ma wagę 3 i najkrótsza ścieŜka z s do c to <s, c>. Cykl <e, f, e> ma wagę -3. Nie istnieje najkrótsza ścieŜka z s do e: <s,e>, <s,e,f,e>, <s,e,f,e,f,e> … 42 graf skierowany G=(V,E), • s-źródło, • funkcja wagowa ω : E → R. Algorytm Bellmana-Forda zwraca wartość logiczną wskazującą czy istnieje lub nie cykl o ujemnej wadze osiągany ze źródła. Jeśli taki cykl istnieje w grafie, to algorytm zwraca fałsz i nie oblicza nic. JeŜeli graf nie zawiera takich cykli, to algorytm zwraca true i oblicza najkrótsze ścieŜki i ich wagi. 7 Function BelFord(G,w,s):Boolean; Algorytm Bellmana-Forda - przykład 5 FOR kaŜdy wierzchołek v∈V[G] DO u d[v] ← ∝; Pi[v] ← NIL; 6 z d[s] ← 0; 0 FOR i=1 TO |V[G]|-1 DO -2 ∞ 8 2 7 -4 7 ∞ FOR kaŜda krawędź (u,v)∈E[G] DO v ∞ -3 ∞ 9 x y IF d[v]>d[u]+w(u,v) THEN d[v] ← d[u]+w(u,v); Pi[v] ← u; FOR kaŜda krawędź (u,v)∈E[G] DO IF d[v]>d[u]+w(u,v) THEN return FALSE; (u,v), (u,x), (u,y), (v,u), (x,v), (x,y), (y,v), (y,z), (z,u), (z,x) O(V⋅E) return TRUE; 43 Źródłem jest wierzchołek z. Relaksacja krawędzi odbywać się będzie w porządku leksykograficznym: Koszt 44 Alg. Bellmana-Forda – przykład c.d. u ∞ 6 z 7 v ∞ -3 8 2 0 5 -2 -4 7 ∞ x ∞ 9 y 5 u i=1 6 z 0 -3 8 2 7 -4 7 7 9 x 45 v ∞ -2 6 Alg. Bellmana-Forda – przykład c.d. (u,v) - ∅; (u,x) - ∅; (u,y) - ∅; (v,u) - ∅; (x,v) - ∅; (x,y) - ∅; (y,v) - ∅; (y,z) - ∅; (z,u):d[u]=6; (z,x):d[x]=7; 5 u 7 6 6 z 7 x 7 -3 -4 7 2 y 9 u 2 6 i=3 z 0 x 7 4 v -3 8 2 7 47 5 -2 -4 7 9 7 ∞ 9 x y 5 u 2 y 6 6 i=2 z 0 2 46 -2 4 v -3 8 7 y 4 v 8 2 0 -4 7 ∞ 5 -2 -3 8 2 0 -4 7 7 x 9 (u,v):d[v]=11; (u,x) - ∅; (u,y):d[y]=2; (v,u) - ∅; (x,v):d[v]=4; (x,y) - ∅; (y,v) - ∅; (y,z) - ∅; (z,u) - ∅; (z,x) - ∅; 2 y Alg. Bellmana-Forda – przykład c.d. Alg. Bellmana-Forda – przykład c.d. u 6 6 z v ∞ -2 5 (u,v) - ∅; (u,x) - ∅; (u,y) - ∅; (v,u):d[u]=2; (x,v) - ∅; (x,y) - ∅; (y,v) - ∅; (y,z) - ∅; (z,u) - ∅; (z,x) - ∅; u 2 6 z 0 -2 4 v -3 8 2 7 x 7 -4 7 2 y 9 5 u i=4 2 6 z 0 x 7 4 v -3 8 2 7 48 -2 -4 7 9 (u,v) - ∅; (u,x) - ∅; (u,y):d[y]=-2; (v,u) - ∅; (x,v) - ∅; (x,y) - ∅; (y,v) - ∅; (y,z) - ∅; (z,u) - ∅; (z,x) - ∅; -2 y 8