Documente Academic
Documente Profesional
Documente Cultură
Parcurgeri de grafuri
Cuprins
Introducere .................................................................................................................... 20
Obiectivele modului ...................................................................................................... 20
U1. Parcurgerea generică ............................................................................................. 21
U2. Parcurgerea în lăţime ............................................................................................. 33
U3. Parcurgerea în adâncime ........................................................................................ 43
U4. Aplicaţii ale parcurgerilor ...................................................................................... 56
Introducere
În acest modul ne vom ocupa de problema parcurgerii unui digraf. Acestă
problemă constă în determinarea tuturor nodurilor accesibile dintr-un nod dat,
numit nod sursă. Problema parcurgerii unui graf poate apărea ca problemă de sine
stătătoare, dar şi ca subproblemă a unei probleme mai complexe.
Vom prezenta mai întâi parcurgerea generică, iar apoi cele mai cunoscute
implementări ale acesteia: parcurgerea în lăţime şi parcurgerea în adâncime. În
finalul modulului, ne vom îndrepta atenţia asupra următoarelor aplicaţii ale
parcurgerilor: determinarea componentelor conexe, determinarea componentelor
tare conexe şi sortarea topologică.
Competenţe
La sfârşitul acestui modul studenţii vor fi capabili să:
Parcurgă grafuri;
Determine componentele conexe ale unui graf orientat sau neorientat;
Determine componentele tare conexe ale unui graf orientat;
Sorteze topologic un digraf fără circuite.
20
Unitatea de învăţare M2.U1. Parcurgerea generică
Cuprins
M2.U1.1. Introducere .................................................................................................... 21
M2.U1.2. Obiectivele unităţii de învăţare ..................................................................... 22
M2.U1.3. Algoritmul de parcurgere generică ............................................................... 22
M2.U1.4. Algoritmul de parcurgere totală generică ..................................................... 27
M2.U1.5. Rezumat ........................................................................................................ 31
M2.U1.6. Test de evaluare a cunoştinţelor ................................................................... 31
M2.U1.1. Introducere
Problema parcurgerii unui digraf G = (N, A) constă în generarea mulţimii W
a nodurilor y accesibile dintr-un nod sursă dat s. Spunem că nodul y este accesibil
din nodul s în digraful G dacă există drum de la nodul sursă s la nodul y. Evident,
W ⊆ N.
Algoritmii pe care îi vom prezenta în acest modul pentru rezolvarea
problemei parcurgerii unui digraf G sunt metode sistematice de vizitare a nodurilor
y accesibile dintr-un nod sursă dat s. Fiecare iteraţie a execuţiei oricărui algoritm
de parcurgere stabileşte pentru fiecare nod apartenenţa la una din următoarele trei
stări:
• nevizitat,
• vizitat şi neanalizat, adică un nod vizitat ai cărui succesori au fost parţial
vizitaţi,
• vizitat şi analizat, adică un nod vizitat ai cărui succesori au fost în
totalitate vizitaţi.
Dacă nodul x este vizitat şi neanalizat, dacă există arc (x, y) şi dacă nodul y
este nevizitat, atunci se poate vizita nodul y. În acest caz se spune că arcul (x, y)
este arc admisibil şi dacă nodul y este vizitat explorând arcul (x, y) se spune că
nodul x este predecesorul-parcurgere al nodului y.
În acest modul se vor prezenta următorii algoritmi pentru parcurgerea unui
digraf: algoritmul generic de parcurgere, algoritmul de parcurgere în lăţime şi
algoritmul de parcurgere în adâncime. Aceşti algoritmi utilizează următoarele
notaţii comune:
21
U mulţimea nodurilor nevizitate;
V mulţimea nodurilor vizitate şi neanalizate;
W mulţimea nodurilor vizitate şi analizate;
p tabloul predecesor, care este unidimensional cu n elemente.
Se folosesc notaţiile precizate mai sus şi în plus notăm cu o tabloul ordine care este
unidimensional şi are n elemente.
Algoritmul parcurgerii generice (algoritmul PG) este următorul:
algoritm PG;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
k = 1; o(s) = 1;
for y∈ U do o(y) = ∞;
while V ≠ Ø do
begin
se selectează un nod x din V;
if există arc (x, y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; k = k+1; o(y) = k;
22
end
else
begin
V = V – {x}; W = W ∪ {x};
end;
end;
end.
23
end;
Fig. 2.1
24
W = {1, 2, 3, 5}.
Iteraţia 9: Se selectează nodul x = 4 din V. Obţinem V = Ø, W = {1, 2, 3, 4,
5} şi algoritmul se termină.
Fig. 2.2
Fig. 2.3
25
Iteraţia 1: Se selectează x = 1. Avem (1, 2)∈ A, 2∈ U, deci U = {3, 4, 5, 6},
V = {1, 2}, p = (0, 1, 0, 0, 0, 0), k = 2, o = (1, 2, ∞, ∞, ∞, ∞).
Iteraţia 2: Dacă dintre nodurile vizitate şi neanalizate a fost selectat nodul
x = 2, atunci, deoarece (2, 3)∈ A, 3 ∈ U, obţinem U = {4, 5, 6}, V = {1, 2, 3}, p =
(0, 1, 2, 0, 0, 0), k = 3, o = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Presupunem că se selectează nodul x = 1 din V, atunci V = {2, 3}
şi W = {1}.
Iteraţia 4: Considerăm că se selectează nodul x = 3 din V. Deoarece
(3, 5)∈ A, 5∈ U, obţinem U = {4, 6}, V = {2, 3, 5}, p = (0, 1, 2, 0, 3, 0), k = 4, o
= (1, 2, 3, ∞, 4, ∞).
Iteraţia 5: Presupunem că se selectează nodul x = 2 din V, atunci V = {3, 5}
şi W = {1, 2}.
Iteraţia 6: Considerăm că se selectează nodul x = 5 din V. Rezultă V = {3}
şi W = {1, 2, 5}.
Iteraţia 7: Se selectează x = 3, rezultă V = Ø şi W = {1, 2, 3, 5} şi algoritmul
se termină deoarece nu mai există noduri vizitate şi neanalizate.
Fig. 2.4
26
M2.U1.4. Algoritmul de parcurgere totală generică
În general, mulţimea W a nodurilor accesibile din nodul sursă dat este o submulţime a
mulţimii nodurilor N. Pentru parcurgerea întregului digraf G = (N, A) se utilizează algoritmul
parcurgerii totale generice (algoritmul PTG) prezentat în continuare.
algoritm PTG;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
k = 1; o(s) = 1;
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează un nod x din V;
if există arc (x, y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; k = k+1; o(y) = k;
end
else
begin
V = V – {x}; W = W ∪ {x};
end;
end;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; k = k+1; o(s) = k;
end;
end;
end.
27
Fie mulţimea S={s | s ∈ N, s este nod sursă selectat la începutul sau pe parcursul
execuţiei algoritmului}.
În parcurgerea totală generică, dacă subgraful predecesor Gp = (Np, Ap) cu Np ={y∈ N |
p(y) ≠ 0} ∪ S, Ap ={(p(y), y) | y∈ Np -S} este o pădure şi Np = W, atunci Gp se numeşte pădure
parcurgere.
Algoritmul PTG determină elementele tabloului p astfel încât subgraful predecesor Gp =
(Np, Ap) este o pădure parcurgere (adică este format din una sau mai multe arborescenţe
parcurgere).
Fig. 2.5
28
4}.
Iteraţia 6: Considerăm că se selectează nodul x = 2. Vom obţine V = {1} şi
W = {2, 3, 4}.
Iteraţia 7: Se selectează nodul x = 1 din V şi obţinem V = Ø, W = {1, 2, 3,
4} şi algoritmul se termină.
Fig. 2.6
Fig. 2.7
29
x = 2, atunci, deoarece (2, 3)∈ A, 3 ∈ U, obţinem U = {4, 5, 6}, V = {1, 2, 3}, p =
(0, 1, 2, 0, 0, 0), k = 3, o = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Presupunem că se selectează nodul x = 1 din V, atunci V = {2, 3}
şi W = {1}.
Iteraţia 4: Considerăm că se selectează nodul x = 3 din V. Deoarece
(3, 5)∈ A, 5∈ U, obţinem U = {4, 6}, V = {2, 3, 5}, p = (0, 1, 2, 0, 3, 0), k = 4, o
= (1, 2, 3, ∞, 4, ∞).
Iteraţia 5: Presupunem că se selectează nodul x = 2 din V, atunci V = {3, 5}
şi W = {1, 2}.
Iteraţia 6: Considerăm că se selectează nodul x = 5 din V. Rezultă V = {3}
şi W = {1, 2, 5}.
Iteraţia 7: Se selectează x = 3, rezultă V = Ø şi W = {1, 2, 3, 5} şi, deoarece
nu mai există noduri vizitate şi neanalizate, algoritmul va selecta un nou nod
sursă dintre nodurile încă nevizitate. Fie acesta nodul 4. Deci, s = 4, U = {6}, V =
{4}, k = 5 şi o = (1, 2, 3, 5, 4, ∞).
Iteraţia 8: Se selectează x = 4. Deoarece (4, 6)∈ A, 6∈ U, obţinem U = Ø, V
= {4, 6}, p = (0, 1, 2, 0, 3, 4), k = 6, o = (1, 2, 3, 5, 4, 6).
Iteraţia 9: Considerăm că se selectează nodul x = 4 din V. Rezultă V = {6}
şi W = {1, 2, 3, 4, 5}.
Iteraţia 10: Se selectează x = 6, rezultă V = Ø şi W = {1, 2, 3, 4, 5, 6} şi
algoritmul se termină.
30
Fig. 2.8
M2.U1.5. Rezumat
Algoritmii de parcurgere a unui graf sunt metode sistematice de vizitare a
nodurilor grafului, pornind dintr-un nod sursă. În cazul algoritmului generic de
parcurgere (totală) nodul din care se continuă parcurgerea este selectat, fără nicio
regulă, dintre nodurile vizitate şi neanalizate.
31
Unitatea de învăţare M2.U2. Parcurgerea în lăţime
Cuprins
M2.U2.1. Introducere .................................................................................................... 32
M2.U2.2. Obiectivele unităţii de învăţare ..................................................................... 32
M2.U2.3. Parcurgerea în lăţime .................................................................................... 33
M2.U2.4. Parcurgerea totală în lăţime .......................................................................... 37
M2.U2.5. Rezumat ........................................................................................................ 41
M2.U2.6. Test de evaluare a cunoştinţelor ................................................................... 41
M2.U2.1. Introducere
32
M2.U2.3. Parcurgerea în lăţime
min{l ( Dx ) | Dx ∈ ∆ x }, daca ∆ x ≠ ∅
⌣
d ( x) =
∞, daca ∆ x = ∅
⌣
Un drum Dx∈ ∆x cu l(Dx) = d(x) se numeşte cel mai scurt drum de la nodul sursă s la
nodul x.
În algoritmul parcurgerii BF (algoritmul PBF) se folosesc aceleaşi notaţii ca în
algoritmul PG cu deosebirea că în locul tabloului ordine o se utilizează tabloul lungime l care
este unidimensional şi are n elemente. Mulţimea nodurilor vizitate şi neanalizate V este
organizată, ca structură de date, ca o coadă. Algoritmul PBF este următorul:
algoritm PBF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
l(s) = 0;
for y∈ U do l(y) = ∞;
while V ≠ Ø do
begin
se selectează cel mai vechi nod x introdus în V;
for (x, y)∈ A do
if y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; l(y) = l(x) + 1;
end
V = V – {x}; W = W ∪ {x};
end;
end.
33
Teoremă. Algoritmul PBF are complexitatea O(m).
Exemplu
Aplicăm algoritmul de parcurgere în lăţime pe digraful din figura 2.9.
Fig. 2.9
34
actualizările: V = {5, 4} şi W = {1, 2, 3}.
Iteraţia 4: Se selectează cel mai vechi nod din V, acesta este x = 5.
Deoarece nu mai există noduri nevizitate, se efectuează V = {4} şi W = {1, 2, 3,
5}.
Iteraţia 5: Se selectează nodul x = 4. Obţinem V = Ø, W = {1, 2, 3, 4, 5} şi
algoritmul se termină.
Fig. 2.10
Fig. 2.11
35
0, 0, 0, 0, 0, 0), l = (0, ∞, ∞, ∞, ∞, ∞, ∞).
Iteraţia 1: Se selectează nodul x = 1. Deoarece (1, 2)∈ A şi 2∈ U, obţinem
U = {3, 4, 5, 6, 7}, V = {1, 2}, p = (0, 1, 0, 0, 0, 0, 0), l = (0, 1, ∞, ∞, ∞, ∞, ∞).
Avem (1, 5)∈ A şi 5 ∈ U, deci U = {3, 4, 6, 7}, V = {1, 2, 5}, p = (0, 1, 0, 0, 1, 0,
0), l = (0, 1, ∞, ∞, 1, ∞, ∞). Cum (1, 6)∈ A şi 6 ∈ U, obţinem U = {3, 4, 7}, V =
{1, 2, 5, 6}, p = (0, 1, 0, 0, 1, 1, 0), l = (0, 1, ∞, ∞, 1, 1, ∞). Se actualizează
mulţimile V şi W: V = {2, 5, 6} şi W = {1}.
Iteraţia 2: Se selectează cel mai vechi nod din V, acesta este x = 2.
Deoarece nu există succesori nevizitaţi ai nodului 2, se efectuează V = {5, 6} şi W
= {1, 2}.
Iteraţia 3: Cel mai vechi nod din V este x = 5. Deoarece (5, 3)∈ A şi 3∈ U,
obţinem U = {4, 7}, V = {5, 6, 3}, p = (0, 1, 5, 0, 1, 1, 0), l = (0, 1, 2, ∞, 1, 1, ∞).
Se fac actualizările: V = {6, 3} şi W = {1, 2, 5}.
Iteraţia 4: Se selectează cel mai vechi nod din V, acesta este x = 6.
Deoarece nodul 6 nu are succesori nevizitaţi, se efectuează V = {3} şi W = {1, 2,
5, 6}.
Iteraţia 5: Se selectează nodul x = 3. Obţinem V = Ø, W = {1, 2, 3, 5, 6} şi
algoritmul se termină.
Fig. 2.12
36
M2.U2.4. Parcurgerea totală în lăţime
Observaţie. În general, mulţimea W a nodurilor accesibile din nodul sursă dat este o
submulţime a mulţimii nodurilor N. Pentru parcurgerea în lăţime a întregului digraf G = (N,
A) se utilizează algoritmul parcurgerii totale în lăţime (algoritmul PTBF), care este următorul:
algoritm PTBF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
l(s) = 0;
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează cel mai vechi nod x introdus în V;
for (x, y)∈ A do
if y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; l(y) = l(x) + 1;
end
V = V – {x}; W = W ∪ {x};
end;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; l(s) = 0;
end;
end;
end.
37
Fie mulţimea S={s | s ∈ N, s este nod sursă selectat la începutul sau pe parcursul
execuţiei algoritmului}.
În parcurgerea totală BF, dacă subgraful predecesor Gp = (Np, Ap) cu Np = {y∈ N |
p(y) ≠ 0} ∪ S, Ap ={(p(y), y) | y∈ Np -S} este o pădure şi Np = W, atunci Gp se numeşte pădure
parcurgere BF.
Algoritmul PTBF determină elementele tabloului p astfel încât subgraful predecesor Gp
= (Np, Ap) este o pădure parcurgere BF.
Fig. 2.13
38
Deoarece nu mai există noduri nevizitate, se efectuează V = {6} şi W = {1, 2, 3,
4, 5}.
Iteraţia 6: Se selectează nodul x = 6. Se efectuează V = Ø, W = {1, 2, 3, 4,
5, 6} şi algoritmul se termină.
Deoarece toate nodurile au fost vizitate pornind din nodul sursă s = 1 (nu a
fost necesar să selectăm noi noduri sursă) rezultatul parcurgerii totale în lăţime ar
fi putut fi obţinut şi cu algoritmul de parcurgere în lăţime. Deci, s-a obţinut o
singură arborescenţa parcurgere BF, care este reprezentată în figura 2.14.
Fig. 2.14
Fig. 2.15
39
Iteraţia 2: Se selectează cel mai vechi nod din V, acesta este x = 2.
Deoarece nodul 2 nu are succesori, se efectuează V = {5} şi W = {1, 2}.
Iteraţia 3: Cel mai vechi nod din V este x = 5. Deoarece nici nodul 5 nu are
succesori nevizitaţi, obţinem V = Ø şi W = {1, 2, 5}. Se determină un nou nod
sursă dintre nodurile nevizitate (din U). Fie acesta s = 3. Se fac actualizările U =
{4, 6, 7}, V = {3}, l = (0, 1, 0, ∞, 1, ∞, ∞).
Iteraţia 4: Se selectează singurul nod din V, acesta este x = 3. Deoarece
nodul 3 nu are succesori nevizitaţi, se efectuează V = Ø şi W = {1, 2, 3, 5}. Se
determină un nou nod sursă dintre nodurile nevizitate. Fie acesta s = 4. Se fac
actualizările U = {6, 7}, V = {4}, l = (0, 1, 0, 0, 1, ∞, ∞).
Iteraţia 5: Se selectează nodul x = 4. Deoarece (4, 6)∈ A şi 6∈ U, obţinem
U = {7}, V = {4, 6}, p = (0, 1, 0, 0, 1, 4, 0), l = (0, 1, 0, 0, 1, 1, ∞). Avem (4, 7)∈
A şi 7∈ U, deci U = Ø, V = {4, 6, 7}, p = (0, 1, 0, 0, 1, 4, 4), l = (0, 1, 0, 0, 1, 1,
1). Se actualizează mulţimile V şi W: V = {6, 7} şi W = {1, 2, 3, 4, 5}.
Iteraţia 6: Cel mai vechi nod din V este x = 6. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {7} şi W = {1, 2, 3, 4, 5, 6}.
Iteraţia 7: Singurul nod din V este x = 7. Se efectuează V = Ø, W = {1, 2, 3,
4, 5, 6, 7} şi algoritmul se termină.
Fig. 2.16
40
M2.U2.5. Rezumat
Algoritmul de parcurgere (totală) în lăţime a unui graf este o metodă
sistematică de vizitare a nodurilor grafului, pornind dintr-un nod sursă. Întotdeauna
nodul din care se continuă parcurgerea este cel mai vechi dintre nodurile vizitate şi
neanalizate. Deci, putem obţine algoritmul de parcurgere (totală) în lăţime
organizând ca o coadă a mulţimea V a nodurilor vizitate şi neanalizate din algoritmul
generic de parcurgere (totală).
41
Unitatea de învăţare M2.U3. Parcurgerea în adâncime
Cuprins
M2.U3.1. Introducere .................................................................................................... 42
M2.U3.2. Obiectivele unităţii de învăţare ..................................................................... 42
M2.U3.3. Parcurgerea în adâncime............................................................................... 43
M2.U3.4. Parcurgerea totală în adâncime ..................................................................... 47
M2.U3.5. Rezumat ........................................................................................................ 54
M2.U3.6. Test de evaluare a cunoştinţelor ................................................................... 54
M2.U3.1. Introducere
Una dintre cele mai des utilizate implementări ale algoritmului generic de
parcurgere (totală) este algoritmul de parcurgere (totală) în adâncime. Acesta
constă, după cum numele său sugerează, în a vizita cât mai “adânc” graful. Pentru
aceasta, la fiecare pas, se continua parcurgerea din ultimul nod vizitat, dacă el are
măcar un successor nevizitat, iar, în caz contrar, se revine la nodul din care el a
fost vizitat.
42
M2.U3.3. Parcurgerea în adâncime
algoritm PDF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
t = 1; t1(s) = 1;
for y∈ U do
begin
t1(y) = ∞; t2(y) = ∞;
end;
while V ≠ Ø do
begin
se selectează cel mai nou nod x introdus în V;
if există arc (x,y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; t = t +1;t1(y)= t;
end
else
begin
V = V – {x}; W = W ∪ {x}; t = t +1; t2(x)= t;
end;
end;
end.
43
În parcurgerea DF, dacă Np =W şi subgraful predecesor Gp = (Np, Ap) este o arborescenţă
atunci Gp se numeşte arborescenţă parcurgere DF.
Fig. 2.17
Iteraţia 2: Cel mai nou nod din V este x = 2. Avem (2, 3)∈ A, 3∈ U,
obţinem U = {4}, V = {1, 2, 3}, p = (0, 1, 2, 0), t = 3, t1 = (1, 2, 3, ∞).
Iteraţia 3: Se selectează cel mai nou nod din V, acesta este x = 3. Deoarece
nodul 3 nu are succesori nevizitaţi, se efectuează V = {1, 2}, W = {3}, t = 4, t2 =
(∞, ∞, 4, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 2. Avem (2, 4)∈ A, 4∈ U,
obţinem U = Ø, V = {1, 2, 4}, p = (0, 1, 2, 2), t = 5, t1 = (1, 2, 3, 5).
Iteraţia 5: Se selectează cel mai nou nod din V, acesta este x = 4. Deoarece
nu mai există noduri nevizitate, se efectuează V = {1, 2}, W = {3, 4}, t = 6, t2 =
(∞, ∞, 4, 6).
Iteraţia 6: Cel mai nou nod din V este x = 2. Se fac actualizările: V = {1},
W = {2, 3, 4}, t = 7, t2 = (∞, 7, 4, 6).
44
Iteraţia 7: Se selectează x = 1. Se efectuează V = Ø, W = {1, 2, 3, 4}, t = 8,
t2 = (8, 7, 4, 6) şi algoritmul se termină.
Fig. 2.18
Fig. 2.19
45
∞).
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 3.
Deoarece (3, 4)∈ A, 4∈ U, obţinem U = {5, 6}, V = {1, 2, 3, 4}, p = (0, 1, 2, 3, 0,
0), t = 4, t1 = (1, 2, 3, 4, ∞, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 4. Avem (4, 5)∈ A, 5∈ U,
obţinem U = {6}, V = {1, 2, 3, 4, 5}, p = (0, 1, 2, 3, 4, 0), t = 5, t1 = (1, 2, 3, 4, 5,
∞).
Iteraţia 5: Se selectează cel mai nou nod din V. Acesta este nodul x = 5.
Deoarece nodul 5 nu are succesori, se efectuează V = {1, 2, 3, 4}, W = {5}, t = 6,
t2 = (∞, ∞, ∞, ∞, 6, ∞).
Iteraţia 6: Se selectează cel mai nou nod din V. Acesta este nodul x = 4.
Deoarece nodul 4 nu are succesori nevizitaţi, se efectuează V = {1, 2, 3}, W = {4,
5}, t = 7, t2 = (∞, ∞, ∞, 7, 6, ∞).
Iteraţia 7: Cel mai nou nod din V este x = 3. Obţinem V = {1, 2}, W = {3, 4,
5}, t = 8, t2 = (∞, ∞, 8, 7, 6, ∞).
Iteraţia 8: Se selectează cel mai nou nod din V. Acesta este nodul x = 2. Se
efectuează V = {1}, W = {2, 3, 4, 5}, t = 9, t2 = (∞, 9, 8, 7, 6, ∞).
Iteraţia 9: Singurul nod din V este x = 1. Obţinem V = Ø, W = {1, 2, 3, 4,
5}, t = 10, t2 = (10, 9, 8, 7, 6, ∞) şi algoritmul se termină.
46
Fig. 2.20
algoritm PTDF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
t = 1; t1(s) = 1;
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează cel mai nou nod x introdus în V;
47
if există arc (x,y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; t = t +1;t1(y)= t;
end
else
begin
V = V – {x}; W = W ∪ {x}; t = t +1; t2(x)= t;
end;
end;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; t = t+ 1; t1(s) = t;
end;
end;
end.
Fie mulţimea S={s | s ∈ N, s este nod sursă selectat la începutul sau pe parcursul
execuţiei algoritmului}.
În parcurgerea totală DF, dacă subgraful predecesor Gp = (Np, Ap) cu Np = {y∈ N |
p(y) ≠ 0} ∪ S, Ap ={(p(y), y) | y∈ Np -S} este o pădure şi Np = W, atunci Gp se numeşte pădure
parcurgere DF.
Algoritmul PTDF determină elementele tabloului p astfel încât subgraful predecesor Gp
= (Np, Ap) este o pădure parcurgere DF.
Parcurgerea totală DF poate fi utilizată la clasificarea arcelor digrafului G = (N, A) în
raport cu pădurea parcurgere DF. În această clasificare există două clase de arce:
• arce arborescenţă,
• arce nonarborescenţă.
Mulţimea arcelor arborescenţă, notată P, este P = Ap. Aceste arce introduc, în timpul
parcurgerii totale DF a digrafului G = (N, A), noduri în mulţimea nodurilor vizitate şi
48
neanalizate V. Mulţimea arcelor nonarborescenţă, notată P , este P = A – Ap. Clasa arcelor
Mulţimea arcelor de înaintare, notată I, este alcătuită din acele arce (x, y) pentru care
nodul x este un ascendent al nodului y în pădurea parcurgere DF. Mulţimea arcelor de
revenire, notată R, este alcătuită din acele arce (x, y) pentru care nodul x este un descendent al
nodului y în pădurea parcurgere DF. Mulţimea arcelor de traversare, notată T, este alcătuită
din acele arce (x, y) pentru care nodul x nu este nici ascendent, nici descendent al nodului y în
pădurea parcurgere DF. Aceste trei mulţimi de arce nonarborescenţă sunt disjuncte două câte
două şi P = I ∪ R ∪ T .
Teoremă. Într-o parcurgere totală DF a unui digraf G = (N, A), arcul (x, y) este:
(1) un arc arborescenţă sau de înaintare dacă şi numai dacă t1(x) < t1(y) < t2(y) < t2(x);
(2) un arc de revenire dacă şi numai dacă t1(y) < t1(x) < t2(x) < t2(y);
(3) un arc de traversare dacă şi numai dacă t1(y) < t2(y) < t1(x) < t2(x).
Fig. 2.21
49
că U = {4, 5, 6}, V = {1, 2, 3}, p = (0, 1, 2, 0, 0, 0), t = 3, t1 = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 3.
Deoarece (3, 4)∈ A, 4∈ U, obţinem U = {5, 6}, V = {1, 2, 3, 4}, p = (0, 1, 2, 3, 0,
0), t = 4, t1 = (1, 2, 3, 4, ∞, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 4. Avem (4, 5)∈ A, 5∈ U,
obţinem U = {6}, V = {1, 2, 3, 4, 5}, p = (0, 1, 2, 3, 4, 0), t = 5, t1 = (1, 2, 3, 4, 5,
∞).
Iteraţia 5: Se selectează cel mai nou nod din V. Acesta este nodul x = 5.
Deoarece nodul 5 nu are succesori, se efectuează V = {1, 2, 3, 4}, W = {5}, t = 6,
t2 = (∞, ∞, ∞, ∞, 6, ∞).
Iteraţia 6: Se selectează cel mai nou nod din V. Acesta este nodul x = 4.
Avem (4, 6)∈ A, 6∈ U, rezultă că U = Ø, V = {1, 2, 3, 4, 6}, p = (0, 1, 2, 3, 4, 4),
t = 7, t1 = (1, 2, 3, 4, 5, 7).
Iteraţia 7: Cel mai nou nod din V este x = 6. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {1, 2, 3, 4}, W = {5, 6}, t = 8, t2 = (∞, ∞, ∞, ∞, 6, 8).
Iteraţia 8: Se selectează cel mai nou nod din V. Acesta este nodul x = 4. Se
efectuează V = {1, 2, 3}, W = {4, 5, 6}, t = 9, t2 = (∞, ∞, ∞, 9, 6, 8).
Iteraţia 9: Cel mai nou nod din V este x = 3. Obţinem V = {1, 2}, W = {3, 4,
5, 6}, t = 10, t2 = (∞, ∞, 10, 9, 6, 8).
Iteraţia 10: Se selectează cel mai nou nod din V. Acesta este nodul x = 2. Se
efectuează V = {1}, W = {2, 3, 4, 5, 6}, t = 11, t2 = (∞, 11, 10, 9, 6, 8).
Iteraţia 11: Singurul nod din V este x = 1. Obţinem V = Ø, W = {1, 2, 3, 4,
5, 6}, t = 12, t2 = (12, 11, 10, 9, 6, 8) şi algoritmul se termină.
50
Fig. 2.22
Fig. 2.23
Exemplu
Aplicăm algoritmul de parcurgere totală în adâncime pe digraful din figura
2.24.
51
Fig. 2.24
52
sursă. Fie aceasta s = 6. Se efectuează U = {7}, V = {6}, t = 11, t1 = (1, 2, 6, 7, 3,
11, ∞).
Iteraţia 10: Se selectează nodul x = 6, fiind singurul nod din V. Deoarece
(6, 7)∈ A, 7∈ U, obţinem U = Ø, V = {6, 7}, p = (0, 1, 1, 3, 2, 0, 6), t = 12, t1 =
(1, 2, 6, 7, 3, 11, 12).
Iteraţia 11: Cel mai nou nod din V este x = 7. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {6}, W = {1, 2, 3, 4, 5, 7}, t = 13, t2 = (10, 5, 9, 8, 4, ∞,
13).
Iteraţia 12: Singurul nod din V este x = 6. Obţinem V = Ø, W = {1, 2, 3, 4,
5, 6, 7}, t = 14, t2 = (10, 5, 9, 8, 4, 14, 13) şi algoritmul se termină.
Fig. 2.25
Fig. 2.26
53
M2.U3.5. Rezumat
Algoritmul de parcurgere (totală) în adâncime a unui graf este o metodă
sistematică de vizitare a nodurilor grafului, pornind dintr-un nod sursă. Întotdeauna
nodul din care se continuă parcurgerea este cel mai nou dintre nodurile vizitate şi
neanalizate. Deci, putem obţine algoritmul de parcurgere (totală) în adâncime
organizând ca o stivă a mulţimea V a nodurilor vizitate şi neanalizate din algoritmul
generic de parcurgere (totală).
54
Unitatea de învăţare M2.U4. Aplicaţii ale parcurgerilor
Cuprins
M2.U4.1. Introducere .................................................................................................... 55
M2.U4.2. Obiectivele unităţii de învăţare ..................................................................... 55
M2.U4.3. Determinarea componentelor conexe ........................................................... 56
M2.U4.4. Determinarea componentelor tare conexe .................................................... 60
M2.U4.5. Sortarea topologică ....................................................................................... 64
M2.U4.6. Rezumat ........................................................................................................ 68
M2.U4.7. Test de evaluare a cunoştinţelor ................................................................... 68
M2.U4.1. Introducere
55
Durata medie de parcurgere a primei unităţi de învăţare este de 3 ore.
Un digraf G = (N, A) se numeşte slab conex sau conex dacă pentru oricare două noduri
diferite x, y există un lanţ care are aceste două noduri drept extremităţi.
Noţiunea de conexitate are sens şi pentru grafuri neorientate.
Se numeşte componentă conexă a unui digraf G = (N, A) un subgraf G´ = (N´, A´) al lui
G, care este conex şi care este maximal în raport cu incluziunea faţă de această proprietate
(oricare ar fi x∈ N - N´, subgraful G x′ generat de N ′x = N´ ∪ {x} nu este conex).
O componentă conexă G´ = (N´, A´) a unui digraf G = (N, A) se poate identifica prin
mulţimea N´ care generează subgraful G´.
Deoarece în problema conexităţii sensul arcelor nu contează, algoritmul va fi descris
pentru grafuri neorientate. Dacă G = (N, A) este digraf atunci i se asociază graful neorientat
Gˆ = ( Nˆ , Aˆ ) , unde N̂ = N, Â ={[x, y]| (x, y) ∈ A sau (y, x) ∈ A}. Este evident că G = (N, A)
şi Gˆ = ( Nˆ , A
ˆ ) au aceleaşi componente conexe (privite ca mulţimi de noduri).
Algoritmul de deteminare a componentelor conexe (algoritmul CC) este o adaptare a
algoritmului PTDF aplicat unui graf neorientat G = (N, A). Nu se calculează tablourile timp t1,
t2 şi nici vectorul predecesor p, în mulţimea N´ reţinem componenta conexă curentă, iar la
sfârşitul algoritmului nc va fi numărul de componte conexe ale grafului. Algoritmul CC este
următorul:
algoritm CC;
begin
U = N – {s}; V = {s}; W = Ø; nc = 1; N' = {s};
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează cel mai nou nod x introdus în V;
56
if există muchie [x, y]∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; N´ = N´ ∪ {y};
end
else
begin
V = V – {x}; W = W ∪ {x};
end;
end;
se tipăresc nc şi N´;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; nc = nc+ 1; N´ = {s};
end;
end;
end.
57
Fig. 2.27
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 2.
Deoarece [2, 4]∈ A, 4∈ U, obţinem U = Ø, V = {1, 3, 2, 4}, N´= {1, 2, 3, 4}.
Iteraţia 4: Cel mai nou nod din V este x = 4. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {1, 3, 2}, W = {4}.
Iteraţia 5: Se selectează cel mai nou nod din V. Acesta este nodul x = 2. Se
efectuează V = {1, 3}, W = {2, 4}.
Iteraţia 6: Cel mai nou nod din V este x = 3. Deci, V = {1}, W = {2, 3, 4}.
Iteraţia 7: Se selectează nodul x = 1. Se efectuează V = Ø, W = {1, 2, 3, 4},
se tipăresc nc=1 şi N´= {1, 2, 3, 4} şi algoritmul se termină.
58
Exemplu Pentru a determina componentele conexe ale digrafului din figura
2.28, trebuie mai întâi să determinăm graful neorientat corespunzător lui. Acesta
este reprezentat în figura 2.29.
Fig. 2.28
Fig. 2.29
59
2, N´= {4}.
Iteraţia 8: Se selectează x = 4. Fiindcă [4, 6]∈ A, 6∈ U, obţinem U = {7},
V = {4, 6}, N´= {4, 6}.
Iteraţia 9: Cel mai nou nod din V este x = 6. Avem [6, 7]∈ A, 7∈ U,
obţinem U = Ø, V = {4, 6, 7}, N´= {4, 6, 7}.
Iteraţia 10: Se selectează cel mai nou nod din V. Acesta este nodul x = 7.
Deoarece nodul nu mai există noduri nevizitate, se efectuează V = {4, 6}, W = {1,
2, 3, 5, 7}.
Iteraţia 11: Cel mai nou nod din V este x = 6. Obţinem V = {4}, W = {1, 2,
3, 5, 6, 7}.
Iteraţia 12: Singurul nod din V este x = 4. Obţinem V = Ø, W = {1, 2, 3, 4,
5, 6, 7}, se tipăresc nc=2 şi N´= {4, 6, 7} şi algoritmul se termină.
Deci, digraful din figura 2.28 nu este conex, are două componente conexe:
{1, 2, 3, 5} şi {4, 6, 7}. Evident, aceste afirmaţii sunt adevărate şi pentru graful
neorientat din figura 2.29.
Un digraf G = (N, A) se numeşte tare conex dacă pentru oricare două noduri diferite x, y
există un drum de la x la y şi un drum de la y la x.
Evident, noţiunea de tare conexitate are sens numai pentru digrafuri.
Se numeşte componentă tare conexă a unui digraf G = (N, A) un subgraf G´ = (N´, A´)
al lui G, care este tare conex şi care este maximal în raport cu incluziunea faţă de această
proprietate (oricare ar fi x∈ N - N´, subgraful G x′ generat de N ′x = N´ ∪ {x} nu este tare
conex).
O componentă tare conexă G´ = (N´, A´) a unui digraf G = (N, A) se poate identifica cu
mulţimea N´ care generează subgraful G´.
Algoritmul de determinare a componentelor tare conexe (algoritmul CTC) este
următorul:
60
algoritm CTC;
begin
se aplică digrafului G algoritmul PTDF pentru a determina vectorul t2;
se determină G-1 graful invers al digrafului G;
se aplică digrafului invers G-1 algoritmul PTDF modificat în modul următor:
nodul sursă s este ales astfel încât t2(s) ≥ t2(x) pentru orice nod nevizitat x, unde t2 este
vectorul timp determinat cu algoritmul PTDF aplicat digrafului G.
se determină componentele tare conexe ale lui G după regula: nodurile care
sunt în aceeaşi arborescenţă DF a digrafului G-1 formează o componentă tare conexă a
lui G.
end.
={N1,…,Nq}, Â ={(Ni, Nj) | Ni, Nj∈ N̂ şi există (x, y)∈ A cu x∈ Ni, y∈ Nj}, unde N1,…,Nq
sunt componentele tare conexe ale digrafului G= (N, A).
Fig. 2.30
61
Fig. 2.31
Fig. 2.32
Fig. 2.33
62
reprezentat în figura 2.34.
Fig. 2.34
Fig. 2.35
63
M2.U4.5. Sortarea topologică
Sortarea topologică a unui digraf G = (N, A) fără circuite constă în ordonarea nodurilor
din N după regula:
dacă (x, y) ∈ A atunci x < y.
Digrafurile fără circuite sunt folosite în multe aplicaţii pentru a indica relaţia de
anterioritate dintre anumite evenimente.
O modalitate de testare a existenţei circuitelor întrun digraf este dată de următoarea
teoremă.
Teoremă Un digraf G = (N, A) este fără circuite dacă şi numai dacă orice parcurgere
totală DF a lui G nu produce arce de revenire.
64
Exemplu Aplicăm algoritmul de sortare topologică pe digraful fără circuite
din figura 2.36.
Fig. 2.36
65
Iteraţia 9: Se selectează nodul x = 1. Obţinem V = Ø, W = {4, 5, 2, 3, 1}, t =
10, t2 = (10, 7, 9, 4, 6) şi algoritmul se termină.
Fig. 2.37
Fig. 2.38
66
Iteraţia 2: Cel mai nou nod din V este x = 2. Avem (2, 3)∈ A, 3∈ U,
obţinem U = {4, 5, 6}, V = {1, 2, 3}, t = 3, t1 = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 3,
care nu are succesori. Deci, se efectuează V = {1, 2}, W = {3}, t = 4, t2 = (∞, ∞,
4, ∞, ∞, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 2, care nu are succesori nevizitaţi.
Obţinem V = {1}, W = {3, 2}, t = 5, t2 = (∞, 5, 4, ∞, ∞, ∞).
Iteraţia 5: Se selectează nodul x = 1, fiind singurul nod din V. Se efectuează
V = Ø, W = {3, 2, 1}, t = 6, t2 = (6, 5, 4, ∞, ∞, ∞). Se selectează nodul sursă s = 6
pentru că ρ⁻(6) = 0. Se efectuează U = {4, 5}, V = {6}, t = 7, t1 = (1, 2, 3, ∞, ∞,
7).
Iteraţia 6: Se selectează nodul x = 6. Deoarece (6, 4)∈ A, 4∈ U, obţinem U
= {5}, V = {6, 4}, t = 8, t1 = (1, 2, 3, 8, ∞, 7).
Iteraţia 7: Cel mai nou nod din V este x = 4. Deoarece (4, 5)∈ A, 5∈ U,
obţinem U = Ø, V = {6, 4, 5}, t = 9, t1 = (1, 2, 3, 8, 9, 7).
Iteraţia 8: Cel mai nou nod din V este x = 5. Fiindcă nu mai există noduri
nevizitate, se efectuează V = {6, 4}, W = {3, 2, 1, 5}, t = 10, t2 = (6, 5, 4, ∞, 10,
∞).
Iteraţia 9: Se selectează nodul x = 4. Obţinem V = {6}, W = {3, 2, 1, 5, 4},
t = 11, t2 = (6, 5, 4, 11, 10, ∞).
Iteraţia 10: Singurul nod din V este x =1. Se efectuează V = Ø, W = {3, 2, 1,
5, 4, 6}, t = 12, t2 = (6, 5, 4, 11, 10, 12) şi algoritmul se termină.
Fig. 2.39
67
La începutul algoritmului existau două noduri care puteau fi alese ca
nod sursă: 1 şi 6. Deci, sortarea topologică a nodurilor grafului din figura 2.38, pe
care am obţinut-o în exemplul 2.18 alegând nodul 1 ca nod sursă, nu este unică.
Dacă am fi început execuţia algoritmului de sortare topologică din nodul
sursă s =6 am fi obţinut următoarea ordine a nodurilor: 1, 6, 4, 5, 2, 3. În figura
2.40 am redesenat graful din figura 2.38, aşezând nodurile în ordinea specificată
mai sus.
Fig. 2.40
M2.U4.6. Rezumat
În acestă unitate de învăţare am prezentat trei aplicaţii ale parcurgerii în
adâncime a unui graf: determinarea componentelor conexe ale unui graf orientat sau
neorientat, determinarea componentelor tare conexe ale unui digraf şi sortarea
topologică a unui digraf fără circuite.
Algoritmul de determinare a componentelor conexe ale unui graf poate fi
obţinut, pornind de la oricare dintre algoritmii de parcurgere. Însă, în vederea unei
abordări unitare a aplicaţiilor parcurgerilor, am folosit, ca punct de plecare, pentru
algoritmul de determinare a componentelor conexe tot algoritmul de parcurgere în
adâncime.
68
2. Determinaţi componentele tare conexe ale următorului graf:
Temă de control
69
3. Aplicaţi algoritmul de parcurgere totală în adâncime pe următorul digraf:
70
Modulul 2. Parcurgeri de grafuri
Cuprins
Introducere .................................................................................................................... 20
Obiectivele modului ...................................................................................................... 20
U1. Parcurgerea generică ............................................................................................. 21
U2. Parcurgerea în lăţime ............................................................................................. 33
U3. Parcurgerea în adâncime ........................................................................................ 43
U4. Aplicaţii ale parcurgerilor ...................................................................................... 56
Introducere
În acest modul ne vom ocupa de problema parcurgerii unui digraf. Acestă
problemă constă în determinarea tuturor nodurilor accesibile dintr-un nod dat,
numit nod sursă. Problema parcurgerii unui graf poate apărea ca problemă de sine
stătătoare, dar şi ca subproblemă a unei probleme mai complexe.
Vom prezenta mai întâi parcurgerea generică, iar apoi cele mai cunoscute
implementări ale acesteia: parcurgerea în lăţime şi parcurgerea în adâncime. În
finalul modulului, ne vom îndrepta atenţia asupra următoarelor aplicaţii ale
parcurgerilor: determinarea componentelor conexe, determinarea componentelor
tare conexe şi sortarea topologică.
Competenţe
La sfârşitul acestui modul studenţii vor fi capabili să:
Parcurgă grafuri;
Determine componentele conexe ale unui graf orientat sau neorientat;
Determine componentele tare conexe ale unui graf orientat;
Sorteze topologic un digraf fără circuite.
20
Unitatea de învăţare M2.U1. Parcurgerea generică
Cuprins
M2.U1.1. Introducere .................................................................................................... 21
M2.U1.2. Obiectivele unităţii de învăţare ..................................................................... 22
M2.U1.3. Algoritmul de parcurgere generică ............................................................... 22
M2.U1.4. Algoritmul de parcurgere totală generică ..................................................... 27
M2.U1.5. Rezumat ........................................................................................................ 31
M2.U1.6. Test de evaluare a cunoştinţelor ................................................................... 31
M2.U1.1. Introducere
Problema parcurgerii unui digraf G = (N, A) constă în generarea mulţimii W
a nodurilor y accesibile dintr-un nod sursă dat s. Spunem că nodul y este accesibil
din nodul s în digraful G dacă există drum de la nodul sursă s la nodul y. Evident,
W ⊆ N.
Algoritmii pe care îi vom prezenta în acest modul pentru rezolvarea
problemei parcurgerii unui digraf G sunt metode sistematice de vizitare a nodurilor
y accesibile dintr-un nod sursă dat s. Fiecare iteraţie a execuţiei oricărui algoritm
de parcurgere stabileşte pentru fiecare nod apartenenţa la una din următoarele trei
stări:
• nevizitat,
• vizitat şi neanalizat, adică un nod vizitat ai cărui succesori au fost parţial
vizitaţi,
• vizitat şi analizat, adică un nod vizitat ai cărui succesori au fost în
totalitate vizitaţi.
Dacă nodul x este vizitat şi neanalizat, dacă există arc (x, y) şi dacă nodul y
este nevizitat, atunci se poate vizita nodul y. În acest caz se spune că arcul (x, y)
este arc admisibil şi dacă nodul y este vizitat explorând arcul (x, y) se spune că
nodul x este predecesorul-parcurgere al nodului y.
În acest modul se vor prezenta următorii algoritmi pentru parcurgerea unui
digraf: algoritmul generic de parcurgere, algoritmul de parcurgere în lăţime şi
algoritmul de parcurgere în adâncime. Aceşti algoritmi utilizează următoarele
notaţii comune:
21
U mulţimea nodurilor nevizitate;
V mulţimea nodurilor vizitate şi neanalizate;
W mulţimea nodurilor vizitate şi analizate;
p tabloul predecesor, care este unidimensional cu n elemente.
Se folosesc notaţiile precizate mai sus şi în plus notăm cu o tabloul ordine care este
unidimensional şi are n elemente.
Algoritmul parcurgerii generice (algoritmul PG) este următorul:
algoritm PG;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
k = 1; o(s) = 1;
for y∈ U do o(y) = ∞;
while V ≠ Ø do
begin
se selectează un nod x din V;
if există arc (x, y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; k = k+1; o(y) = k;
22
end
else
begin
V = V – {x}; W = W ∪ {x};
end;
end;
end.
23
end;
Fig. 2.1
24
W = {1, 2, 3, 5}.
Iteraţia 9: Se selectează nodul x = 4 din V. Obţinem V = Ø, W = {1, 2, 3, 4,
5} şi algoritmul se termină.
Fig. 2.2
Fig. 2.3
25
Iteraţia 1: Se selectează x = 1. Avem (1, 2)∈ A, 2∈ U, deci U = {3, 4, 5, 6},
V = {1, 2}, p = (0, 1, 0, 0, 0, 0), k = 2, o = (1, 2, ∞, ∞, ∞, ∞).
Iteraţia 2: Dacă dintre nodurile vizitate şi neanalizate a fost selectat nodul
x = 2, atunci, deoarece (2, 3)∈ A, 3 ∈ U, obţinem U = {4, 5, 6}, V = {1, 2, 3}, p =
(0, 1, 2, 0, 0, 0), k = 3, o = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Presupunem că se selectează nodul x = 1 din V, atunci V = {2, 3}
şi W = {1}.
Iteraţia 4: Considerăm că se selectează nodul x = 3 din V. Deoarece
(3, 5)∈ A, 5∈ U, obţinem U = {4, 6}, V = {2, 3, 5}, p = (0, 1, 2, 0, 3, 0), k = 4, o
= (1, 2, 3, ∞, 4, ∞).
Iteraţia 5: Presupunem că se selectează nodul x = 2 din V, atunci V = {3, 5}
şi W = {1, 2}.
Iteraţia 6: Considerăm că se selectează nodul x = 5 din V. Rezultă V = {3}
şi W = {1, 2, 5}.
Iteraţia 7: Se selectează x = 3, rezultă V = Ø şi W = {1, 2, 3, 5} şi algoritmul
se termină deoarece nu mai există noduri vizitate şi neanalizate.
Fig. 2.4
26
M2.U1.4. Algoritmul de parcurgere totală generică
În general, mulţimea W a nodurilor accesibile din nodul sursă dat este o submulţime a
mulţimii nodurilor N. Pentru parcurgerea întregului digraf G = (N, A) se utilizează algoritmul
parcurgerii totale generice (algoritmul PTG) prezentat în continuare.
algoritm PTG;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
k = 1; o(s) = 1;
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează un nod x din V;
if există arc (x, y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; k = k+1; o(y) = k;
end
else
begin
V = V – {x}; W = W ∪ {x};
end;
end;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; k = k+1; o(s) = k;
end;
end;
end.
27
Fie mulţimea S={s | s ∈ N, s este nod sursă selectat la începutul sau pe parcursul
execuţiei algoritmului}.
În parcurgerea totală generică, dacă subgraful predecesor Gp = (Np, Ap) cu Np ={y∈ N |
p(y) ≠ 0} ∪ S, Ap ={(p(y), y) | y∈ Np -S} este o pădure şi Np = W, atunci Gp se numeşte pădure
parcurgere.
Algoritmul PTG determină elementele tabloului p astfel încât subgraful predecesor Gp =
(Np, Ap) este o pădure parcurgere (adică este format din una sau mai multe arborescenţe
parcurgere).
Fig. 2.5
28
4}.
Iteraţia 6: Considerăm că se selectează nodul x = 2. Vom obţine V = {1} şi
W = {2, 3, 4}.
Iteraţia 7: Se selectează nodul x = 1 din V şi obţinem V = Ø, W = {1, 2, 3,
4} şi algoritmul se termină.
Fig. 2.6
Fig. 2.7
29
x = 2, atunci, deoarece (2, 3)∈ A, 3 ∈ U, obţinem U = {4, 5, 6}, V = {1, 2, 3}, p =
(0, 1, 2, 0, 0, 0), k = 3, o = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Presupunem că se selectează nodul x = 1 din V, atunci V = {2, 3}
şi W = {1}.
Iteraţia 4: Considerăm că se selectează nodul x = 3 din V. Deoarece
(3, 5)∈ A, 5∈ U, obţinem U = {4, 6}, V = {2, 3, 5}, p = (0, 1, 2, 0, 3, 0), k = 4, o
= (1, 2, 3, ∞, 4, ∞).
Iteraţia 5: Presupunem că se selectează nodul x = 2 din V, atunci V = {3, 5}
şi W = {1, 2}.
Iteraţia 6: Considerăm că se selectează nodul x = 5 din V. Rezultă V = {3}
şi W = {1, 2, 5}.
Iteraţia 7: Se selectează x = 3, rezultă V = Ø şi W = {1, 2, 3, 5} şi, deoarece
nu mai există noduri vizitate şi neanalizate, algoritmul va selecta un nou nod
sursă dintre nodurile încă nevizitate. Fie acesta nodul 4. Deci, s = 4, U = {6}, V =
{4}, k = 5 şi o = (1, 2, 3, 5, 4, ∞).
Iteraţia 8: Se selectează x = 4. Deoarece (4, 6)∈ A, 6∈ U, obţinem U = Ø, V
= {4, 6}, p = (0, 1, 2, 0, 3, 4), k = 6, o = (1, 2, 3, 5, 4, 6).
Iteraţia 9: Considerăm că se selectează nodul x = 4 din V. Rezultă V = {6}
şi W = {1, 2, 3, 4, 5}.
Iteraţia 10: Se selectează x = 6, rezultă V = Ø şi W = {1, 2, 3, 4, 5, 6} şi
algoritmul se termină.
30
Fig. 2.8
M2.U1.5. Rezumat
Algoritmii de parcurgere a unui graf sunt metode sistematice de vizitare a
nodurilor grafului, pornind dintr-un nod sursă. În cazul algoritmului generic de
parcurgere (totală) nodul din care se continuă parcurgerea este selectat, fără nicio
regulă, dintre nodurile vizitate şi neanalizate.
31
Unitatea de învăţare M2.U2. Parcurgerea în lăţime
Cuprins
M2.U2.1. Introducere .................................................................................................... 32
M2.U2.2. Obiectivele unităţii de învăţare ..................................................................... 32
M2.U2.3. Parcurgerea în lăţime .................................................................................... 33
M2.U2.4. Parcurgerea totală în lăţime .......................................................................... 37
M2.U2.5. Rezumat ........................................................................................................ 41
M2.U2.6. Test de evaluare a cunoştinţelor ................................................................... 41
M2.U2.1. Introducere
32
M2.U2.3. Parcurgerea în lăţime
min{l ( Dx ) | Dx ∈ ∆ x }, daca ∆ x ≠ ∅
⌣
d ( x) =
∞, daca ∆ x = ∅
⌣
Un drum Dx∈ ∆x cu l(Dx) = d(x) se numeşte cel mai scurt drum de la nodul sursă s la
nodul x.
În algoritmul parcurgerii BF (algoritmul PBF) se folosesc aceleaşi notaţii ca în
algoritmul PG cu deosebirea că în locul tabloului ordine o se utilizează tabloul lungime l care
este unidimensional şi are n elemente. Mulţimea nodurilor vizitate şi neanalizate V este
organizată, ca structură de date, ca o coadă. Algoritmul PBF este următorul:
algoritm PBF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
l(s) = 0;
for y∈ U do l(y) = ∞;
while V ≠ Ø do
begin
se selectează cel mai vechi nod x introdus în V;
for (x, y)∈ A do
if y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; l(y) = l(x) + 1;
end
V = V – {x}; W = W ∪ {x};
end;
end.
33
Teoremă. Algoritmul PBF are complexitatea O(m).
Exemplu
Aplicăm algoritmul de parcurgere în lăţime pe digraful din figura 2.9.
Fig. 2.9
34
actualizările: V = {5, 4} şi W = {1, 2, 3}.
Iteraţia 4: Se selectează cel mai vechi nod din V, acesta este x = 5.
Deoarece nu mai există noduri nevizitate, se efectuează V = {4} şi W = {1, 2, 3,
5}.
Iteraţia 5: Se selectează nodul x = 4. Obţinem V = Ø, W = {1, 2, 3, 4, 5} şi
algoritmul se termină.
Fig. 2.10
Fig. 2.11
35
0, 0, 0, 0, 0, 0), l = (0, ∞, ∞, ∞, ∞, ∞, ∞).
Iteraţia 1: Se selectează nodul x = 1. Deoarece (1, 2)∈ A şi 2∈ U, obţinem
U = {3, 4, 5, 6, 7}, V = {1, 2}, p = (0, 1, 0, 0, 0, 0, 0), l = (0, 1, ∞, ∞, ∞, ∞, ∞).
Avem (1, 5)∈ A şi 5 ∈ U, deci U = {3, 4, 6, 7}, V = {1, 2, 5}, p = (0, 1, 0, 0, 1, 0,
0), l = (0, 1, ∞, ∞, 1, ∞, ∞). Cum (1, 6)∈ A şi 6 ∈ U, obţinem U = {3, 4, 7}, V =
{1, 2, 5, 6}, p = (0, 1, 0, 0, 1, 1, 0), l = (0, 1, ∞, ∞, 1, 1, ∞). Se actualizează
mulţimile V şi W: V = {2, 5, 6} şi W = {1}.
Iteraţia 2: Se selectează cel mai vechi nod din V, acesta este x = 2.
Deoarece nu există succesori nevizitaţi ai nodului 2, se efectuează V = {5, 6} şi W
= {1, 2}.
Iteraţia 3: Cel mai vechi nod din V este x = 5. Deoarece (5, 3)∈ A şi 3∈ U,
obţinem U = {4, 7}, V = {5, 6, 3}, p = (0, 1, 5, 0, 1, 1, 0), l = (0, 1, 2, ∞, 1, 1, ∞).
Se fac actualizările: V = {6, 3} şi W = {1, 2, 5}.
Iteraţia 4: Se selectează cel mai vechi nod din V, acesta este x = 6.
Deoarece nodul 6 nu are succesori nevizitaţi, se efectuează V = {3} şi W = {1, 2,
5, 6}.
Iteraţia 5: Se selectează nodul x = 3. Obţinem V = Ø, W = {1, 2, 3, 5, 6} şi
algoritmul se termină.
Fig. 2.12
36
M2.U2.4. Parcurgerea totală în lăţime
Observaţie. În general, mulţimea W a nodurilor accesibile din nodul sursă dat este o
submulţime a mulţimii nodurilor N. Pentru parcurgerea în lăţime a întregului digraf G = (N,
A) se utilizează algoritmul parcurgerii totale în lăţime (algoritmul PTBF), care este următorul:
algoritm PTBF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
l(s) = 0;
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează cel mai vechi nod x introdus în V;
for (x, y)∈ A do
if y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; l(y) = l(x) + 1;
end
V = V – {x}; W = W ∪ {x};
end;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; l(s) = 0;
end;
end;
end.
37
Fie mulţimea S={s | s ∈ N, s este nod sursă selectat la începutul sau pe parcursul
execuţiei algoritmului}.
În parcurgerea totală BF, dacă subgraful predecesor Gp = (Np, Ap) cu Np = {y∈ N |
p(y) ≠ 0} ∪ S, Ap ={(p(y), y) | y∈ Np -S} este o pădure şi Np = W, atunci Gp se numeşte pădure
parcurgere BF.
Algoritmul PTBF determină elementele tabloului p astfel încât subgraful predecesor Gp
= (Np, Ap) este o pădure parcurgere BF.
Fig. 2.13
38
Deoarece nu mai există noduri nevizitate, se efectuează V = {6} şi W = {1, 2, 3,
4, 5}.
Iteraţia 6: Se selectează nodul x = 6. Se efectuează V = Ø, W = {1, 2, 3, 4,
5, 6} şi algoritmul se termină.
Deoarece toate nodurile au fost vizitate pornind din nodul sursă s = 1 (nu a
fost necesar să selectăm noi noduri sursă) rezultatul parcurgerii totale în lăţime ar
fi putut fi obţinut şi cu algoritmul de parcurgere în lăţime. Deci, s-a obţinut o
singură arborescenţa parcurgere BF, care este reprezentată în figura 2.14.
Fig. 2.14
Fig. 2.15
39
Iteraţia 2: Se selectează cel mai vechi nod din V, acesta este x = 2.
Deoarece nodul 2 nu are succesori, se efectuează V = {5} şi W = {1, 2}.
Iteraţia 3: Cel mai vechi nod din V este x = 5. Deoarece nici nodul 5 nu are
succesori nevizitaţi, obţinem V = Ø şi W = {1, 2, 5}. Se determină un nou nod
sursă dintre nodurile nevizitate (din U). Fie acesta s = 3. Se fac actualizările U =
{4, 6, 7}, V = {3}, l = (0, 1, 0, ∞, 1, ∞, ∞).
Iteraţia 4: Se selectează singurul nod din V, acesta este x = 3. Deoarece
nodul 3 nu are succesori nevizitaţi, se efectuează V = Ø şi W = {1, 2, 3, 5}. Se
determină un nou nod sursă dintre nodurile nevizitate. Fie acesta s = 4. Se fac
actualizările U = {6, 7}, V = {4}, l = (0, 1, 0, 0, 1, ∞, ∞).
Iteraţia 5: Se selectează nodul x = 4. Deoarece (4, 6)∈ A şi 6∈ U, obţinem
U = {7}, V = {4, 6}, p = (0, 1, 0, 0, 1, 4, 0), l = (0, 1, 0, 0, 1, 1, ∞). Avem (4, 7)∈
A şi 7∈ U, deci U = Ø, V = {4, 6, 7}, p = (0, 1, 0, 0, 1, 4, 4), l = (0, 1, 0, 0, 1, 1,
1). Se actualizează mulţimile V şi W: V = {6, 7} şi W = {1, 2, 3, 4, 5}.
Iteraţia 6: Cel mai vechi nod din V este x = 6. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {7} şi W = {1, 2, 3, 4, 5, 6}.
Iteraţia 7: Singurul nod din V este x = 7. Se efectuează V = Ø, W = {1, 2, 3,
4, 5, 6, 7} şi algoritmul se termină.
Fig. 2.16
40
M2.U2.5. Rezumat
Algoritmul de parcurgere (totală) în lăţime a unui graf este o metodă
sistematică de vizitare a nodurilor grafului, pornind dintr-un nod sursă. Întotdeauna
nodul din care se continuă parcurgerea este cel mai vechi dintre nodurile vizitate şi
neanalizate. Deci, putem obţine algoritmul de parcurgere (totală) în lăţime
organizând ca o coadă a mulţimea V a nodurilor vizitate şi neanalizate din algoritmul
generic de parcurgere (totală).
41
Unitatea de învăţare M2.U3. Parcurgerea în adâncime
Cuprins
M2.U3.1. Introducere .................................................................................................... 42
M2.U3.2. Obiectivele unităţii de învăţare ..................................................................... 42
M2.U3.3. Parcurgerea în adâncime............................................................................... 43
M2.U3.4. Parcurgerea totală în adâncime ..................................................................... 47
M2.U3.5. Rezumat ........................................................................................................ 54
M2.U3.6. Test de evaluare a cunoştinţelor ................................................................... 54
M2.U3.1. Introducere
Una dintre cele mai des utilizate implementări ale algoritmului generic de
parcurgere (totală) este algoritmul de parcurgere (totală) în adâncime. Acesta
constă, după cum numele său sugerează, în a vizita cât mai “adânc” graful. Pentru
aceasta, la fiecare pas, se continua parcurgerea din ultimul nod vizitat, dacă el are
măcar un successor nevizitat, iar, în caz contrar, se revine la nodul din care el a
fost vizitat.
42
M2.U3.3. Parcurgerea în adâncime
algoritm PDF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
t = 1; t1(s) = 1;
for y∈ U do
begin
t1(y) = ∞; t2(y) = ∞;
end;
while V ≠ Ø do
begin
se selectează cel mai nou nod x introdus în V;
if există arc (x,y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; t = t +1;t1(y)= t;
end
else
begin
V = V – {x}; W = W ∪ {x}; t = t +1; t2(x)= t;
end;
end;
end.
43
În parcurgerea DF, dacă Np =W şi subgraful predecesor Gp = (Np, Ap) este o arborescenţă
atunci Gp se numeşte arborescenţă parcurgere DF.
Fig. 2.17
Iteraţia 2: Cel mai nou nod din V este x = 2. Avem (2, 3)∈ A, 3∈ U,
obţinem U = {4}, V = {1, 2, 3}, p = (0, 1, 2, 0), t = 3, t1 = (1, 2, 3, ∞).
Iteraţia 3: Se selectează cel mai nou nod din V, acesta este x = 3. Deoarece
nodul 3 nu are succesori nevizitaţi, se efectuează V = {1, 2}, W = {3}, t = 4, t2 =
(∞, ∞, 4, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 2. Avem (2, 4)∈ A, 4∈ U,
obţinem U = Ø, V = {1, 2, 4}, p = (0, 1, 2, 2), t = 5, t1 = (1, 2, 3, 5).
Iteraţia 5: Se selectează cel mai nou nod din V, acesta este x = 4. Deoarece
nu mai există noduri nevizitate, se efectuează V = {1, 2}, W = {3, 4}, t = 6, t2 =
(∞, ∞, 4, 6).
Iteraţia 6: Cel mai nou nod din V este x = 2. Se fac actualizările: V = {1},
W = {2, 3, 4}, t = 7, t2 = (∞, 7, 4, 6).
44
Iteraţia 7: Se selectează x = 1. Se efectuează V = Ø, W = {1, 2, 3, 4}, t = 8,
t2 = (8, 7, 4, 6) şi algoritmul se termină.
Fig. 2.18
Fig. 2.19
45
∞).
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 3.
Deoarece (3, 4)∈ A, 4∈ U, obţinem U = {5, 6}, V = {1, 2, 3, 4}, p = (0, 1, 2, 3, 0,
0), t = 4, t1 = (1, 2, 3, 4, ∞, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 4. Avem (4, 5)∈ A, 5∈ U,
obţinem U = {6}, V = {1, 2, 3, 4, 5}, p = (0, 1, 2, 3, 4, 0), t = 5, t1 = (1, 2, 3, 4, 5,
∞).
Iteraţia 5: Se selectează cel mai nou nod din V. Acesta este nodul x = 5.
Deoarece nodul 5 nu are succesori, se efectuează V = {1, 2, 3, 4}, W = {5}, t = 6,
t2 = (∞, ∞, ∞, ∞, 6, ∞).
Iteraţia 6: Se selectează cel mai nou nod din V. Acesta este nodul x = 4.
Deoarece nodul 4 nu are succesori nevizitaţi, se efectuează V = {1, 2, 3}, W = {4,
5}, t = 7, t2 = (∞, ∞, ∞, 7, 6, ∞).
Iteraţia 7: Cel mai nou nod din V este x = 3. Obţinem V = {1, 2}, W = {3, 4,
5}, t = 8, t2 = (∞, ∞, 8, 7, 6, ∞).
Iteraţia 8: Se selectează cel mai nou nod din V. Acesta este nodul x = 2. Se
efectuează V = {1}, W = {2, 3, 4, 5}, t = 9, t2 = (∞, 9, 8, 7, 6, ∞).
Iteraţia 9: Singurul nod din V este x = 1. Obţinem V = Ø, W = {1, 2, 3, 4,
5}, t = 10, t2 = (10, 9, 8, 7, 6, ∞) şi algoritmul se termină.
46
Fig. 2.20
algoritm PTDF;
begin
U = N – {s}; V = {s}; W = Ø;
for y∈ N do p(y) = 0;
t = 1; t1(s) = 1;
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează cel mai nou nod x introdus în V;
47
if există arc (x,y)∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; p(y) = x; t = t +1;t1(y)= t;
end
else
begin
V = V – {x}; W = W ∪ {x}; t = t +1; t2(x)= t;
end;
end;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; t = t+ 1; t1(s) = t;
end;
end;
end.
Fie mulţimea S={s | s ∈ N, s este nod sursă selectat la începutul sau pe parcursul
execuţiei algoritmului}.
În parcurgerea totală DF, dacă subgraful predecesor Gp = (Np, Ap) cu Np = {y∈ N |
p(y) ≠ 0} ∪ S, Ap ={(p(y), y) | y∈ Np -S} este o pădure şi Np = W, atunci Gp se numeşte pădure
parcurgere DF.
Algoritmul PTDF determină elementele tabloului p astfel încât subgraful predecesor Gp
= (Np, Ap) este o pădure parcurgere DF.
Parcurgerea totală DF poate fi utilizată la clasificarea arcelor digrafului G = (N, A) în
raport cu pădurea parcurgere DF. În această clasificare există două clase de arce:
• arce arborescenţă,
• arce nonarborescenţă.
Mulţimea arcelor arborescenţă, notată P, este P = Ap. Aceste arce introduc, în timpul
parcurgerii totale DF a digrafului G = (N, A), noduri în mulţimea nodurilor vizitate şi
48
neanalizate V. Mulţimea arcelor nonarborescenţă, notată P , este P = A – Ap. Clasa arcelor
Mulţimea arcelor de înaintare, notată I, este alcătuită din acele arce (x, y) pentru care
nodul x este un ascendent al nodului y în pădurea parcurgere DF. Mulţimea arcelor de
revenire, notată R, este alcătuită din acele arce (x, y) pentru care nodul x este un descendent al
nodului y în pădurea parcurgere DF. Mulţimea arcelor de traversare, notată T, este alcătuită
din acele arce (x, y) pentru care nodul x nu este nici ascendent, nici descendent al nodului y în
pădurea parcurgere DF. Aceste trei mulţimi de arce nonarborescenţă sunt disjuncte două câte
două şi P = I ∪ R ∪ T .
Teoremă. Într-o parcurgere totală DF a unui digraf G = (N, A), arcul (x, y) este:
(1) un arc arborescenţă sau de înaintare dacă şi numai dacă t1(x) < t1(y) < t2(y) < t2(x);
(2) un arc de revenire dacă şi numai dacă t1(y) < t1(x) < t2(x) < t2(y);
(3) un arc de traversare dacă şi numai dacă t1(y) < t2(y) < t1(x) < t2(x).
Fig. 2.21
49
că U = {4, 5, 6}, V = {1, 2, 3}, p = (0, 1, 2, 0, 0, 0), t = 3, t1 = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 3.
Deoarece (3, 4)∈ A, 4∈ U, obţinem U = {5, 6}, V = {1, 2, 3, 4}, p = (0, 1, 2, 3, 0,
0), t = 4, t1 = (1, 2, 3, 4, ∞, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 4. Avem (4, 5)∈ A, 5∈ U,
obţinem U = {6}, V = {1, 2, 3, 4, 5}, p = (0, 1, 2, 3, 4, 0), t = 5, t1 = (1, 2, 3, 4, 5,
∞).
Iteraţia 5: Se selectează cel mai nou nod din V. Acesta este nodul x = 5.
Deoarece nodul 5 nu are succesori, se efectuează V = {1, 2, 3, 4}, W = {5}, t = 6,
t2 = (∞, ∞, ∞, ∞, 6, ∞).
Iteraţia 6: Se selectează cel mai nou nod din V. Acesta este nodul x = 4.
Avem (4, 6)∈ A, 6∈ U, rezultă că U = Ø, V = {1, 2, 3, 4, 6}, p = (0, 1, 2, 3, 4, 4),
t = 7, t1 = (1, 2, 3, 4, 5, 7).
Iteraţia 7: Cel mai nou nod din V este x = 6. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {1, 2, 3, 4}, W = {5, 6}, t = 8, t2 = (∞, ∞, ∞, ∞, 6, 8).
Iteraţia 8: Se selectează cel mai nou nod din V. Acesta este nodul x = 4. Se
efectuează V = {1, 2, 3}, W = {4, 5, 6}, t = 9, t2 = (∞, ∞, ∞, 9, 6, 8).
Iteraţia 9: Cel mai nou nod din V este x = 3. Obţinem V = {1, 2}, W = {3, 4,
5, 6}, t = 10, t2 = (∞, ∞, 10, 9, 6, 8).
Iteraţia 10: Se selectează cel mai nou nod din V. Acesta este nodul x = 2. Se
efectuează V = {1}, W = {2, 3, 4, 5, 6}, t = 11, t2 = (∞, 11, 10, 9, 6, 8).
Iteraţia 11: Singurul nod din V este x = 1. Obţinem V = Ø, W = {1, 2, 3, 4,
5, 6}, t = 12, t2 = (12, 11, 10, 9, 6, 8) şi algoritmul se termină.
50
Fig. 2.22
Fig. 2.23
Exemplu
Aplicăm algoritmul de parcurgere totală în adâncime pe digraful din figura
2.24.
51
Fig. 2.24
52
sursă. Fie aceasta s = 6. Se efectuează U = {7}, V = {6}, t = 11, t1 = (1, 2, 6, 7, 3,
11, ∞).
Iteraţia 10: Se selectează nodul x = 6, fiind singurul nod din V. Deoarece
(6, 7)∈ A, 7∈ U, obţinem U = Ø, V = {6, 7}, p = (0, 1, 1, 3, 2, 0, 6), t = 12, t1 =
(1, 2, 6, 7, 3, 11, 12).
Iteraţia 11: Cel mai nou nod din V este x = 7. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {6}, W = {1, 2, 3, 4, 5, 7}, t = 13, t2 = (10, 5, 9, 8, 4, ∞,
13).
Iteraţia 12: Singurul nod din V este x = 6. Obţinem V = Ø, W = {1, 2, 3, 4,
5, 6, 7}, t = 14, t2 = (10, 5, 9, 8, 4, 14, 13) şi algoritmul se termină.
Fig. 2.25
Fig. 2.26
53
M2.U3.5. Rezumat
Algoritmul de parcurgere (totală) în adâncime a unui graf este o metodă
sistematică de vizitare a nodurilor grafului, pornind dintr-un nod sursă. Întotdeauna
nodul din care se continuă parcurgerea este cel mai nou dintre nodurile vizitate şi
neanalizate. Deci, putem obţine algoritmul de parcurgere (totală) în adâncime
organizând ca o stivă a mulţimea V a nodurilor vizitate şi neanalizate din algoritmul
generic de parcurgere (totală).
54
Unitatea de învăţare M2.U4. Aplicaţii ale parcurgerilor
Cuprins
M2.U4.1. Introducere .................................................................................................... 55
M2.U4.2. Obiectivele unităţii de învăţare ..................................................................... 55
M2.U4.3. Determinarea componentelor conexe ........................................................... 56
M2.U4.4. Determinarea componentelor tare conexe .................................................... 60
M2.U4.5. Sortarea topologică ....................................................................................... 64
M2.U4.6. Rezumat ........................................................................................................ 68
M2.U4.7. Test de evaluare a cunoştinţelor ................................................................... 68
M2.U4.1. Introducere
55
Durata medie de parcurgere a primei unităţi de învăţare este de 3 ore.
Un digraf G = (N, A) se numeşte slab conex sau conex dacă pentru oricare două noduri
diferite x, y există un lanţ care are aceste două noduri drept extremităţi.
Noţiunea de conexitate are sens şi pentru grafuri neorientate.
Se numeşte componentă conexă a unui digraf G = (N, A) un subgraf G´ = (N´, A´) al lui
G, care este conex şi care este maximal în raport cu incluziunea faţă de această proprietate
(oricare ar fi x∈ N - N´, subgraful G x′ generat de N ′x = N´ ∪ {x} nu este conex).
O componentă conexă G´ = (N´, A´) a unui digraf G = (N, A) se poate identifica prin
mulţimea N´ care generează subgraful G´.
Deoarece în problema conexităţii sensul arcelor nu contează, algoritmul va fi descris
pentru grafuri neorientate. Dacă G = (N, A) este digraf atunci i se asociază graful neorientat
Gˆ = ( Nˆ , Aˆ ) , unde N̂ = N, Â ={[x, y]| (x, y) ∈ A sau (y, x) ∈ A}. Este evident că G = (N, A)
şi Gˆ = ( Nˆ , A
ˆ ) au aceleaşi componente conexe (privite ca mulţimi de noduri).
Algoritmul de deteminare a componentelor conexe (algoritmul CC) este o adaptare a
algoritmului PTDF aplicat unui graf neorientat G = (N, A). Nu se calculează tablourile timp t1,
t2 şi nici vectorul predecesor p, în mulţimea N´ reţinem componenta conexă curentă, iar la
sfârşitul algoritmului nc va fi numărul de componte conexe ale grafului. Algoritmul CC este
următorul:
algoritm CC;
begin
U = N – {s}; V = {s}; W = Ø; nc = 1; N' = {s};
while W ≠ N do
begin
while V ≠ Ø do
begin
se selectează cel mai nou nod x introdus în V;
56
if există muchie [x, y]∈ A şi y∈ U then
begin
U = U – {y}; V = V ∪ {y}; N´ = N´ ∪ {y};
end
else
begin
V = V – {x}; W = W ∪ {x};
end;
end;
se tipăresc nc şi N´;
if U ≠ Ø then
begin
se selectează un nou nod sursă s din U;
U = U – {s}; V = {s}; nc = nc+ 1; N´ = {s};
end;
end;
end.
57
Fig. 2.27
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 2.
Deoarece [2, 4]∈ A, 4∈ U, obţinem U = Ø, V = {1, 3, 2, 4}, N´= {1, 2, 3, 4}.
Iteraţia 4: Cel mai nou nod din V este x = 4. Deoarece nu mai sunt noduri
nevizitate, obţinem V = {1, 3, 2}, W = {4}.
Iteraţia 5: Se selectează cel mai nou nod din V. Acesta este nodul x = 2. Se
efectuează V = {1, 3}, W = {2, 4}.
Iteraţia 6: Cel mai nou nod din V este x = 3. Deci, V = {1}, W = {2, 3, 4}.
Iteraţia 7: Se selectează nodul x = 1. Se efectuează V = Ø, W = {1, 2, 3, 4},
se tipăresc nc=1 şi N´= {1, 2, 3, 4} şi algoritmul se termină.
58
Exemplu Pentru a determina componentele conexe ale digrafului din figura
2.28, trebuie mai întâi să determinăm graful neorientat corespunzător lui. Acesta
este reprezentat în figura 2.29.
Fig. 2.28
Fig. 2.29
59
2, N´= {4}.
Iteraţia 8: Se selectează x = 4. Fiindcă [4, 6]∈ A, 6∈ U, obţinem U = {7},
V = {4, 6}, N´= {4, 6}.
Iteraţia 9: Cel mai nou nod din V este x = 6. Avem [6, 7]∈ A, 7∈ U,
obţinem U = Ø, V = {4, 6, 7}, N´= {4, 6, 7}.
Iteraţia 10: Se selectează cel mai nou nod din V. Acesta este nodul x = 7.
Deoarece nodul nu mai există noduri nevizitate, se efectuează V = {4, 6}, W = {1,
2, 3, 5, 7}.
Iteraţia 11: Cel mai nou nod din V este x = 6. Obţinem V = {4}, W = {1, 2,
3, 5, 6, 7}.
Iteraţia 12: Singurul nod din V este x = 4. Obţinem V = Ø, W = {1, 2, 3, 4,
5, 6, 7}, se tipăresc nc=2 şi N´= {4, 6, 7} şi algoritmul se termină.
Deci, digraful din figura 2.28 nu este conex, are două componente conexe:
{1, 2, 3, 5} şi {4, 6, 7}. Evident, aceste afirmaţii sunt adevărate şi pentru graful
neorientat din figura 2.29.
Un digraf G = (N, A) se numeşte tare conex dacă pentru oricare două noduri diferite x, y
există un drum de la x la y şi un drum de la y la x.
Evident, noţiunea de tare conexitate are sens numai pentru digrafuri.
Se numeşte componentă tare conexă a unui digraf G = (N, A) un subgraf G´ = (N´, A´)
al lui G, care este tare conex şi care este maximal în raport cu incluziunea faţă de această
proprietate (oricare ar fi x∈ N - N´, subgraful G x′ generat de N ′x = N´ ∪ {x} nu este tare
conex).
O componentă tare conexă G´ = (N´, A´) a unui digraf G = (N, A) se poate identifica cu
mulţimea N´ care generează subgraful G´.
Algoritmul de determinare a componentelor tare conexe (algoritmul CTC) este
următorul:
60
algoritm CTC;
begin
se aplică digrafului G algoritmul PTDF pentru a determina vectorul t2;
se determină G-1 graful invers al digrafului G;
se aplică digrafului invers G-1 algoritmul PTDF modificat în modul următor:
nodul sursă s este ales astfel încât t2(s) ≥ t2(x) pentru orice nod nevizitat x, unde t2 este
vectorul timp determinat cu algoritmul PTDF aplicat digrafului G.
se determină componentele tare conexe ale lui G după regula: nodurile care
sunt în aceeaşi arborescenţă DF a digrafului G-1 formează o componentă tare conexă a
lui G.
end.
={N1,…,Nq}, Â ={(Ni, Nj) | Ni, Nj∈ N̂ şi există (x, y)∈ A cu x∈ Ni, y∈ Nj}, unde N1,…,Nq
sunt componentele tare conexe ale digrafului G= (N, A).
Fig. 2.30
61
Fig. 2.31
Fig. 2.32
Fig. 2.33
62
reprezentat în figura 2.34.
Fig. 2.34
Fig. 2.35
63
M2.U4.5. Sortarea topologică
Sortarea topologică a unui digraf G = (N, A) fără circuite constă în ordonarea nodurilor
din N după regula:
dacă (x, y) ∈ A atunci x < y.
Digrafurile fără circuite sunt folosite în multe aplicaţii pentru a indica relaţia de
anterioritate dintre anumite evenimente.
O modalitate de testare a existenţei circuitelor întrun digraf este dată de următoarea
teoremă.
Teoremă Un digraf G = (N, A) este fără circuite dacă şi numai dacă orice parcurgere
totală DF a lui G nu produce arce de revenire.
64
Exemplu Aplicăm algoritmul de sortare topologică pe digraful fără circuite
din figura 2.36.
Fig. 2.36
65
Iteraţia 9: Se selectează nodul x = 1. Obţinem V = Ø, W = {4, 5, 2, 3, 1}, t =
10, t2 = (10, 7, 9, 4, 6) şi algoritmul se termină.
Fig. 2.37
Fig. 2.38
66
Iteraţia 2: Cel mai nou nod din V este x = 2. Avem (2, 3)∈ A, 3∈ U,
obţinem U = {4, 5, 6}, V = {1, 2, 3}, t = 3, t1 = (1, 2, 3, ∞, ∞, ∞).
Iteraţia 3: Se selectează cel mai nou nod din V. Acesta este nodul x = 3,
care nu are succesori. Deci, se efectuează V = {1, 2}, W = {3}, t = 4, t2 = (∞, ∞,
4, ∞, ∞, ∞).
Iteraţia 4: Cel mai nou nod din V este x = 2, care nu are succesori nevizitaţi.
Obţinem V = {1}, W = {3, 2}, t = 5, t2 = (∞, 5, 4, ∞, ∞, ∞).
Iteraţia 5: Se selectează nodul x = 1, fiind singurul nod din V. Se efectuează
V = Ø, W = {3, 2, 1}, t = 6, t2 = (6, 5, 4, ∞, ∞, ∞). Se selectează nodul sursă s = 6
pentru că ρ⁻(6) = 0. Se efectuează U = {4, 5}, V = {6}, t = 7, t1 = (1, 2, 3, ∞, ∞,
7).
Iteraţia 6: Se selectează nodul x = 6. Deoarece (6, 4)∈ A, 4∈ U, obţinem U
= {5}, V = {6, 4}, t = 8, t1 = (1, 2, 3, 8, ∞, 7).
Iteraţia 7: Cel mai nou nod din V este x = 4. Deoarece (4, 5)∈ A, 5∈ U,
obţinem U = Ø, V = {6, 4, 5}, t = 9, t1 = (1, 2, 3, 8, 9, 7).
Iteraţia 8: Cel mai nou nod din V este x = 5. Fiindcă nu mai există noduri
nevizitate, se efectuează V = {6, 4}, W = {3, 2, 1, 5}, t = 10, t2 = (6, 5, 4, ∞, 10,
∞).
Iteraţia 9: Se selectează nodul x = 4. Obţinem V = {6}, W = {3, 2, 1, 5, 4},
t = 11, t2 = (6, 5, 4, 11, 10, ∞).
Iteraţia 10: Singurul nod din V este x =1. Se efectuează V = Ø, W = {3, 2, 1,
5, 4, 6}, t = 12, t2 = (6, 5, 4, 11, 10, 12) şi algoritmul se termină.
Fig. 2.39
67
La începutul algoritmului existau două noduri care puteau fi alese ca
nod sursă: 1 şi 6. Deci, sortarea topologică a nodurilor grafului din figura 2.38, pe
care am obţinut-o în exemplul 2.18 alegând nodul 1 ca nod sursă, nu este unică.
Dacă am fi început execuţia algoritmului de sortare topologică din nodul
sursă s =6 am fi obţinut următoarea ordine a nodurilor: 1, 6, 4, 5, 2, 3. În figura
2.40 am redesenat graful din figura 2.38, aşezând nodurile în ordinea specificată
mai sus.
Fig. 2.40
M2.U4.6. Rezumat
În acestă unitate de învăţare am prezentat trei aplicaţii ale parcurgerii în
adâncime a unui graf: determinarea componentelor conexe ale unui graf orientat sau
neorientat, determinarea componentelor tare conexe ale unui digraf şi sortarea
topologică a unui digraf fără circuite.
Algoritmul de determinare a componentelor conexe ale unui graf poate fi
obţinut, pornind de la oricare dintre algoritmii de parcurgere. Însă, în vederea unei
abordări unitare a aplicaţiilor parcurgerilor, am folosit, ca punct de plecare, pentru
algoritmul de determinare a componentelor conexe tot algoritmul de parcurgere în
adâncime.
68
2. Determinaţi componentele tare conexe ale următorului graf:
Temă de control
69
3. Aplicaţi algoritmul de parcurgere totală în adâncime pe următorul digraf:
70