Algorytmy grafowe (AGR 320)
semestr letni 2004/2005
Michał Karo ´nski
Wydział Matematyki i Informatyki UAM
1. Rodzaje grafów
grafy proste multigrafy
grafy skierowane (digrafy)
grafy wa˙zone
2. Reprezentacje grafów
2.1 Macierz przyległo´sci (s ˛asiedztwa)
Definicja (Macierz przyległo´sci). Dany jest graf G = (V, E), przy
czym V = {v1, v2, . . . , vn} jest zbiorem wierzchołków, to n × n
macierz A(G) = (aij), gdzie aij jest liczb ˛a kraw ˛edzi ł ˛acz ˛acych wierzchołki vi oraz vj nazywa si ˛e macierz ˛a przyległo´sci grafu G.
W przypadku grafu skierowanego aij jest liczb ˛a łuków z wierzchołka
vi do vj.
s
s s
s
s
@@
@@@
v1 v2
v3
v4
v5
@@
@@@
Rysunek 1:
Przykład grafu prostego G = (V, E), gdzie V =Przykład . Macierz przyległo´sci dla grafu przedstawionego na Rysunku 1.
A(G) =
v1 v2 v3 v4 v5 v1 0 1 0 1 0 v2 1 0 1 1 1 v3 0 1 0 1 0 v4 1 1 1 0 1 v5 0 1 0 1 0
=
0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0
.
macierz przyległo´sci (s ˛asiedztwa) A(G) jest macierz ˛a binarn ˛a (dla grafu prostego)
macierz przyległo´sci wymaga |V |2 = n2 bitów pami ˛eci je˙zeli w jest długo´sci ˛a słowa maszynowego, to ka˙zdy wiersz macierzy przyległo´sci mo˙zna zapisa´c jako ci ˛ag n bitów w dn/we słowach maszynowych (dxe oznacza
najmniejsz ˛a liczb ˛e całkowit ˛a nie mniejsz ˛a ni˙z x)
graf prosty: A(G) jest symetryczna - n(n − 1)/2 bitów graf skierowany: ndn/we
2.2 Macierz incydencji
Definicja (Macierz incydencji). Dany jest graf G = (V, E), przy czym
V = {v1, v2, . . . , vn} jest zbiorem wierzchołków natomiast
E = {e1, e2, . . . , em} zbiorem kraw ˛edzie grafu, to macierz
M (G) = (mij)1, 1 6 i 6 n, 1 6 j 6 m, gdzie liczba
mij ∈ {0, 1, 2} oznacza ile razy vi oraz ej s ˛a incydentne ( 2 wyst ˛epuje w przypadku p ˛etli), jest macierz ˛a incydencji grafu G.
s
s s
s
s
@@
@@@
v1 v2
v3
v4
v5 e1
e2 e3 e4
e5
@@
@@@
e6 e7
Przykład . Macierz incydencji dla grafu przedstawionego na Rysunku 1.
G = (V, E): |V | = 5, |E| = 7, V = {v1, v2, v3, v4, v5}, E = {e1, e2, e3, e4, e5, e6, e7}, e1 = v1v2, e2 = v2v3, e3 = v2v5, e4 = v3v4, e5 = v2v4, e6 = v4v5, e7 = v1v4.
M (G) =
e1 e2 e3 e4 e5 e6 e7
v1 1 0 0 0 0 0 1
v2 1 1 1 0 1 0 0
v3 0 1 0 1 0 0 0
v4 0 0 0 1 1 1 1
v5 0 0 1 0 0 1 0
Macierz incydencji wymaga |V ||E| bitów pami ˛eci, co mo˙ze by´c liczb ˛a wi ˛eksz ˛a ni˙z |V |2 bitów zajmowanych przez macierz przyległo´sci, poniewa˙z liczba kraw ˛edzi
|E| jest cz ˛esto wi ˛eksza ni˙z liczba wierzchołków |V |. W niektórych jednak przypadkach mo˙ze by´c
korzystniejsze u˙zycie macierzy incydencji, ni˙z macierzy przyległo´sci pomimo zwi ˛ekszonej zaj ˛eto´sci pami ˛eci.
Macierze incydencji s ˛a szczególnie dogodne przy rozpatrywaniu obwodów elektrycznych i układów przeł ˛aczaj ˛acych.
2.3 Lista kraw ˛edzi
Innym, cz ˛esto stosowanym sposobem reprezentacji grafu jest wypisanie wszystkich jego kraw ˛edzi jako par wierzchołków. Tak na przykład, graf z Rysunku 1 byłby przedstawiony jako lista nast ˛epuj ˛acych
nieuporz ˛adkowanych par:
(v1, v2), {v1, v4}, {v2, v3}, {v2, v4}, {v2, v5}, {v3, v4}, {v4, v5}.
Dla grafu skierowanego, były by to uporz ˛adkowane pary wierzchołków odpowiadaj ˛ace łukom.
liczba bitów potrzebna do zaetykietowania (etykietami od 1 do n) wierzchołków grafu G jest równa b, gdzie 2b−1 < n 6 2b, czyli b = blog2 nc + 1
całkowita zaj ˛eto´s´c pami ˛eci jest równa 2|E|b bitów
ten sposób reprezentacji jest bardziej ekonomiczny ni˙z macierz przyległo´sci, je˙zeli 2|E|b < |V |2
reprezentacja “listowa" jest korzystniejsza dla grafów rzadkich
przechowywanie i przekształcanie grafu w komputerze
2.4 Dwie tablice liniowe
modyfikacj ˛a listy kraw ˛edzi - przedstawienie grafu za pomoc ˛a dwóch tablic liniowych:
F = (f1, f2, . . . , fe) , H = (h1, h2, . . . , he).
elementy tablic: etykiety wierzchołków, e = |E|
G graf skierowany: i-ty łuk, ei, prowadzi od wierzchołka fi, do wierzchołka hi
G graf nieskierowany: kraw ˛ed´z ei ł ˛aczy fi i hi . dogodna reprezentacja do sortowania w grafach wa˙zonych
Przykład . Dwie tablice liniowe dla grafu przedstawionego na Rysunku 1.
s
s s
s
s
@@
@@@
v1 v2
v3
v4 e1
e2 e3 e4
e5
@@
@
@@
e6 e7
2.5 Lista wierzchołków s ˛asiednich (nast ˛epników) efektywna metoda reprezentacji grafów stosowana w przypadku gdy stosunek |E|/|V | nie jest du˙zy
dla ka˙zdego wierzchołka v tworzymy list ˛e (tablic ˛e), której pierwszym elementem jest v; a pozostałymi elementami s ˛a:
wierzchołki b ˛ed ˛ace s ˛asiadami wierzchołka v (w przypadku grafu nieskierowanego)
bezpo´sredni nast ˛epnicy wierzchołka v, tzn.
wierzchołki, do których istnieje łuk z wierzchołka v (w przypadku grafu skierowanego)
s
s s
s
s
@@
@@@
v1 v2
v3
v4
v5
@@
@@@
v1 : v2, v4
v2 : v1, v3, v4, v5
1 2
3 4
5
6
1 2 3 4 5 6
6 2
1 1 2 4 2
3 3 2 3 6 5
4 4 5
1 2
3 4
5
6
1 2 3 4
2
1 2 4
4 6
5
3. Przeszukiwanie grafów
Znajduj ˛ac si ˛e w pewnym wierzchołku v przeszukujemy wszystkie kraw ˛edzie incydentne do v, a nast ˛epnie
poruszamy si ˛e do pewnego wierzchołka przyległego w. W wierzchołku w przeszukujemy wszystkie kraw ˛edzie incydentne do w. Ten proces prowadzi si ˛e dot ˛ad, a˙z
przeszuka si ˛e wszystkie wierzchołki w grafie. Metod ˛e t ˛e nazywa si ˛e przeszukiwaniem wszerz (ang. breadth-first search, cz ˛esto oznaczane skrótowo BFS).
zamiast przeszukiwa´c ka˙zd ˛a kraw ˛ed´z incydentn ˛a do wierzchołka v, poruszamy si ˛e do pewnego wierzchołka przyległego w (wierzchołka, w którym dotychczas
jeszcze nie byli´smy), gdy tylko to jest mo˙zliwe, pozostawiaj ˛ac na razie wierzchołek v z by´c mo˙ze
niezbadanymi kraw ˛edziami. Inaczej mówi ˛ac, pod ˛a˙zamy przez graf ´scie˙zk ˛a przechodz ˛ac do nowego
wierzchołka, gdy tylko to jest mo˙zliwe. Taka metoda przeszukiwania grafu, zwana przeszukiwaniem w gł ˛ab (ang. depth-first search, w skrócie DFS) lub metod ˛a powrotu po tej samej ´scie˙zce na grafie.
3.1 Przeszukiwanie grafu wszerz (BFS)
G = (V, E) - graf nieskierowanym reprezentowanym w postaci listy wierzchołków s ˛asiednich.
x - ustalony wierzchołek z którego nale˙zy rozpocz ˛a´c przeszukiwanie grafu
Iv - tablica zawieraj ˛aca wierzchołki incydentne z v N Iv liczba elementów w Iv
1. Ustaw: N umer[x] ← 1, Drzewo ← ∅, P ozostale ← ∅; dopisz x do Kolejki.
2. Je˙zeli Kolejka jest pusta to STOP.
3. Pobierz element z Kolejki i zapisz go jako v.
4. Dla ka˙zdego wierzchołka w incydentnego do v wykonaj:
(a) Je˙zeli N umer[w] = 0, tzn. wierzchołek w
odwiedzamy po raz pierwszy, to nadaj wierzchołkowi w kolejny numer, dopisz w do Kolejki, a kraw ˛ed´z vw dodaj do Drzewo.
(b) Je˙zeli N umer[w] 6= 0, tzn. wierzchołek w ju˙z był
(G, x)
N umer[x] ← P onumerowano ← 1
N Kolejka ← 1; Kolejka[N Kolejka] ← x
N Kolejka > 0
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
i ← 1 N Kolejka
Kolejka[i] ← Kolejka[i + 1]
i ← 1 N Iv
w ← Iv[i]
N umer[w] = 0
P onumerowano ← P onumerowano + 1
N umer[w] ← P onumerowano
Drzewo ← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1
Kolejka[N Kolejka] ← w
← ∪ {vw}
N umer, Drzewo,
" #
$ % & ' ( ) * +, +, - . / 0 1 2
G, x
3
$ # % 4 5 #
N umer, Drzewo, 6 7 8 7 9 :; <=
2 > 3
N umer[x] ← P onumerowano ← 1
2 ? 3
N Kolejka ← 1; Kolejka[N Kolejka] ← x 2 @ 3
A ) ' #B
N Kolejka > 0 2 C 3
D %
v ← Kolejka[1] 2 E 3
N Kolejka ← N Kolejka − 1 2 F 3
G % &
i ← 1 ( % N Kolejka
2 H 3
D %
Kolejka[i] ← Kolejka[i + 1] 2 I 3
G % &
i ← 1 ( % N Iv
2 J 3
D
w ← Iv[i] 2 > K 3
' G
N umer[w] = 0 2 > > 3
P onumerowano ← P onumerowano + 1 2 > ? 3 N umer[w] ← P onumerowano 2 > @ 3
Przykład . Przeszukiwanie grafu wszerz
O P Q R S T U V W XY X Z [ \ ] ^
G, x
_
Q P R ` a P
N umer, Drzewo, b c d c e f g h i N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
j V T P k
N Kolejka >0
l R
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
m R S
i ← 1 U R N Kolejka
l R
Kolejka[i] ← Kolejka[i + 1]
m R S
i ← 1 U R N Iv
l R
w ← Iv[i]
T m
N umer[w] = 0
U V k n
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
k P o k b c d c e f g h i
← b c d c e f g h i∪ {vw}
S k U p S n
(N umer, Drzewo, b c d c e f g h i)
q r s tu v w x y s tz
a= 1
b c
d e f g
N umer[a] ← 1 P onumerow← 1
Kolejka← a
← 1
{ | } ~
G, x
} | ~ |
N umer, Drzewo,
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
|
N Kolejka >0
~
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
~
i ← 1 ~ N Kolejka
~
Kolejka[i] ← Kolejka[i + 1]
~
i ← 1 ~ N Iv
~
w ← Iv[i]
N umer[w] = 0
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
|
← ∪ {vw}
(N umer, Drzewo, )
¡ ¢£ ¤ ¢¥ ¦£ § ¨ © ª «
a
a= 1
b= 2 c= 3
d e f g
v ← a Kolejka ← ∅ N Kolejka ← 0 w ← b
P onumerow ← 2 N umer[b] ← 2
{ | } ~
G, x
} | ~ |
N umer, Drzewo,
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
|
N Kolejka >0
~
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
~
i ← 1 ~ N Kolejka
~
Kolejka[i] ← Kolejka[i + 1]
~
i ← 1 ~ N Iv
~
w ← Iv[i]
N umer[w] = 0
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
|
← ∪ {vw}
(N umer, Drzewo, )
¬ ® ¯ ° ± ² ³ ´ µ¶ µ · ¸ ¹ º »
G, x
¼
® ¯ ½ ¾
N umer, Drzewo, ¿ À Á À Â Ã Ä
Å Æ
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
Ç ³ ± È
N Kolejka >0
É ¯
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
Ê ¯ °
i ← 1 ² ¯ N Kolejka
É ¯
Kolejka[i] ← Kolejka[i + 1]
Ê ¯ °
i ← 1 ² ¯ N Iv
É ¯
w ← Iv[i]
± Ê
N umer[w] = 0
² ³ È Ë
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
È Ì È ¿ À Á À Â Ã Ä Å Æ
← ¿ À Á À Â Ã Ä Å Æ∪ {vw}
° È ² Í ° Ë
(N umer, Drzewo, ¿ À Á À Â Ã Ä Å Æ)
Î Ï Ð Ñ Ò ÓÔ Ñ Õ ÓÖ ×Ô Ø Ù Ú Û Ü Ñ
b
a= 1
b= 2 c= 3
d= 4 e= 5 f g
v ← b Kolejka ← c N Kolejka ← 1 w ← a w ← c w ← d
P onumerow← 4 N umer[d] ← 4 Drzewo ← {ab, ac, Kolejka← c, d N Kolejka ← 2
w ← e
P onumerow← 5 N umer[e] ← 5 Drzewo ← {ab, ac, bd, Kolejka← c, d, e N Kolejka ← 3
w ← f
Ý Þ ß à á â ã ä å æç æ è é ê ë ì
G, x
í
ß Þ à î ï Þ
N umer, Drzewo, ð ñ ò ñ ó ô õ
ö ÷
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
ø ä â Þ ù
N Kolejka >0
ú à
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
û à á
i ← 1 ã à N Kolejka
ú à
Kolejka[i] ← Kolejka[i + 1]
û à á
i ← 1 ã à N Iv
ú à
w ← Iv[i]
â û
N umer[w] = 0
ã ä ù ü
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
ù Þ ý ù ð ñ ò ñ ó ô õ ö ÷
← ð ñ ò ñ ó ô õ ö ÷∪ {vw}
á ù ã þ á ü
(N umer, Drzewo, ð ñ ò ñ ó ô õ ö ÷)
ÿ
c
a= 1
b= 2 c= 3
d= 4 e= 5 f = 6 g = 7
v ← c Kolejka ← d, e, f N Kolejka← 3 w ← a w ← b w ← f w ← g P onumerow← 7 N umer[g] ← 7
Drzewo← {ab, ac, bd, be, bf, cg}
G, x
N umer, Drzewo, ! " # " $ % &
' (
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
) *
N Kolejka >0
+
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
,
i ← 1 N Kolejka
+
Kolejka[i] ← Kolejka[i + 1]
,
i ← 1 N Iv
+
w ← Iv[i]
,
N umer[w] = 0
* -
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
* . * ! " # " $ % & ' (
← ! " # " $ % & ' (∪ {vw}
* / -
(N umer, Drzewo, ! " # " $ % & ' ()
0 1 2 3 4 56 3 7 58 96 : ; < = > 3
d
a= 1
b= 2 c= 3
d= 4 e= 5 f = 6 g = 7
v ← d Kolejka ← e, f, g N Kolejka ← 3 w ← b w ← e
? @ A B C D E F G HI H J K L M N
G, x
O
A @ B P Q @
N umer, Drzewo, R S T S U V W
X Y
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
Z F D @ [
N Kolejka >0
\ B
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
] B C
i ← 1 E B N Kolejka
\ B
Kolejka[i] ← Kolejka[i + 1]
] B C
i ← 1 E B N Iv
\ B
w ← Iv[i]
D ]
N umer[w] = 0
E F [ ^
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
[ @ _ [ R S T S U V W X Y
← R S T S U V W X Y∪ {vw}
C [ E ` C ^
(N umer, Drzewo, R S T S U V W X Y)
a b c d e fg d h fi jg k l m n o d
e
a= 1
b= 2 c= 3
d= 4 e= 5 f = 6 g = 7
v ← e Kolejka ← f, g N Kolejka ← 2 w ← b w ← d w ← f
p q r s t u v w x yz y { | } ~
G, x
r q s q
N umer, Drzewo,
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
w u q
N Kolejka >0
s
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
s t
i ← 1 v s N Kolejka
s
Kolejka[i] ← Kolejka[i + 1]
s t
i ← 1 v s N Iv
s
w ← Iv[i]
u
N umer[w] = 0
v w
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
q
← ∪ {vw}
t v t
(N umer, Drzewo, )
f
a= 1
b= 2 c= 3
d= 4 e= 5 f = 6 g = 7
v ← f Kolejka← g N Kolejka ← 1 w ← b w ← c w ← g
¡ ¢ £ ¤ ¥ ¦ § ¨ © ª« ª ¬ ® ¯ °
G, x
±
£ ¢ ¤ ² ³ ¢
N umer, Drzewo, ´ µ ¶ µ · ¸ ¹
º »
N umer[x] ← P onumerow ← 1
N Kolejka← 1; Kolejka[N Kolejka] ← x
¼ ¨ ¦ ¢ ½
N Kolejka >0
¾ ¤
v ← Kolejka[1]
N Kolejka ← N Kolejka − 1
¿ ¤ ¥
i ← 1 § ¤ N Kolejka
¾ ¤
Kolejka[i] ← Kolejka[i + 1]
¿ ¤ ¥
i ← 1 § ¤ N Iv
¾ ¤
w ← Iv[i]
¦ ¿
N umer[w] = 0
§ ¨ ½ À
P onumerow ← P onumerow + 1 N umer[w] ← P onumerow Drzewo← Drzewo ∪ {vw}
N Kolejka ← N Kolejka + 1 Kolejka[N Kolejka] ← w
½ ¢ Á ½ ´ µ ¶ µ · ¸ ¹ º »
← ´ µ ¶ µ · ¸ ¹ º »∪ {vw}
¥ ½ § Â ¥ À
(N umer, Drzewo, ´ µ ¶ µ · ¸ ¹ º »)
Ã Ä Å Æ Ç ÈÉ Æ Ê ÈË ÌÉ Í Î Ï Ð Ñ Æ
g
a= 1
b= 2 c= 3
d= 4 e= 5 f = 6 g = 7
v ← g Kolejka← ∅ N Kolejka ← 0 w ← c w ← f
3.2 Przeszukiwanie grafu w gł ˛ab (DFS)
G = (V, E) - graf nieskierowanym reprezentowanym w postaci listy wierzchołków s ˛asiednich.
x - ustalony wierzchołek z którego nale˙zy rozpocz ˛a´c przeszukiwanie grafu
Iv - tablica zawieraj ˛aca wierzchołki incydentne z v, N Iv liczba elementów w Iv
Stos - tablica przechowuj ˛aca ci ˛ag wierzchołków
umo˙zliwiaj ˛aca “powrót", N Stos - liczba wierzchołków w Stos
1. Ustaw v ← x, i ← 0, Drzewo ← ∅, P ozostale ← ∅. 2. Ustaw i ← i + 1, N umer(v) ← i.
3. Poszukaj nieprzebytej kraw ˛edzi incydentnej do wierzchołka v.
Je˙zeli nie ma takiej kraw ˛edzi (tzn. po ka˙zdej kraw ˛edzi incydentnej do v ju˙z przeszli´smy), to przejd´z do kroku 5.
Wybierz pierwsz ˛a nieprzebyt ˛a kraw ˛ed´z incydentn ˛a do
4. Jeste´smy teraz w wierzchołku w.
Je˙zeli w jest wierzchołkiem, w którym jeszcze nie byli´smy podczas tego szukania (tzn. N umer(w) jest nieokre´slony), to dodaj kraw ˛ed´z vw do zbioru Drzewo. Ustaw v ← w i przejd´z do kroku 2.
Je˙zeli w jest wierzchołkiem, w którym ju˙z wcze´sniej
byli´smy (tzn. N umer(w) < N umer(v)), to dodaj kraw ˛ed´z vw do zbioru P ozostale. Przejd´z do kroku 3. Jeste´smy wi ˛ec z powrotem w wierzchołku v.