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

Podobne dokumenty