Sunteți pe pagina 1din 75

Proiectarea Algoritmilor

Curs 8 Puncte de articulaie,


Puni, Drumuri minime

Proiectarea Algoritmilor 2017


Bibliografie
[1] Giumale Introducere n Analiza Algoritmilor cap. 5.3, 5.4, 5.4.1

[2] Cormen Introducere n Algoritmi cap. Heap-uri binomiale (20),


Heap-uri Fibonacci (21), Drumuri minime de surs unica - primele 2
subcapitole (25.1 i 25.2)

[3] R. Sedgewick, K. Wayne - Algorithms and Data Structures Fall


2007 Curs Princeton -
http://www.cs.princeton.edu/~rs/AlgsDS07/06PriorityQueues.pdf

[4] Heap Fibonacci:


http://www.cse.yorku.ca/~aaw/Jason/FibonacciHeapAnimation.html

[5] Fibonacci heap:


http://www.growingwiththeweb.com/data-structures/fibonacci-
heap/overview/

Proiectarea Algoritmilor 2017


Obiective

Descoperirea algoritmilor de:


Identificare a punctelor de articulaie;
Identificare a punilor;

Identificare a drumurilor de cost minim.

Identificarea structurilor de date


necesare pentru reducerea complexitii
acestor algoritmi.

Proiectarea Algoritmilor 2017


Puncte de articulaie. Def. Exemple

Definiie: G = (V,E) graf neorientat, uV.


U este punct de articulaie dac x,yV,
x y, x u, y u, a.. x..y n G trece
prin u.
x
x y
y
u
u

Orice drum x..y trece prin u Exista x....y care nu trece prin
u este punct de articulaie. u u nu mai este punct de
articulaie!

Proiectarea Algoritmilor 2017


Algoritm naiv de detectare a
punctelor de articulaie
Elimin fiecare nod i verific
conectivitatea grafului rezultat:
Graf conex nodul nu e punct de
articulaie.
Altfel punct de articulaie.

Complexitate?
O(V(V+E))

Proiectarea Algoritmilor 2017


Puncte de articulaie. Teorem

Teorema 5.15: G = (V,E), graf neorientat


i uV. U este punct de articulaie n G
n urma DFS n G una din proprietile
de mai jos este satisfcut:
p(u) = null i u domin cel puin 2 subarbori;
p(u) null i v descendent al lui u n Arb(u)
a.. xArb(v) i (x,z) parcurs de DFS(G)
avem d(z) d(u).

Proiectarea Algoritmilor 2017


Situaii posibile
1) p(u) = null i u domina cel puin 2 subarbori:
u

x
y
u x
y

2) p(u) null i v descendent al lui u n Arb(u) a..


xArb(v) i (x,z) parcurs de DFS(G) d(z) d(u):

x
1/10

u 4/9
u
5/8
v
2/3 v
Pentru orice muchie din subarborele lui v nu
exist nici o muchie napoi spre u sau spre un 6/7 x
nod descoperit naintea lui u.
Proiectarea Algoritmilor 2017
Puncte de articulaie. Demonstraie teorem
(Ia)
p(u) = null i u domin cel puin 2 subarbori u este punct de articulaie.

Dem (Reducere la absurd): Fie A1 i A2 cei 2 subarbori, x A1 , y A2. Pp x....y i u x....y.

z = primul nod descoperit de DFS din care se poate ajunge la x i la y. Cf. T drumurilor albe x,y
Arb(z).

Dar x,yArb(u) 2 cazuri:


Caz 1: d(u)<d(z): Caz 2: d(z)<d(u):
u z
u

x y z u

Subarborele Subarborele
A1 A2 x y x y

Pp x....y i u x....y. Contradictie (1) x,y Contradictie (1),


nu sunt n subarbori p(u) null.
diferii ai lui Arb(u).

Proiectarea Algoritmilor 2017


Puncte de articulaie. Demonstraie teorem
(Ib)
u este punct de articulaie i este descoperit n ciclul principal al
DFS p(u) = null i u domin cel puin 2 subarbori.

Dem (Reducere la absurd): Fie nodurile x i y a.. u x..y. u =


primul nod descoperit din cale (altfel u nu mai e descoperit n ciclul
principal al DFS) => p(u) = null i x, y Arb(u).
DFS(G) x, y n acelai subarbore
V = noduri(G)
pp c x, y suntPentru
n acelai subarbore
fiecare nod u (u V) u
c(u) = alb; p(u) = null; // iniializare structur
2 subarbori
fie z rdcina celordate
x..z..y u nu etimp
punct
= 0; // de articulaie
reine distana de la rdcina arborelui z
DFS pan la nodul curent
se contrazice ipoteza.
Pentru fiecare nod u (u V)
Dac c(u) este alb x y
Atunci explorare(u); // explorez nodul
y
Contradicie x..z..y =>
x
u nu este punct de articulaie
u


Proiectarea Algoritmilor 2017
Puncte de articulaie. Demonstraie teorem
(IIa)
p(u) null i v descendent al lui u n Arb(u) a.. x
Arb(v) i (x,z) parcurs de DFS(G) are d(z) d(u)
u este punct de articulaie.
Dem (Reducere la absurd): Pp. u nu e punct
de articulaie w Arb(v), y Arb(u) a..
y..w. Fie z primul nod din y..w a.. z Arb(u) i
u
x ultimul nod din w..y a.. x Arb(u) (x,z)
Arb(u) taie frontiera Arb(u).
v

Dac d(z) > d(u) u..x, z alb la d(u) z


Arb(v) x Arb(u) contradicie (z Arb(u))

y
z Dac d(z) < d(u) contradicie (ipoteza)

y..w u punct de articulaie

Proiectarea Algoritmilor 2017


Puncte de articulaie. Demonstraie teorem
(IIb)
u este punct de articulaie i nu este descoperit n ciclul principal al DFS p(u)
null i v descendent al lui u n Arb(u) a.. x Arb(v) i (x,z) parcurs de DFS(G)
avnd d(z) d(u).

Dem: Fie nodurile x i y a.. u x..y i p(u) null. Se pot forma 3 tipuri de structuri:
x y

u u u

Arb(u) Arb(u)
x
v v y A2
A1
Arb(v) Arb(v)
y x
Arb(u)
Pentru primele 2 structuri, nu trebuie sa existe muchie care sa formeze ciclu de la
nici un nod din Arb(v) ctre vreun predecesor al lui u. Altfel x..y a.. u x..y.

Pentru a 3-a structura, trebuie s muchie care s formeze ciclu ctre un


predecesor al lui u de la niciun nod din cel puin un subarbore A1 sau A2.

Proiectarea Algoritmilor 2017


Puncte de articulaie. Structuri de date.

Structura de date de la DFS + pentru


fiecare nod u V se rein:
Low(u) = min{d(v) | v descoperit pornind din
u n cursul DFS i c(v) alb}

Subarb(u) = numrul subarborilor dominai


de u (dac e 2, atunci avem un punct de
articulaie).

Proiectarea Algoritmilor 2017


Idee algoritm
Se aplic DFS i se salveaz pentru
fiecare nod pn unde merge napoi (low):
low[u] = min {d(u), d(v) pentru toate
muchiile napoi (u,v), low(w) pentru toi fiii
w ai lui u}.

Pentru eficien, trebuie ca fiii s se


parcurg naintea prinilor ordinea
invers a d(u).
Proiectarea Algoritmilor 2017
Algoritm Tarjan (I)
Articulaii (G)
V = noduri(G) // iniializri
Timp = 0;
Pentru fiecare (u V)
c(u) = alb;
d(u) = 0;
p(u) = null;
low(u) = 0;
subarb(u) = 0; // reine numrul de subarbori dominai de u
art(u) = 0; // reine punctele de articulaie
Pentru fiecare (uV)
Dac c(u) e alb
Exploreaza(u);
Dac (subarb(u) > 1) // cazul n care u este rdcina n arborele
art(u) = 1 // DFS i are mai muli subarbori cazul
// 1 al teoremei

Proiectarea Algoritmilor 2017


Algoritm Tarjan (II)
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
c(u) = gri;
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr subarbori
// dominai de u
Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low

Proiectarea Algoritmilor 2017


Exemplu rulare (1)
d low Timp = 0
C(i) = alb
0 9 D(i) = 0
1 Low(i) = 0
P(i) = null
Subarb(i) =0
Art(i) = 0
2 Exploreaza (0)

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (2)
d low Low(0) = d(0) = 0
0 0 Timp = 1
0 9
1 C(0) = gri
P(1) = 0
Subarb(0) = 1
Exploreaza (1)
2
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (3)
d low Low(1) = d(1) = 1
0 0 Timp = 2
0 9
1 1 1 C(1) = gri
P(2) = 1
Subarb(1) = 1
Exploreaza (2)
2
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (4)
d low Low(2) = d(2) = 2
0 0 Timp = 3
0 9
1 1 1 C(2) = gri
P(3) = 2
Subarb(2) = 1
Exploreaza (3)
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (5)
d low Low(3) = d(3) = 3
0 0 Timp = 4
0 9
1 1 1 C(3) = gri
P(4) = 3
Subarb(3) = 1
Exploreaza (4)
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (6)
d low
0 0 Low(4) = d(4)=4
0 9
1 1 1 Timp =5
C(4) =gri
revenire
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (7)
d low Low(4) = d(4) = 4
Timp = 5
0 0 C(4) = gri
0 9
1 1 1 revenire
Low (3) = min {low(3), low(4)} = 3
Low(4) > d(3) art(3) = 1
P(5) = 3
Subarb(3) = 2
2 2 2 Exploreaza (5)

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 4 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (8)
d low Low(5) = d(5) = 5
0 0 Timp = 6
0 9
1 1 1 C(5) = gri
P(6) = 5
Subarb(5) = 1
Exploreaza (6)
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6

Proiectarea Algoritmilor 2017


Exemplu rulare (9)
d low
0 0 Low(6) = d(6) = 6
0 9
1 1 1 Timp = 7
C(6) = gri
revenire
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (10)
d low Low(6) = d(6) = 6
0 0 Timp = 7
0 9 C(6) = gri
1 1 1
revenire
Low (5) = min {low(5), low(6)} = 5
Low(6) > d(5) art(5) = 1
2 2 2 revenire
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (11)
d low Low(5) = d(5) = 5
Timp = 7
0 0 C(5) = gri
0 9
1 1 1 revenire
Low (3) = min {low(3), low(5)} = 3
Low(5) > d(3) art(3) = 1
P(7) = 3
Subarb(3) = 3
2 2 2 Exploreaza (7)

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 5 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (12)
d low Low(7) = d(7) = 7
0 0 Timp = 8
0 9
1 1 1 C(7) = gri
P(8) = 7
Subarb(7) = 1
Exploreaza (8)
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (13)
d low
0 0 Low(8) = d(8) = 8
0 9
1 1 1 Timp = 9
C(8) = gri
Low(8) = min{d(0), low(8)} = 0
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 c(u) = gri;
3 3 3 8 8
0 Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (14)
d low d(8) = 8
0 0 Low(8) = 0
0 9
1 1 1 Timp = 9
C(8) = gri
Low(8) = min{d(1), low(8)} = 0
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (15)
d low
d(8) = 8
0 0
0 9 Low(8) = 0
1 1 1 Timp = 9
C(8) = gri
revenire
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 7 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (16)
d low
0 0
0 9
1 1 1 low(7) = min(low(7), low(8)) = 0
low(8) < d(7) nu se
modific art(7)
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (17)
d low
0 0
0 9
1 1 1
low(7) = min(low(7), low(8)) = 0
revenire

2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 3
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (18)
d low
0 0
0 9 low(3) = min(low(3), low(7)) = 0
1 1 1
low(7) < d(3) nu se modific
art(3)
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (19)
d low
0 0
0 9 low(3) = min(low(3), low(7)) = 0
1 1 1
low(7) < d(3) nu se modific
art(3)
revenire
2 2 2

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (20)
d low
0 0
0 9 low(2) = min(low(2), low(3)) = 0
1 1 1
low(3) < d(2) nu se modific
art(2)
2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (21)
d low
0 0
0 9 low(2) = min(low(2), low(3)) = 0
1 1 1
low(3) < d(2) nu se modific
art(2)
revenire
2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (22)
d low
0 0
0 9 low(1) = min(low(1), low(2)) = 0
1 1 0
low(2) < d(1) nu se modific
art(1)
2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (23)
d low
0 0
0 9 low(1) = 0
1 1 0
low(1) = min(low(1), d(8)) = 0

2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (24)
d low
0 0
0 9 low(1) = 0
1 1 0
revenire

2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (25)
d low
0 0
0 9 low(0) = min{low(1), low(0)} = 0
1 1 0 P(0) = null continu cu
urmtorul copil

2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (26)
d low
0 0 low(0) = min(low(0),d (8)) = 0
0 9
1 1 0 P(9) = 0
Subarb(0) = 2
Exploreaza (9)
2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (27)
d low
0 0 9 9 Low(9) = d(9) = 9
0 9
1 1 0 Timp = 10
C(9) = gri
revenire
2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (28)
d low
0 0 9 9
0 9
1 1 0
low(0) = min(low(0), low(9)) = 0
P(0) = null revenire

2 2 0

Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
8 8 0 c(u) = gri;
3 3 0
Pentru fiecare nod v succs(u)
Dac (c(v) e alb)
p(v) = u; subarb(u)++; // actualizare nr
// subarbori dominai de u
4 4 45 5 57 7 0 Exploreaz(v);
low(u) = min{low(u), low(v)} // actualizare low
Dac (p(u) != null && low(v) d(u)) art(u) = 1;
// cazul 2 al teoremei
Altfel low(u) = min{low(u), d(v)} // actualizare low
6 6 6

Proiectarea Algoritmilor 2017


Exemplu rulare (29)
d low
1 0 9 9
0 9 Subarb(0) = 2 > 1 art(0) = 1
1 0 0
Articulaii (G)
2 V = noduri(G) // iniializri
Timp = 0;
2 0 Pentru fiecare (u V)
c(u) = alb;
d(u) = 0;
p(u) = null;
3 low(u) = 0;
3 8 8 0 subarb(u) = 0; // reine numrul de subarbori
0 // dominai de u
art(u) = 0; // reine punctele de articulaie
Pentru fiecare (uV)
4 4 4 7 Dac c(u) e alb
5 7 0 Exploreaza(u);
Dac (subarb(u) > 1) // cazul n care u este
5 5

// rdcina n arborele
art(u) = 1 // DFS i are mai muli subarbori
// cazul 1 al teoremei

6 6 6

Proiectarea Algoritmilor 2017


Algoritmul lui Tarjan adaptat pentru
determinarea CTC
index = 0 // nivelul pe care este nodul n arborele DFS
S = empty // se folosete o stiv care se iniializeaz cu
Pentru fiecare v din V
Dac (v.index e nedefinit) atunci // se pornete DFS din fiecare nod pe care
Tarjan(v) // nu l-am vizitat nc

Tarjan(v)
v.index = index // se seteaz nivelul nodului v
v.lowlink = index // reine strmoul nodului v
index = index + 1 // incrementez nivelul
S.push(v) // introduc v n stiv
Pentru fiecare (v, v') din E // se prelucreaz succesorii lui v
Dac (v'.index e nedefinit sau v' e n S) atunci // CTC deja identificate sunt ignorate
Dac (v'.index e nedefinit) atunci Tarjan(v') // dac nu a fost vizitat v intru n recursivitate
v.lowlink = min(v.lowlink, v'.lowlink) //actualizez strmoul
Dac (v.lowlink == v.index) atunci // printez CTC ncepnd de la coad spre rdcin
print CTC:"
Repet
v' = S.pop // extrag nodul din stiva i l printez
print v'
Pn cnd (v' == v) // pn cnd extrag rdcina

Proiectarea Algoritmilor 2017


Exemplu rulare (CTC)
d low
1 0 9 9
0 9
1 0 0

2
2 0

3
3 8 8 0
0

4 4 4 7
5 7 0
5 5

6 6 6

Proiectarea Algoritmilor 2017


Puni

Definiie: G = (V,E), graf neorientat i


(u,v) E. (u,v) este punte n G x,y
V, x y, a.. x..y conine muchia (u,v).

x v
u y x v
u y

Orice drum x..y trece prin (u,v) (u,v) nu este punte


=>(u,v) este punte

Proiectarea Algoritmilor 2017


Algoritm puni (I)
Puni(G)
V = noduri(G) // iniializri
Timp = 0;
Pentru fiecare nod u (u V)
c(u) = alb;
d(u) = 0;
p(u) = null;
low(u) = 0;
punte(u) =0; // nlocuiete: subarb(u) = 0; art(u) = 0;
Pentru fiecare nod u (u V)
Dac c(u) e alb
Exploreaz(u)

Proiectarea Algoritmilor 2017


Algoritm puni (II)
Exploreaz(u)
d(u) = low(u) = timp++; // iniializri
c(u) = gri;
Pentru fiecare nod v (v succs(u))
Dac c(v) e alb
p(v) = u; // se elimin: subarb(u)++;
Exploreaz(v);

low(u) = min{low(u), low(v)} // actualizare low

Dac (low(v) > d(u)) punte(v) = 1;

// n loc de: Dac(p(u) != null && low(v) >= d(u))


Altfel
Dac (p(u) v) low(u) = min{low(u), d(v)} // actualizare low

Proiectarea Algoritmilor 2017


Exemplu rulare (Puni)
d low
1 0 9 9
0 9
1 0 0

2
2 0

3
3 8 8 0
0

4 4 4 7
5 7 0
5 5

6 6 6

Proiectarea Algoritmilor 2017


Exemplu

x v
u y

u v

x
v

u
y

y

x

DFS din u; puntea este detectat n v


DFS din v; puntea este detectat n u

Proiectarea Algoritmilor 2017


Drumuri de cost minim
G = (V,E) un graf, iar w:E o funcie de cost asociat arcelor grafului
(w(u,v) = costul arcului (u,v)).

Cost(u..v) = costul drumului u..v (este aditiv costul drumului = suma


costurilor arcelor).

Variante:
1. Drumuri punct multipunct: pentru un nod dat s V, s se gseasc un drum de
cost minim de la s la u V; Dijkstra, Bellman-Ford
2. Drumuri multipunct punct: pentru un nod dat e V, s se gseasc un drum de
cost minim de la u V la e; GT i apoi 1
3. Drumuri punct punct: pentru dou noduri date u i v V, s se gseasc un
drum u..v de cost minim; Folosind 1
4. Drumuri multipunct multipunct: u, v V, s se gseasc un drum u..v de cost
minim. Floyd-Warshall
5. Drumuri de cost maxim!
Tem de gndire pentru acas posibil subiect de examen!

Proiectarea Algoritmilor 2017


Optimalitatea drumurilor minime (I)

Lem 25.1 (Subdrumurile unui drum minim sunt drumuri


optimale): G = (V,E), w : E funcie de cost asociat.
Fie p = v1v2...vk un drum optim de la v1 la vk. Atunci pentru
orice i i j cu 1 i j k, subdrumul lui p de la vi la vj este
un drum minim.

Dem: Fie pij = vi..vj subdrumul din p dintre vi i vj. p =


v1..vi..vj..vk => cost (p) = cost (v1..vi) + cost (vi..vj) + cost
(vj..vk).
Pp. prin absurd c vi..vj nu e optim => p a.. cost (p) <
cost (vi..vj) => p nu e drum minim Contrazice ipoteza
pij este drum minim.

Proiectarea Algoritmilor 2017


Optimalitatea drumurilor minime (II)

Corolar 25.2: G = (V,E), w : E funcie de cost asociat.


Fie p = s..uv un drum optim de la s la v. Atunci costul optim
al acestui drum poate fi scris ca (s,v) = (s,u) + w(u,v).

Dem: Conform teoremei anterioare, s..u e un drum optim


=> cost (s..u) = (s,u).

Lem 25.3: G = (V,E), w : E funcie de cost asociat.


(u,v) E avem (s,v) (s,u) + w(u,v).

Dem: Orice drum optim are costul mai mic ca al oricrui alt
drum.

Proiectarea Algoritmilor 2017


Drumuri minime de surs unic
Sunt concepui pentru grafuri orientate.

Bazai pe algoritmi Greedy.

Se pornete de la nodul de start i pe baza unui optim


local, drumurile sunt extinse i optimizate pn la soluia
final.

Notaii:
d[v] = costul drumului descoperit s..v;
(u,v) = costul drumului optim u..v; (u,v)= daca v R(u);
p(v) = predecesorul lui v pe drumul s..v.

Proiectarea Algoritmilor 2017


Drumuri minime de surs unic
Relaxarea arcelor dac d[v] > d[u] +
w(u,v), atunci actualizeaz d[v].

d = 10 d=7
s v s v

d=5 w(u,v) = 2 d=5 w(u,v) = 2


u u

Exemple: Dijkstra i BellmanFord.


Proiectarea Algoritmilor 2017
Algoritmul lui Dijkstra (I)
Folosete o coad de prioriti n care se adaug nodurile n
funcie de distana cunoscut n momentul respectiv de la s pn
la nod.

Se folosete NUMAI pentru costuri pozitive (w(u,v) > 0, u,vV).

Dijkstra_generic (G,s)
V = nodurile lui G
Ct timp (V != )
u = nod din V cu d[u] min
V = V - {u}

Pentru fiecare (v succesorii lui u) relaxare_arc(u,v)

// optimizare drum s..v pentru v succesorilor lui u

Proiectarea Algoritmilor 2017


Relaxarea arcelor (I)
Lem 25.5: G = (V,E), w : E funcie de cost asociat. v
V, d[v] obinut de algoritmul lui Dijkstra respect d[v] (s,v). n
plus, odat atins valoarea (s,v), ea nu se mai modific.

Dem:
v V, v R(s) d[v] = (s,v) = ; d[s] = (s,s) = 0 (iniializare)
Pt v R(s), iniializare d[v] = (s,v). Dem. prin reducere la
absurd c dup oricte relaxri, relaia se menine. Fie v primul vrf
pentru care relaxarea (u,v) determin d[v] < (s,v) dup relaxarea
(u,v): d[u] + w(u,v) = d[v] < (s,v) (s,u) + w(u,v) d[u] < (s,u).
Dar relaxarea nu modific d[u], iar v e primul pentru care d[v] <
(s,v). Contrazice presupunerea! => d[v] (s,v), v V
Cum d[v] (s,v) => odat ajuns la d[v] = (s,v), ea nu mai scade.
Cum relaxarea nu creste valorile => d[v] nu se mai modific.

Proiectarea Algoritmilor 2017


Relaxarea arcelor (II)
Lem 25.7: G = (V,E), w : E funcie de cost asociat.
Fie p = s..uv un drum optim de la s la v. Dac d[u] = (s,u)
la un moment dat, atunci ncepnd cu momentul imediat
urmtor relaxrii arcului (u,v) avem d[v] = (s,v)

Dem:
Dac nainte de relaxare d[v] > d[u] + w(u,v), prin relaxare
d[v] = d[u] + w(u,v). Altfel, d[v] d[u] + w(u,v) => dup
relaxare avem d[v] d[u] + w(u,v).
Cum d[u] = (s,u) i relaxarea (u,v) nu modific d[u] => d[v]
d[u] + w(u,v) = (s,u) + w(u,v) = (s,v) (conf. Corolar 25.2)
d[v] = (s,v)

Proiectarea Algoritmilor 2017


Algoritmul lui Dijkstra (II)
Dijkstra(G,s)
Pentru fiecare (u V) // iniializri
d[u] = ; p[u] = null;
d[s] = 0;
Q = construiete_coada(V) // coad cu prioriti
Ct timp (Q != )
u = ExtrageMin(Q); // extrage din V elementul cu d[u] minim
// Q = Q - {u} se execut n cadrul lui ExtrageMin
Pentru fiecare (v Q i v din succesorii lui u)
Dac (d[v] > d[u] + w(u,v))
d[v] = d[u] + w(u,v) // actualizez distana
p[v] = u // i printele

Proiectarea Algoritmilor 2017


Exemplu (I)

Proiectarea Algoritmilor 2017


Exemplu (II)
d[1] = 0;
(1): d[2] = 1; d[3] = 2; d[6] = 3;
(2): d[4] = 7; d[5] = 10;
(3): d[5] = 7;
Dijkstra(G,s)
Pentru fiecare (u V)
d[u] = ; p[u] = null;
d[s] = 0;
Q = construiete_coada(V) // coad cu prioriti
Ct timp (Q != )
u = ExtrageMin(Q); // extrage din V elementul cu d[u]
// minim
// Q = Q - {u} se execut n cadrul lui ExtrageMin
Pentru fiecare (v Q i v din succesorii lui u)
Dac (d[v] > d[u] + w(u,v))
d[v] = d[u] + w(u,v) // actualizez distana
p[v] = u // i printele

Proiectarea Algoritmilor 2017


Complexitate Dijkstra
Depinde de ExtrageMin coad cu
prioriti.

Operaii ce trebuie realizate pe coad +


frecvena lor:
Dijkstra(G,s)
insert V; Pentru fiecare (u V)
d[u] = ; p[u] = null;

delete V;
d[s] = 0;
Q = construiete_coada(V) // coad cu prioriti
Ct timp (Q != )
conine? E;

u = ExtrageMin(Q); // extrage din V elementul cu d[u]
minim

micoreaz_val E;
// Q = Q - {u} se execut in cadrul lui ExtrageMin
Pentru fiecare (v Q si v din succesorii lui u)
Dac (d[v] > d[u] + w(u,v))
este_vid? V.

d[v] = d[u] + w(u,v) // actualizez distana


p[v] = u // si printele

Proiectarea Algoritmilor 2017


Implementare cu vectori
Costuri:
insert 1 * V = V;
delete V * V = V2 (necesit cutarea
minimului);
conine? 1 * E = E;
micoreaz_val 1 * E = E;
este_vid? 1 * V = V;

Cea mai bun metod pentru grafuri


dese (EV2)!
Proiectarea Algoritmilor 2017
Implementare cu heap binar

Heap binar structur de date de tip


arbore binar + 2 constrngeri:
Fiecare nivel este complet; ultimul se umple
de la stnga la dreapta;
u Heap; u rd(st(u)) i u rd(dr(u)) (u
este dect ambii copii ai si) unde este
o relaie de ordine pe mulimea pe care sunt
definite elementele heapului.

Proiectarea Algoritmilor 2017


Operatii pe Heap Binar
delete
insert
24
15
9 15
9 6

7 8 3 24 7 8 3 6

15 6
9 24 9 15

7 8 3 6 7 8 3
24 15
9 15 9 6

7 8 3 6 7 8 3

Proiectarea Algoritmilor 2017


Implementare Heap Binar
Implementare folosind vectori.

Poziie[i] = unde se gsete n indexul de valori elementul de pe poziia i


din heap.

Reverse[i] = unde se gsete n heap elementul de pe poziia i din


valoare.

Implementare disponibila la [3].

Index 0 1 2 3 4 5 6 0 24
1 9 15 2
Valoare 7 6 15 8 24 9 3
Poziie 4 5 2 0 3 6 1 7 8 3 6
Reverse 3 6 2 4 0 1 5 3 4 5 6

Proiectarea Algoritmilor 2017


Heap Binar
Costuri:
insert logV * V = VlogV;
delete logV * V = VlogV;

conine? 1 * E = E;

micoreaz_val logV * E = ElogV;

este_vid? 1 * V = V.

Eficient dac graful are arce puine


comparativ cu numrul de noduri.
Proiectarea Algoritmilor 2017
Heap Fibonacci
Poate fi format din mai muli arbori.

Cheia unui printe cheia oricrui copil.

Fiind dat un nod u i un heap H:


p(u) printele lui u;
copil(u) legtura ctre unul din copiii lui u;
st(u), dr(u) legtura la fraii din stnga i din dreapta (cei
de pe primul nivel sunt legai ntre ei astfel);
grad(u) numrul de copii ai lui u;
min(H) cel mai mic nod din H;
n(H) numrul de noduri din H.

Proiectarea Algoritmilor 2017


Operatii Heap Fibonacci
Inserare nod O(1)
construiete un nou arbore cu un singur nod
(insert 8)

Min accesibil direct - min(H) O(1)

ExtrageMin O(logn) cost amortizat!


Mut copiii minimului pe prima coloan;
Consolideaz heap-ul.

Proiectarea Algoritmilor 2017


Operatii Heap Fibonacci
Consolidare Heap
Ct timp exist 2 arbori cu grade egale
Arb(x) i Arb(y), x < y:
Arb(y) transformat n copil al lui x;
grad[x] ++;

Applet i implementare disponibile la [4].

Gif + implementare putei gsi la [5]


Proiectarea Algoritmilor 2017
Consolidare Heap

Proiectarea Algoritmilor 2017


Costuri Heap Fibonacci

Costuri:
insert 1 * V = V;
delete logV * V = VlogV(amortizat!);

micoreaz_val 1 * E = E;

este_vid? 1 * V = V.

Cea mai rapid structur dpdv teoretic.

Proiectarea Algoritmilor 2017


Concluzii Dijkstra
Implementarea trebuie realizat n
funcie de tipul grafului pe care lucrm:
vectori pentru grafuri dese - O(V2);
heap pentru grafuri rare: HB - O(E logV),
HF - O(V log V+E)

Heapul Fibonacci este mai eficient dect


heapul binar dar mai dificil de
implementat.
Proiectarea Algoritmilor 2017
NTREBRI?

Proiectarea Algoritmilor 2017