Transcript wyk6

Algorytmy i Struktury Danych
Grafy
WYKŁAD 6
PROWADZĄCY: DR PAWEŁ DROZDA
Plan wykładu
 Podstawowe pojęcia grafowe
 Reprezentacja grafów
 Problemy grafowe
 Algorytmy
 Przeszukiwanie w głąb i wszerz
 Minimalnie drzewo rozpinające
 Najkrótsze ścieżki
 Inne
dr Paweł Drozda
Pojęcie grafu (nieskierowany)
 Nieformalnie: zbiór wierzchołków oraz krawędzi
łączących te wierzchołki
 Formalnie:

Grafem (nieskierowanym) nazywamy parę G=(V,E)
V – zbiór wierzchołków
E – zbiór krawędzi, E  {{u, v} : u, v V }
e2
v1
v3
e3={v2,v3}
e4
v2
dr Paweł Drozda
e1
v4
Graf skierowany
 Grafem skierowanym nazywamy parę G=(V,A)
V – zbiór wierzchołków
A – zbiór krawędzi skierowanych E  V  V
(uporządkowanych par różnych wierzchołków)
e2
v1
v3
v4
e5
e3=(v3,v2)
e4
v2
dr Paweł Drozda
e1
Cechy grafu
 Wierzchołek v i krawędź e są incydentne gdy
v e
 Wierzchołki u i v są sąsiednie gdy
e  {u, v} E
 G’ jest podgrafem G w.t.w.
G' (V ' , E' )  G(V , E)  V '  V , E'  E
 Stopień wierzchołka deg(v) = liczba krawędzi
incydentnych z v
dr Paweł Drozda
Cechy grafu (2)
 Graf ważony to trójka G=(V,E,w), gdzie (V,E) jest
grafem, a w jest fukcją wag: w:E→R
Jeżeli
to w(e) jest wagą krawędzi e
e E
7
3
v1
v3
5
v4
1
4
v2
Wagi krawędzi:
(v1 ,v3) = 3, (v3 ,v4) = 7, (v4 ,v3) = 1
(v3 ,v2) = 4, (v2 ,v1) = 5
dr Paweł Drozda
Cechy grafu(3)
 Droga to wyznaczona przez krawędzi trasa
e1 e2 ei ei+1…
pozwalająca na „podróżowanie po grafie” od wierzchołka do
wierzchołka
 Ścieżka to droga nie zawierająca tych samych krawędzi. Ścieżka
wyznaczana jest przez wierzchołki


ścieżka otwarta: v1v2v3vivi+1…
ścieżka zamknięta: v1v2v3vivi+1…v1
 Cykl w grafie – droga wracająca do tego samego wierzchołka
 Graf cykliczny to graf w którym istnieje co najmniej jeden cykl
dr Paweł Drozda
Spójność grafu
 Graf jest spójny jeżeli pomiędzy dowolnymi
jego wierzchołkami istnieje droga
e2
v1
e4
v2
e10
dr Paweł Drozda
e1
v3
e5
v7
v4
e6
e3
e9
v6
e7
e8
v5
v8
Reprezentacja grafu
 Macierz sąsiedztwa – |V|2 elementów
 Lista Sąsiedztwa – lepsza dla grafów rzadkich, t.j.
|E|<<|V|2, O(max(V,E))=O(V+E) elementów
e2
v1
e1
v3
e3
e4
v2
v4
1
2
3
4
1
0
1
1
0
2
1
0
1
0
3
1
1
0
1
4
0
0
1
0
1: 2→3→null
2: 1→3→null
3: 1→2→4→ null
4: 3→null
dr Paweł Drozda
Reprezentacja grafu
 Macierz sąsiedztwa – |V|2 elementów
 Lista Sąsiedztwa – lepsza dla grafów rzadkich, t.j.
|E|<<|V|2, O(max(V,E))=O(V+E) elementów
3
v1
5
v3
v4
1
2
3
4
1
0
2
3
0
2
2
0
1
0
3
3
1
0
5
4
0
0
5
0
1
2
1: (2,2)→(3,3)→null
v2
2: (1,2)→(3,1)→null
3: (1,3)→(2,1)→ (4,5)→ null
4: (3,5)→null
dr Paweł Drozda
Reprezentacja grafu
 Dla grafu skierowanego
e2
v1
e1
v3
e3
e4
v2
v4
e5
1
2
3
4
1
1
0
1
0
2
1
0
0
0
3
0
1
0
1
4
0
0
0
0
1: 1 → 3→null
2: 1→null
3: 2→4→null
4: 3→null
dr Paweł Drozda
Problem mostów królewieckich
 Czy można przejść kolejno przez wszystkie mosty tak,
żeby każdy przekroczyć tylko raz i wrócić do miejsca, z
którego się wyruszyło?
 Zagadnienie opublikowane przez Eulera w 1736 roku –
pierwsza praca n.t. teorii grafów
dr Paweł Drozda
Algorytmy grafowe
 Przeszukiwanie grafów

w głąb, wszerz
 Drzewa – szczególna postać grafów

Znajdowanie minimalnego drzewa rozpinającego – algorytm Kruskala i
Prima
 Problemy:






znajdowanie najkrótszej ścieżki (Dijkstry, Bellmana – Forda, Floyda –
Warshalla)
znajdowanie ścieżki/cyklu Eulera
chińskiego listonosza – najkrótsza droga przechodząca wszystkie
krawędzie grafu co najmniej raz
znajdowanie ścieżki/cyklu Hamiltona - Θ(n!)
komiwojażera – najkrótsza zamknięta ścieżka, przechodząca przez
wszystkie wierzchołki (minimalny cykl Hamiltona)
kojarzenia małżeństw
dr Paweł Drozda
Przeszukiwanie wszerz
 Breadth-First Search
 dane: graf G(V,E), wierzchołek początkowy s
 BFS(G,s):
zaznacz wszystkie wierzcholki jako nieodwiedzone
enqueue(Q,s);
zaznacz s jako odwiedzony;
while ~empty(Q) do
begin
w = dequeue(Q);
foreach sasiad w do
if sasiad nie odwiedzony then
begin
zaznacz sasiad jako odwiedzony;
enqueue(Q, sasiad);
end
end
Zł. czasowa = O(|V|+|E|)
Θ(|V|) – inicjalizacja
O(|E|) – przeglądanie
dr Paweł Drozda
Przeszukiwanie w głąb
 Depth-first search
 dane: graf G(V,E), wierzchołek początkowy s
 DFS(G,s):
zaznacz wszystkie wierzcholki jako nieodwiedzone
push(S,s);
zaznacz s jako odwiedzony;
while ~empty(S) do
begin
w = pop(Q);
foreach sasiad wierzcholka w do
if sasiad nie odwiedzony then
begin
zaznacz sasiad jako odwiedzony;
push(S, sasiad);
end
end
Zł. czasowa = O(|V|+|E|)
Θ(|V|) – inicjalizacja
O(|E|) – przeglądanie
dr Paweł Drozda
Minimalne drzewo rozpinające
Niech będzie dany graf G = <V, E> spójny niezorientowany,
skończony i niech c : E  R+ będzie funkcją kosztu określoną
na krawędziach tego grafu.
Problem
Dla danego skończonego grafu G oraz danej funkcji kosztu c,
znaleźć minimalne drzewo rozpinające, tzn. takie drzewo <V, T>
rozpinające grafu G, że suma kosztów jego krawędzi  eT c (e)
jest najmniejsza.
Uwaga Warunkiem koniecznym istnienia drzewa
rozpinającego grafu jest spójność!
dr Paweł Drozda
Przykład minimalne drzewo rozpinające
1
a
7
b
7
6
4
d
10
2
e
Jedno z drzew
dr Paweł Drozda
f
8
a
4
c
5
1
7
b
7
6
4
c
5
d
10
2
4
e
f
8
Minimalne drzewo
rozpinające
Algorytm Prima
Idea algorytmu
1.
Wybieramy dowolnie korzeń szukanego drzewa rozpinającego
2. W każdym kroku algorytmu wybieramy krawędź lekką – tzn.
łączącą powstałe do tej pory drzewo z jednym z pozostałych
wierzchołków najmniejszym kosztem
1
a
Krawędź lekka (c,d)
7
7
6
4
5
10
2
4
c
d
dr Paweł Drozda
b
e
f
8
Przykład - algorytm Prima
2
a
7
b
4
6
1
c
10
3
GRAF
d
2
e
5
4
f
5
g
Start – wierzchołek g:
Kolejne wierzchołki:
g-f-c-d-e-b-a
dr Paweł Drozda
a-> b, c
b -> a, c, d
c -> a, b, d, e, f
d -> b, c, e, g
e -> c, d, f
f -> c, e, g
g -> f, d
Kolejne krawędzie:
(f, g); (c, f); (c, d); (d,e);
(b, c); (a, b)
Kodowanie – algorytm Prima
Dla każdego u  V
k[u] = ∞
p[u]= NIL
k[s]=0
Q=V
while Q not empty
u = EXTRACT–MIN(Q)
dla każdego v=sąsiada(u)
if v  Q i w(u,v) < k[v]
then p[v] = u
k[v] = w(u,v)
dr Paweł Drozda
Algorytm Kruskala
Jeśli drzewo rozpinające ma mieć koszt minimalny i ma zawierać dany
las drzew, to musi też zawierać krawędź e, której koszt jest najmniejszy
wśród wszystkich krawędzi nie należących do żadnego z drzew i która
łączy dwa wierzchołki z różnych drzew.
• Utworzyć kolejkę priorytetową PQ z wszystkimi krawędziami
grafu, uporządkowanymi ze względu na koszt.
• Utworzyć początkowy podział Po zbioru V jako rodzinę
jednoelementowych zbiorów {x}, gdzie x V (stanowiący las
początkowy).
• Przeglądać kolejno elementy kolejki i jeżeli końce rozważanej
krawędzi należą do różnych zbiorów podziału, to krawędź
dołączyć do tworzonego drzewa, a zbiory podziału połączyć.
dr Paweł Drozda
Algorytm Kruskala – przykład
2
a
7
b
4
6
1
c
10
3
d
2
e
9
4
f
dr Paweł Drozda
8
g
Szeregowanie krawędzi
(c,d)=1
(d,e)=2
(a,b)=2
(c,f)=3
(b,c)=4
(e,f)=4
(b,d)=6
(a,c)=7
(f,g)=8
(d,g)=9
(c,e)=10
krawędzie wybrane
(c,d)=1
(d,e)=2
(a,b)=2
(c,f)=3
(b,c)=4
(e,f)=4
(b,d)=6
(a,c)=7
(f,g)=8
(d,g)=9
(c,e)=10
Kodowanie – Algorytm Kruskala
A = zbiór pusty
dla każdego v  V
stwórz oddzielny zbiór
posortuj krawędzie niemalejąco względem wag
dla każdej krawędzi e według niemalejących wag
jeśli u,v należą do różnych zbiorów
A =A + {(u,v)}
połącz zbiory z u i v
dr Paweł Drozda
Wyszukiwanie najkrótszej ścieżki
 Wyznaczenie najkrótszych ścieżek o wspólnym początku
 Algorytm Dijkstry (zachłanny) dla grafów ważonych:
 wagi są nieujemne
 brak krawędzi oznaczany jest przez „odpowiednio dużą” wagę
 Q – zbiór wierzchołków, do których nie jest znana optymalna
droga
 D – tablica z najmniejszymi odległościami od wierzchołka do
źródła
 P – tablica zawierająca nr poprzedzającego wierzchołka na
najkrótszej drodze
dr Paweł Drozda
Algorytm Dijkstry
Dijkstra(G,s):
foreach wierzchołek w
begin
d[w] = ∞;
p[w] = -1;
end
d[s] = 0;
Q = V;
while ~empty(Q) do
begin
u = wyjmij_min(Q);
foreach sasiad wierzcholka u
begin
alt = d[u]+koszt(u,sasiad);
if alt<d[sasiad] then
begin
d[sasiad] = alt;
p[sasiad] = u;
end
end
end
dr Paweł Drozda
1
10
100
30
2
50
5
60
10
3
20
4
Algorytm Bellmana – Forda
 Najkrótsze ścieżki z jednego źródła
 Wagi mogą być ujemne
 p[] – tablica poprzedników
 d[] – odległość od źródła
 informuje czy da się wyznaczyć najkrótsze ścieżki –
czy nie zawiera cykli ujemnych
dr Paweł Drozda
Kodowanie – algorytm Bellmana - Forda
dla każdego v  V
p[v] = nil
d[v] = ∞
for i=1 to |V| - 1
dla każdej krawędzi e(u,v)  E
if d[v] > d[u] +w(u,v)
d[v] = d[u] +w(u,v)
p[v] = u
dla każdej krawędzi e(u,v)  E
if d[v] > d[u] +w(u,v) RETURN FALSE
RETURN TRUE
dr Paweł Drozda
Ścieżka Eulera
 Ścieżka przechodząca przez wszystkie krawędzie dokładnie raz
 Graf nieskierowany


eulerowski – jeżeli wszystkie wierzchołki grafu (nieskierowanego) mają stopień
parzysty, to da się skonstruować cykl Eulera
półeulerowski – jeżeli najwyżej dwa wierzchołki mają nieparzysty stopień, to
możliwe jest zbudowanie ścieżki Eulera
 Graf skierowany


eulerowski – wszystkie wierzchołki z wyjątkiem dwóch mają takie same stopnie
wychodzące i wchodzące
półeulerowski – wszystkie wierzchołki z wyjątkiem dwóch mają takie same
stopnie wychodzące i wchodzące, w jednym z tych dwóch wierzchołków stopień
wychodzący jest o 1 większy niż wchodzący a w drugim odwrotnie
dr Paweł Drozda
Algorytm
 Zbadać czy graf jest spójny
 Zbadać stopnie wierzchołków grafu
O(|V|+|E|)+O(|V|+|E|) = O(|V|+|E|)
 Przejdź graf zaczynając od wierzchołka o
nieparzystym stopniu (jeżeli jest)
dr Paweł Drozda
Problem kojarzenia małżeństw
 Graf dwudzielny – graf, w którym możemy podzielić
wierzchołki na 2 podzbiory tak, że nie istnieje krawędź
łącząca 2 wierzchołki z tego samego podzbioru
dr Paweł Drozda
Problem kojarzenia małżeństw
Problem małżeństw jest rozwiązywalny, jeśli każdy podzbiór k
panien, akceptuje jako przyszłych mężów co najmniej k
kawalerów, gdzie k ≤ n.
Filip
Anna
dr Paweł Drozda
Gustaw
Henryk
Beata
Celina
Igor
Danuta
Jan
Ewa