Documente Academic
Documente Profesional
Documente Cultură
1
1.1
Algoritmi elementari
Introducere
Def Se numeste graf sau graf neorientat o structura G = (V, E), unde V 6=
este o multime de varfuri si E este o submultime posibil vida a multimii perechilor
neordonate cu componente distincte din V .
Obs:
1. Graful G = (V, E) este graf finit, daca V este o multime finita.
2. Varfurile u, v sunt adiacente in G daca [u, v] E. Intr-un graf neorientat relatia
de adiacenta este simetrica. Se spune si ca muchia [u, v] este incidenta varfurilor u
si v.
3. Intr-un graf neorientat [u, v] si [v, u] sunt considerate a fi aceeasi muchie.
Def Gradul unui varf al unui graf neorientat este nr muchiilor incidente ale acestuia.
Obs: Varful u este izolat daca gradul sau este 0.
Def Un graf orientat sau digraf G este o pereche (V, E) unde V - multimea varfurilor lui G este o multime finita, iar E este o relatie binara pe V . Elementele multimii E se numesc arce. Spunem ca arcul (u, v) este incident din sau pleaca din
varful u si este incident in sau intra in varful v.
Def Un arc care pleaca dintr-un nod u si intra in acelasi nod u se numeste autobucla.
1.2
Reprezentarea grafurilor
Parcurgerea in latime
Parcurgerea in latime sta la baza multor algoritmi importanti din teoria grafurilor,
dintre care amintim Algoritmul lui Prim de gasire a arborelui partial de cost minim
al unui graf conex ponderat, sau Algoritmul lui Dijkstra de stabilire a drumului de
cost minim de la un nod de start la oricare altul dintr-un graf.
Fie G = (V, E) si un varf sursa s. Algoritmul de parcurgere in latime (BF) calculeaza distanta (numarul de muchii) dintre varful sursa si fiecare varf la care se
poate ajunge de la s si construieste un arbore de latime (BF) cu radacina in s.
Algoritmul poate fi aplicat atat pe grafuri neorientate cat si pe digrafuri.
Parcurgerea in adancime (BF) gaseste toate varfurile aflate la o distanta k de s inainte de a cauta varfurile de la distanta k + 1.
Figure 3: Parcurgerea in latime (BFS) a unui graf neorientat. Muchiile arborelui sunt
marcate cu rosu pe masura ce se avanseaza.Valoarea lui u.d este calculata pentru
fiecare varf u. Coada Q este afisata la inceputul fiecarei iteratii din ciclul while liniile 10-18. Distanta asociata fiecarui varf este scrisa sub varful introdus in coada.
Procedura BFS este construita astfel:
1. fiecare varf, cu exceptia sursei s, are urmatoarele proprietati: culoare = alb,
distanta = infinit si predecesorul = NIL (liniile 1 - 4);
2. s se coloreaza in gri considerandu-se gasit la inceputul procedurii (linia 5),
atributul distanta devine 0 (linia 6) si predecesorul sursei devine NIL (linia 7);
3. se initializeaza coada Q si se introduce varful sursa (liniile 8 - 9);
4. structura repetitiva while (liniile 10 - 18) se executa atata timp cat exista
varfuri gri (varfuri care sunt descoperite, dar listele lor de adiacenta nu au fost
parcurse in intregime). Invariantul instructiunii repetitive este coada Q care
contine doar varfuri gri (linia 10):
- inaintea primei iteratii Q contine singurul varf gri s;
- se determina u capul cozii si se elimina (linia 11);
- fiecare varf v din lista de adiacenta a nodului u este considerat in structura
repetitiva for (liniile 12 - 17). Daca v este alb (nu a fost inca vizitat) procedura il marcheaza ca gasit (liniile 14 - 17), il coloreaza gri, ii seteaza distanta
ca distanta predecesorului + 1, inregistreaza pe u drept predecesor al lui v si
il introduce pe v in coada.
- u devine negru - toate varfurile adiacente lui au fost vizitate (linia 18).
Analiza complexitatii
Odata lansat in executie algoritmul BFS nu coloreaza niciodata in alb un varf
si deci, testul din linia 13 asigura ca fiecare varf este introdus in coada, si implicit
scos din coada cel mult o data. Operatiile specifice cozii ruleaza in timp O(1), deci
timpul total alocat cozii este O (V).
Deoarece procedura parcurge lista de adiacenta a fiecarui varf doar cand acesta este
scos din coada, parcurgerea listelor se face cel mult o data. Cum suma tuturor
lungimilor listelor de adiacenta este (E), timpul total alocat parcurgerii listelor de
adiacenta este O(E). Initializarea se face in timp O(V) si deci timpul total al rularii
procedurii BFS este O(V+E). Parcurgerea in latime BF ruleaza in timp linear in
cazul unui graf dat prin liste de adiacenta.
Drumul minim
Def Se defineste distanta minima (s, v) de la s la v astfel:
(
numarul minim de muchii de la s la v, daca drum de la s la v
(s, v) =
, altfel.
Lema 1 Fie G = (V, E) un graf neorientat si s V un varf orecare. Atunci, pentru
[u, v] E,
(s, v) (s, u) + 1.
(1)
Demonstratie Daca drum de la s la u, atunci exista drum si de la s la v. In acest
caz, drumul minim de la s la v nu poate fi mai lung decat drumul minim de la s la
u plus muchia [u, v].
Daca @ drum de la u la s, atunci (s, u) = .
(2)
In momentul in care varful u este scos din coada, varful v este alb, gri sau negru.
In fiecare din aceste cazuri contradictia va fi aratata. Daca v este alb, linia 15 din BFS
implica v.d = u.d + 1 contrazicand inegalitatea 2. Daca este negru, atunci inseamna
ca a fost deja scos din coada si conform Corolarului v.d u.d, iarasi contrazicand
2. Daca v este gri, atunci un varf oarecare w pentru care v.d = w.d + 1 a fost scos
din coada. Corolarul implica w.d u.d si deci se obtine v.d = w.d + 1 u.d + 1
contrazicand 2.
Concluzionand, se poate observa ca daca v. = u, atunci v.d = u.d + 1 si deci,
se poate obtine drumul minim de la s la v luand drumul minim de la s la v. si
adaugand muchia [v., v].
2.1
Procedura BFS construieste un arbore pe masura ce graful G = (V, E) este parcurs. Arborele corespunde atributelor (precedentilor). Mai formal, pentru un graf
G = (V, E) cu varful sursa s, se defineste graful predecesor al lui G astfel:
G = (V , E ), unde V = {v V : v. 6= N IL} {s}
and E = {[v., v] : v V {s}}.
Graful predecesor G este un arbore in latime daca V contine varfurile la care
se poate ajunge pornind de la s si, pentru v V., graful G contine un drum
minim unic de la s la v. Un arbore de latime este un arbore deoarece este conex si
|E.| = |V.| 1.
Lema 6 Graful predecesor G = (V , E ), obtinut prin BFS pornind de la graful
initial, este arbore de latime.
Demonstratie:
v. = u = [u, v] E si (s, v) < (linia 16 dn BFS). V contine varfurile v la care
se poate ajunge pornind de la sursa s. Cum G este arbore, atunci contine un drum
minim unic de la s la fiecare varf din V . Aplicand inductiv Teorema 1 se poate
demonstra ca fiecare asfel de drum este drum minim in G.
Procedura PRINT-PATH afiseaza varfurile celui mai mic drum de la s la v,
presupunand ca BFS a creat deja un arbore de latime.
1
2
3
4
5
6
PRINT-PATH (G,s,v)
if v = s
print s
elseif v. N IL
print no path from s to v exists
else PRINT-PATH (G,s,v.)
print v
10
Parcurgerea in adancime
Algoritmul de parcurgere in adancime (DFS) exploreaza muchiile incidente (nemarcate) ale celui mai recent varf descoperit v. Daca toate muchiile incidente varfului v
au fost explorate, se face cautarea muchiilor neexplorate ale varfului anterior de la
care v este descoperit in urma parcurgerii DFS. Procesul continua pana cand toate
varfurile la care se poate ajunge de la sursa s, au fost descoperite.
Obs Daca raman varfuri nedescoperite (graful nu este conex), DFS selecteaza
unul dintre ele drept noua sursa si repeta cautarea pornind de la el. Algoritmul
se repeta pana cand toate nodurile au fost descoperite. Ca si in cazul algoritmului de parcurgere in latime (BFS), atributul ia valoarea predecesorului varfului v
(v. = u) cand procedura DFS descopera un varf v in urma parcurgerii listei de
adiacenta a unui nod deja vizitat u.
Obs Spre deosebire de BFS unde subgraful predecesor era un arbore, in cazul
DFS el poate fi format din mai multi arbori deoarece cautarea se poate face pornind
de la mai multe surse. Astfel ca definitia unui graf predecesor difera usor fata de
BF: G = (V, E ) unde E = {[v., v] : v V si v. 6= N IL}.
Subgraful predecesor obtinut printr-un DFS formeaza o padure de adancime (DF)
continand cativa arbori de adancime. Muchiile din E reprezinta muchiile arborelui.
Ca si in cazul BFS, algoritmul DFS coloreaza varfurile pe masura ce sunt vizitate
pentru a indica starea. Fiecare varf este initial alb, devine gri cand este descoperit
in urma parcurgerii si negru cand lista lui de adiacenta a fost complet parcursa.
Aceasta tehnica garanteaza ca fiecare varf apare intr-un arbore de adancime unic si
deci arborii de adancime sunt disjuncti.
Algoritmul DFS eticheteaza temporal fiecare varf v astfel: v.d inregistreaza momentul in care varful este descoperit prima data (si colorat in gri), iar v.f inregistreaza momentul in care lista de adiacenta a lui v a fost complet traversata (varful
devine negru).
Procedura DFS inregistreaza in atributul u.d momentul descoperirii si in atributul
u.f momentul terminarii procesarii lui u. Aceste marcaje sunt numere intregi intre
1 si 2|V | deoarece exista un eveniment unic de descoperire si de terminare u V :
u.d < u.f
11
(3)
Varful u este alb inaintea initierii momentului u.d, gri intre u.d si u.f si negru
dupa.
Pseudocod-ul urmator prezinta algoritmul DFS. Graful poate fi neorientat sau
orientat. Variabila time este folosita pentru etichetare.
1
2
3
4
5
6
7
DFS (G)
for each vertex u G.V
u.color W HIT E
u. N IL
time 0
for each vertex u G.V
if u.color = W HIT E
DFS VISIT(G, u)
1
2
3
4
5
6
7
8
9
10
DFS-VISIT(G,u)
time time + 1
u.d time
u.color GRAY
for each v G.Adj[u]
if v.color = W HIT E
v. u
DFS VISIT(G, v)
u.color BLACK
time time + 1
u.f time
12
13
14
Analiza complexitatii
Loop-urile liniilor 1 - 3 si, respectiv, 5 - 7 se realizeaza in timp (V ) independent
de timpul apelurilor procedurii DFS-VIZIT. Procedura DFS-VIZIT este apelata
exact o singura data v V deoarece varful u pe care se aplica procedura trebuie sa
fie alb, iar actiune a procedurii DFS este de a colora varful vizitat in gri. In timpul
unei executii a DFS-VIZIT(G,v) codul din liniile 4 - 7 se executa de |Adj[v]| ori.
Dar:
X
|Adj[v]| = (E),
vV
15