Sunteți pe pagina 1din 191

PROIECTAREA SI IMPLEMENTAREA

ALGORITMILOR
AU

Conf. univ. dr. COSTEL BALC


2015

Tematica
1 Elemente de complexitatea algoritmilor
1.1 Notatii asimptotice . . . . . . . . . . . .
1.2 Exemple si proprietati . . . . . . . . . .
1.3 Analiza algoritmilor . . . . . . . . . . . .
1.4 Determinarea maximului dintr-un vector

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

7
7
11
15
22

2 Metoda Greedy
2.1 Descrierea metodei. Algoritmi generali . . . . . . .
2.2 O problema de maxim/minim . . . . . . . . . . . .
2.3 Memorarea optimala a textelor pe benzi . . . . . .
2.4 Problema rucsacului, varianta continua . . . . . . .
2.5 Problema planificarii spectacolelor . . . . . . . . . .
2.6 Arbori partiali de cost minim . . . . . . . . . . . .
2.7 Distante si drumuri minime. Algoritmul lui Dijkstra

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

27
27
30
33
35
42
49
55

3 Metoda Backtracking
3.1 Descrierea metodei. Algoritmi generali
3.2 Colorarea grafurilor . . . . . . . . . . .
3.3 Problema celor n dame pe tabla de sah
3.4 Problema nebunilor pe tabla de sah . .
3.5 Generarea obiectelor combinatoriale . .
3.5.1 Preliminarii . . . . . . . . . . .
3.5.2 Produs cartezian . . . . . . . .
3.5.3 Submultimi . . . . . . . . . . .
3.5.4 Aranjamente cu repetitie . . . .
3.5.5 Aranjamente . . . . . . . . . .
3.5.6 Permutari . . . . . . . . . . . .
3.5.7 Combinari . . . . . . . . . . . .
3.5.8 Combinari cu repetitie . . . . .
3.5.9 Permutari cu repetitie . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

64
64
72
75
79
88
88
89
90
92
92
96
98
100
102

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.

TEMATICA
4 Metoda Divide et Impera
4.1 Descrierea metodei. Algoritmi generali . . .
4.2 Complexitatea metodei. Teorema Master . .
4.3 Problema turnurilor din Hanoi . . . . . . . .
4.4 Cautarea binara . . . . . . . . . . . . . . . .
4.5 Algoritmi de sortare . . . . . . . . . . . . .
4.5.1 Problema sortarii . . . . . . . . . . .
4.5.2 Interclasarea a doi vectori . . . . . .
4.5.3 Sortarea prin interclasare (mergesort)
4.5.4 Sortarea rapida (quicksort) . . . . . .
4.6 O problema de acoperire . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

5 Metoda program
arii dinamice
5.1 Descrierea metodei. Algoritm general . . . . . . . . . . . . .
5.2 Problema subsirului crescator de lungime maxima . . . . . .
5.3 Problema drumului de suma maxima/minima ntr-o matrice

.
.
.
.
.
.
.
.
.
.

107
107
110
118
121
131
131
135
138
148
160

164
. 164
. 165
. 173

Evaluare
Prezenta: 10%
Activitate laborator: 30% (Programe si probleme din Temele de laborator)
Teme de casa: 10% (Programe si probleme suplimentare)
Examen final: 50% (Proba scrisa: teorie, algoritmi -cu implementaresi probleme)

Bibliografie
[1] A.V. Aho, J.E. Hopcroft, J.D. Ullman, Data Structures and Algorithms, AddisonWesley, Massachusetts, 2009.
[2] Gh. Barbu, V. P
aun, Programarea n limbajul C/C++, Editura Matrix Rom, Bucuresti, 2011.
[3] Gh. Barbu, V. P
aun, Calculatoare personale si programare n C/C++, Editura Didactic
a si Pedagogic
a, Bucuresti, 2005.
[4] Gh. Barbu, I. V
aduva, M. Bolosteanu, Bazele informaticii, Editura Tehnica, Bucuresti, 1997.
[5] C. Balc
au, Combinatoric
a si teoria grafurilor, Editura Universitatii din Pitesti,
Pitesti, 2007.
[6] O. Basc
a, L. Livovschi, Algoritmi euristici, Editura Universitatii din Bucuresti, Bucuresti, 2003.
[7] E. Cerchez, M. Serban, Programarea n limbajul C/C++ pentru liceu. Vol. 2: Metode
si tehnici de programare, Ed. Polirom, Iasi, 2005.
[8] E. Ciurea, L. Ciupal
a, Algoritmi. Introducere n algoritmica fluxurilor n retele, Editura Matrix Rom, Bucuresti, 2006.
[9] T.H. Cormen, Algorithms Unlocked, MIT Press, Cambridge, 2013.
[10] T.H. Cormen, C.E. Leiserson, R.L. Rivest, C. Stein, Introduction to Algorithms, MIT
Press, Cambridge, 2009.
[11] C. Croitoru, Tehnici de baz
a n optimizarea combinatorie, Editura Universitatii Al.
I. Cuza, Iasi, 1992.
[12] N. Dale, C. Weems, Programming and problem solving with JAVA, Jones & Bartlett
Publishers, Sudbury, 2008.
[13] D. Du, X. Hu, Steiner Tree Problems in Computer Communication Networks, World
Scientific Publishing Co. Pte. Ltd., Hackensack, 2008.
[14] S. Even, Graph Algorithms, Cambridge University Press, Cambridge, 2012.

5
[15] H. Georgescu, Tehnici de programare, Editura Universitatii din Bucuresti, Bucuresti,
2005.
[16] C.A. Giumale, Introducere n analiza algoritmilor. Teorie si aplicatii, Ed. Polirom,
Iasi, 2004.
[17] F.V. Jensen, T.D. Nielsen, Bayesian Networks and Decision Graphs, Springer, New
York, 2007.
[18] D. Jungnickel, Graphs, Networks and Algorithms, Springer, Heidelberg, 2013.
[19] D.E. Knuth, The Art Of Computer Programming. Vol. 4A: Combinatorial Algorithms, Addison-Wesley, Massachusetts, 2011.
[20] B. Korte, J. Vygen, Combinatorial Optimization. Theory and Algorithms, Springer,
Heidelberg, 2012.
[21] L. Livovschi, H. Georgescu, Sinteza si analiza algoritmilor, Editura Stiintific
a si
Enciclopedica, Bucuresti, 1986.
[22] D. Logofatu, Algoritmi fundamentali n C++: Aplicatii, Ed. Polirom, Iasi, 2007.
[23] D. Logofatu, Algoritmi fundamentali n Java: Aplicatii, Ed. Polirom, Iasi, 2007.
[24] D. Lucanu, M. Craus, Proiectarea algoritmilor, Ed. Polirom, Iasi, 2008.
[25] D.R. Popescu, Combinatoric
a si teoria grafurilor, Societatea de Stiinte Matematice
din Rom
ania, Bucuresti, 2005.
[26] N. Popescu, Data structures and algorithms using Java, Editura Politehnica Press,
Bucuresti, 2008.
[27] V. Preda, C. Balc
au, Entropy optimization with applications, Editura Academiei
Rom
ane, Bucuresti, 2010.
[28] R. Sedgewick, K. Wayne. Algorithms, Addison Wesley, Massachusetts, 2011.
[29] R. Stephens, Essential Algorithms: A Practical Approach to Computer Algorithms,
Wiley, Indianopolis, 2013.
[30] S. T
anasa, C. Olaru, S. Andrei, Java de la 0 la expert, Ed. Polirom, Iasi, 2007.
[31] T. Toadere, Grafe. Teorie, algoritmi si aplicatii, Editura Albastr
a, Cluj-Napoca,
2002.
[32] I. Tomescu, Combinatoric
a si teoria grafurilor, Tipografia Universitatii din Bucuresti, Bucuresti, 1978.
[33] I. Tomescu, Probleme de combinatoric
a si teoria grafurilor, Editura Didactica si
Pedagogic
a, Bucuresti, 1981.
[34] I. Tomescu, Data structures, Editura Universitatii din Bucuresti, Bucuresti, 2004.

6
[35] ***, Handbook of combinatorics, edited by R.L. Graham, M. Grotschel and L. Lovasz,
Elsevier, Amsterdam, 1995.
[36] ***, Handbook of discrete and combinatorial mathematics, edited by K.H. Rosen,
J.G. Michaels, J.L. Gross, J.W. Grossman and D.R. Shier, CRC Press, Boca Raton,
2000.

Tema 1
Elemente de complexitatea
algoritmilor
1.1

Notatii asimptotice

Vom defini un tip de functii care reprezinta un bun model pentru descrierea
complexitatii temporale a unui algoritm, adica a dependentei timpului de
executie fata de dimensiunea datelor de intrare.
Definitia 1.1.1. O functie asimptotic pozitiv
a (prescurtat a.p.) este o
functie f : N \ A R a..
A N este o multime finita;
n0 N \ A astfel ncat f (n) > 0, n n0 .
Observatia 1.1.1. De cele mai multe ori, multimea A este de forma
A=

{0, 1, 2, . . . , k} , unde k N.
{z
}
|

primele numere naturale

(3n4 + n + 3) n 5
Exemplul 1.1.1. Functia f : D R, f (n) =
, unde
(5n + 1)(n 8)
D = {n N | n 5, n 6= 8}, este asimptotic pozitiva, deoarece D = N \ A
cu A = {0, 1, 2, 3, 4, 8} (multime finita) si f (n) > 0, n 9.
ln(n5 + 1) n
, nu este
(n 1)(n 6)
asimptotic pozitiva, deoarece (n 1)(n 6) > 0, n 7, dar lim [ln(n5 +
Exemplul 1.1.2. Functia g : N \ {1, 6} R, g(n) =

1) n] = , deci n0 N, n0 7 a.. g(n) < 0, n n0 .


7

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

Lema 1.1.1. O functie polinomiala f : N R, de grad p,


f (n) = ap np + ap1 np1 + + a1 n + a0 , a0 , a1 , . . . , ap R, ap 6= 0,
este asimptotic pozitiva daca si numai daca ap > 0.
Definitia 1.1.2. Fie f si g doua functii asimptotic pozitive. Spunem ca f
si g sunt asimptotic echivalente si notam
f g (sau f (n) g(n))
daca

f (n)
= 1.
n g(n)

lim

Definitia 1.1.3. Fie g o functie a.p. (asimptotic pozitiva). Definim multimea


de functii O (g) (sau O (g(n))) ca fiind

O (g) = f f = functie a.p., c > 0, n0 N a..

f (n) c g(n), n n0 .
Daca f O (g) spunem ca f este asimptotic m
arginit
a superior
de g.
Pentru f O (g) se mai utilizeaza (n mod abuziv!) si scrierea f (n) =
O (g(n)).
Se citeste:
f este de ordinul O mare de g sau

f (n) este de ordinul O mare de g(n) (cand n ).

Observatia 1.1.2. Ilustrarea grafica a notatiei f O (g), si anume ca pentru


n n0 graficul functiei c g se afla deasupra graficului functiei f , este data
n Figura 1.1.1.
Definitia 1.1.4. Fie g o functie a.p. (asimptotic pozitiva). Definim multimea
de functii (g) (sau (g(n))) ca fiind

(g) = f f = functie a.p., c > 0, n0 N a..

c g(n) f (n), n n0 .
Daca f (g) spunem ca f este asimptotic m
arginit
a inferior
de g.

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

Figura 1.1.1:

Pentru f (g) se mai utilizeaza (n mod abuziv!) si scrierea f (n) =


(g(n)).
Se citeste:
f este de ordinul Omega mare de g sau
f (n) este de ordinul Omega mare de g(n) (cand n ).
Observatia 1.1.3. Ilustrarea grafica a notatiei f (g), si anume ca pentru
n n0 graficul functiei c g se afla sub graficul functiei f , este data n Figura
1.1.2.
Definitia 1.1.5. Fie g o functie a.p. (asimptotic pozitiva). Definim multimea
de functii (g) (sau (g(n))) ca fiind

(g) = f f = functie a.p., c1 , c2 > 0, n0 N a..

c1 g(n) f (n) c2 g(n), n n0 .
Daca f (g) spunem ca f este asimptotic m
arginit
a inferior

si superior de g (sau ca f si g au acela


si ordin de cre
stere).
Pentru f (g) se mai utilizeaza (n mod abuziv!) si scrierea f (n) =
(g(n)).
Se citeste:
f este de ordinul Theta (mare) de g sau

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

10

Figura 1.1.2:

f (n) este de ordinul Theta (mare) de g(n) (cand n ).


Observatia 1.1.4. Ilustrarea grafica a notatiei f (g), si anume ca pentru
n n0 graficul functiei f este cuprins ntre graficele functiilor c1 g si c2 g,
este data n Figura 1.1.3.

Figura 1.1.3:

Observatia 1.1.5. Notatia O se foloseste pentru a exprima complexitatea unui


algoritm corespunzatoare timpului de executie n cazul cel mai defavorabil,
fiind astfel cea mai adecvata analizei algoritmilor.

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

11

Notatia se foloseste pentru a exprima complexitatea unui algoritm corespunzatoare timpului de executie n cazul cel mai favorabil.
Notatia se foloseste atunci cand se poate determina exact timpul de
executie al unui algoritm sau atunci cand timpii de executie corespunzatori
cazurilor extreme sunt exprimati prin functii care au acelasi ordin de crestere.

1.2

Exemple si propriet
ati

Propozitia 1.2.1. Fie f si g doua functii asimptotic pozitive.


a) f (n) = O(g(n)) daca si numai daca g(n) = (f (n)).
b) f (n) = (g(n)) daca si numai daca f (n) = O (g(n)) si f (n) = (g(n)).
Demonstratie. a) Avem echivalentele
f (n) = O(g(n)) c > 0 si n0 N a.. f (n) c g(n), n n0
1
c > 0 si n0 N a.. f (n) g(n), n n0
c
1
c1 = > 0 si n0 N a.. c1 f (n) g(n), n n0
c
g(n) = (f (n)).
Echivalenta de la punctul b) este o consecinta imediata a definitiilor celor
trei notatii.
Propozitia 1.2.2. Fie f si g doua functii asimptotic pozitive astfel ncat
exista
f (n)
= .
lim
n g(n)
a) f (n) = O (g(n)) daca si numai daca [0, +).
b) f (n) = (g(n)) daca si numai daca (0, +].
c) f (n) = (g(n)) daca si numai daca (0, +).
Demonstratie. Deoarece f si g sunt functii asimptotic pozitive, rezulta ca
n1 N a.. f (n) > 0, n n1 ,
n2 N a.. g(n) > 0, n n2 .

(1.2.1)
(1.2.2)

a) Fie f (n) = O (g(n)), deci


c > 0 si n0 N a.. f (n) c g(n), n n0 .

(1.2.3)

12

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR


Fie n3 = max {n0 , n1 , n2 }.
Din relatiile (1.2.1) si (1.2.3) obtinem ca
0 < f (n) c g(n), n n3 .
Impartind cu g(n) > 0 rezulta ca
0<

f (n)
c, n n3 .
g(n)

Trecand la limita, n , obtinem ca


f (n)
c,
n g(n)

0 lim

adica 0 c, deci [0, +).


Presupunem acum ca [0, +).
Fie N = max {n1 , n2 }.
Deoarece [0, +) (adica limita este finita), rezulta ca sirul
este convergent, deci marginit. Prin urmare, M > 0 a..


f (n)


g(n) M, n N.


f (n)
Termenii sirului
fiind strict pozitivi, avem
g(n) nN

f (n)
g(n)

nN

f (n)
M, n N.
g(n)
Prin nmultire cu g(n) > 0, obtinem ca
f (n) M g(n), n N,
deci f (n) = O (g(n)).
b) Fie f (n) = (g(n)), deci
c > 0 si n0 N a.. c g(n) f (n), n n0 .
Fie n3 = max {n0 , n2 }. Impartind cu g(n) > 0 rezulta ca
0<c

f (n)
, n n3 .
g(n)

(1.2.4)

13

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR


Trecand la limita, n , obtinem ca
0 < c lim

f (n)
,
g(n)

(1.2.5)

adica 0 < c , deci (0, +].


Presupunem acum ca (0, +].
Fie, din nou, N= max{n
 1 , n2 }.


g(n)
f (n)
si
au termenii strict pozitivi.
Atunci sirurile
g(n) nN
f (n) nN
f (n)
Deoarece lim
= (0, +], rezulta ca exista
n g(n)

, daca (0, +),


g(n)
1

lim
= lim
=
n f (n)
n f (n)

0, daca = +,
g(n)
deci

g(n)
[0, +).
n f (n)
lim

Conform punctului a) rezulta ca g(n) = O (f (n)), deci conform Propozitiei


1.2.1 obtinem ca f (n) = (g(n)).
c) Aplicand Propozitia 1.2.1 si afirmatiile de la punctele a) si b), avem
echivalentele


[0, +)
f (n) = O (g(n))

f (n) = (g(n))
(0, +]
f (n) = (g(n))
[0, +) (0, +] (0, +).
Exemplul 1.2.1. Vom aplica propozitia anterioar
a pentru functia asimptotic
(3n4 + n + 3) n 5
, unde D = {n N | n
pozitiva f : D R, f (n) =
(5n + 1)(n 8)
5, n 6= 8}, considerata n Exemplul 1.1.1.
Deoarece

f (n)
(3n4 + n + 3) n 5
lim
= lim
n n3
n n3 (5n + 1)(n 8)
q

n4 n 3 + n13 + n34
1 n5
= lim
= 0,
n
n5 (5 + n1 )(1 n8 )

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

14

rezulta ca f (n) = O (n3 ), dar f (n) 6= (n3 ) si f (n) 6= (n3 ).


Deoarece

f (n)
(3n4 + n + 3) n 5
lim
= lim
n n2
n n2 (5n + 1)(n 8)
q

n4 n 3 + n13 + n34
1 n5
= lim
= ,
n
n4 (5 + n1 )(1 n8 )
rezulta ca f (n) = (n2 ), dar f (n) 6= O (n2 ) si f (n) 6= (n2 ).
Deoarece

f (n)
(3n4 + n + 3) n 5
lim
= lim 2
n n2 n
n n
n(5n + 1)(n 8)
q

1 n5
n4 n 3 + n13 + n34
3

= ,
= lim
8
1
4
n
5
n n(5 + n )(1 n )

rezulta ca f (n) = (n2 n), deci f (n) = O (n2 n) si f (n) = (n2 n).
Propozitia 1.2.3. Fie f si g doua functii asimptotic pozitive. Daca f g,
atunci f (n) = (g(n)).
f (n)
= 1 (0, ), deci conform
n g(n)
propozitiei anterioare rezulta ca f (n) = (g(n)).
Demonstratie. Daca f g, atunci lim

Propozitia 1.2.4. Fie f : N R o functie polinomiala de grad p,


f (n) = ap np + ap1 np1 + + a1 n + a0 , a0 , a1 , . . . , ap R,
astfel ncat ap > 0.
Atunci
a) f (n) = O (nk ), k p;
b) f (n) = (nk ), k p;
c) f (n) = (np ).
Demonstratie. Fie
ap np + ap1 np1 + + a1 n + a0
f (n)
=
lim
.
n
n nk
nk

= lim

a) Pentru k p avem
=

0,
ap ,

daca k > p,
daca k = p,

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

15

deci [0, +), si atunci conform propozitiei anterioare rezulta ca f (n) =


O (nk ).
b) Pentru k p avem

+, daca k < p,
=
ap ,
daca k = p,
deci (0, +], si atunci conform propozitiei anterioare rezulta ca f (n) =
(nk ).
c) Pentru k = p avem
ap np + ap1 np1 + + a1 n + a0
f (n)
=
lim
n
n np
np
= ap (0, +),

l = lim

deci conform propozitiei anterioare rezulta ca f (n) = (np ).

1.3

Analiza algoritmilor

Definitia 1.3.1. Un algoritm pentru rezolvarea unei probleme este o secventa finita de propozitii (declaratii ale datelor utilizate si instructiuni
aplicabile acestor date) prin aplicarea carora se trece de la informatia initial
a (datele de intrare, parametrii problemei) la informatia final
a
(datele de ie
sire, rezultatele problemei), cu respectarea urmatoarelor
caracteristici:
1) generalitatea: algoritmul este aplicabil pentru orice set de valori ale
datelor de intrare, compatibile cu problema;
2) unicitatea (neambiguitatea): pentru orice set fixat de valori ale
datelor de intrare (din domeniul de aplicabilitate al problemei) succesiunea instructiunilor aplicate este univoc determinata de algoritm
(adica nu depinde de alti factori precum locul sau momentul aplicarii);
3) finitudinea: pentru orice set de valori ale datelor de intrare aplicarea
algoritmului se termina dupa un numar finit de pasi, adica dupa executarea unei succesiuni finite de instructiuni.
Definitia 1.3.2. Un algoritm este corect daca pentru orice set de valori
ale datelor de intrare (din domeniul de aplicabilitate) rezultatele obtinute la
terminarea aplicarii algoritmului sunt corecte.

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

16

Definitia 1.3.3. a) Verificarea corectitudinii rezultatelor, n ipoteza c


a
algoritmul se ncheie dupa un numar finit de pasi, reprezinta problema
corectitudinii partiale.
b) Verificarea atat a corectitudinii partiale, cat si a finitudinii algoritmului, reprezinta problema corectitudinii totale.
Observatia 1.3.1. Corectitudinea invocata n definitiile anterioare este denumita si corectitudine semantic
a, pentru deosebirea de corectitudinea
sintactic
a, aceasta din urma nsemnand respectarea regulilor de scriere ale
limbajului folosit la descrierea algoritmului.
Definitia 1.3.4. Analiza performantelor unui algoritm consta n:
1) Estimarea resurselor de calcul, n functie de dimensiunea datelor
de intrare:
Calculul necesarului de resurse hardware (memorie interna,
externa etc.).
Evaluarea timpului de executie, adica a numarului de operatii
elementare (primitive) care se executa (operatii aritmetice, operatii
logice, comparatii, atribuiri etc.). In urma acestei evaluari se
obtine ordinul de complexitate al algoritmului (complexitatea algoritmului).

Figura 1.3.1: Complexitatea temporala a unui algoritm (cum depinde timpul


de executie de dimensiunea datelor de intrare)

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

17

2) Studiul eficientei algoritmului, n comparatie cu alti algoritmi care


rezolva aceeasi problema. Daca un algoritm utilizeaz
a mai putine resurse
de calcul (resurse hardware sau timp de executie) decat un altul, atunci
el este considerat ca fiind mai eficient.
Studiul eficientei poate eventual justifica optimalitatea algoritmului
(daca este cazul). Un algoritm este considerat optim daca se demonstreaza ca nu poate exista un algoritm mai eficient decat el, pentru
rezolvarea problemei date.
Observatia 1.3.2. Dimensiunea datelor de intrare poate fi exprimata
prin:
numarul de componente (valori reale, valori ntregi, caractere etc.) ale
datelor de intrare;
numarul de octeti sau de biti necesari stocarii datelor de intrare;
numarul de operatii aritmetice care trebuie efectuate si care, de cele
mai multe ori, este determinat de valorile unor date de intrare, etc.
Observatia 1.3.3. Ideal este ca un algoritm sa foloseasca resurse hardware
cat mai putine si sa necesite un timp de executie cat mai mic.
De cele mai multe ori, nsa, micsorarea necesarului de resurse hardware
face ca timpul de executie sa creasca si, invers, minimizarea timpului de
executie poate duce la o crestere considerabila a necesarului de resurse hardware.
Exemplul 1.3.1. Interschimbarea valorilor a doua variabile a si b (avand
acelasi tip).
Varianta 1: Cu memorie suplimentara, pentru o variabila aux (regula
celor trei pahare):
INTERSCHIMBARE1(a, b) :
aux a;
a b;
b aux;
Analiza algoritmului:
a) resurse hardware: 3 locatii de memorie;
b) operatii efectuate: 3 atribuiri.
Varianta 2: Fara memorie suplimentara:

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

18

INTERSCHIMBARE2(a, b) :
a a + b;
b a b;
a a b;
Analiza algoritmului:
a) resurse hardware: 2 locatii de memorie;
b) operatii efectuate:
3 atribuiri;
3 adunari si scaderi.
Observam ca Varianta 2 utilizeaza mai putine locatii de memorie, dar
mai multe operatii.
Exemplul 1.3.2. Calculul produsului a doua numere complexe z1 , z2 C. Fie
z1 = a1 + b1 i,
z2 = a2 + b2 i, cu a1 , a2 , b1 , b2 R,
sau, altfel scris,
z1 = (a1 , b1 ),
z2 = (a2 , b2 ).
Atunci
z1 z2 = (a1 + b1 i) (a2 + b2 i) =
= a1 a2 b1 b2 + (a1 b2 + a2 b1 ) i,
{z
} |
|
{z
}
partea real
a

partea imaginar
a

sau, altfel scris,

z1 z2 = (a1 a2 b1 b2 , a1 b2 + a2 b1 ).
{z
} |
{z
}
|
p

Varianta 1:

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

19

PRODUS1(a1 , b1 , a2 , b2 , p, q) :
citeste a1 , b1 , a2 , b2 ;
t1 a1 a2 ;
t2 b1 b2 ;
p t1 t2 ;
t1 a1 b2 ;
t2 a2 b1 ;
q t1 + t2 ;
afiseaz
a p, q;
Analiza algoritmului:
a) resurse hardware: 4 + 2 + 2 = 8 locatii de memorie;
b) operatii efectuate:
4 nmultiri;
2 adunari si scaderi;
6 atribuiri;
Varianta 2: Rescriem expresiile pentru partile reala si imaginara astfel:
p = a1 a2 b1 b2 = (a1 + b1 ) a2 b1 (a2 + b2 ),
q = a1 b2 + a2 b1 = (a1 + b1 ) a2 + a1 (b2 a2 ).
PRODUS2(a1 , b1 , a2 , b2 , p, q) :
citeste a1 , b1 , a2 , b2 ;
t1 a1 + b1 ;
t2 t1 a2 ;
t1 a2 + b2 ;
t3 b1 t1 ;
p t2 t3 ;
t1 b2 a2 ;
t3 a1 t1 ;
q t2 + t3 ;
afiseaz
a p, q;
Analiza algoritmului:
a) resurse hardware: 4 + 2 + 3 = 9 locatii de memorie;
b) operatii efectuate:
3 nmultiri;

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

20

5 adunari si scaderi;
8 atribuiri;
Observam ca Varianta 2 utilizeaza mai putine nmultiri, dar mai multe locatii
de memorie, mai multe adunari si scaderi si mai multe atribuiri.
Observatia 1.3.4. In analiza performantelor algoritmilor, este esential tipul
de masin
a pe care acestia vor rula:
masin
a secvential
a (masin
a cu acces aleator, Random Access Machine = RAM), n care toate prelucrarile sunt executate secvential;
masin
a paralel
a (de regula, un sistem de calcul multiprocesor ), n care
se pot executa simultan (n paralel) portiuni ale aceluiasi algoritm.
Observatia 1.3.5. Pentru analiza algoritmilor ce vor fi prezentati n continuare, stabilim urmatoarele conventii:
vom lucra cu algoritmi secventiali (nu paraleli ), destinati a fi implementati pe masini secventiale;
n general, ne vom referi numai la analiza timpului de executie (complexitatea temporal
a);
timpul de executie al oricarei operatii elementare nu depinde de valorile operanzilor (timpul de executie pentru a calcula 1+2 nu difera de
timpul de executie pentru a calcula 12345+6789);
timpul necesar accesarii datelor nu depinde de locatia acestora n memorie (nu este diferenta ntre timpul necesar prelucrarii primului element al unui tablou si cel al prelucrarii penultimului element);
De asemenea, pentru simplificarea calculelor, de cele mai multe ori ne
vom concentra atentia numai asupra anumitor operatii, semnificative pentru
algoritmii respectivi, rezumandu-ne astfel numai la estimarea (numararea)
acestora.
Definitia 1.3.5. Fie A un algoritm, n dimensiunea datelor de intrare si
T (n) timpul de executie estimat pentru algoritmul A.
Ordinul de complexitate al algoritmului (complexitatea algoritmului) A este ordinul (de crestere) al functiei T (n) (cand n ).

Definitia 1.3.6. Un algoritm A este considerat asimptotic-optim daca se


demonstreaza ca nu exista un algoritm avand un ordin de complexitate mai
bun pentru rezolvarea problemei date, adica pentru orice algoritm A care
rezolva problema data avem T (n) = (T (n)), unde T (n) si T (n) reprezinta
timpii de executie pentru algoritmii A, respectiv A .

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

21

Definitia 1.3.7. Fie A un algoritm, n dimensiunea datelor de intrare si


T (n) timpul de executie estimat pentru algoritmul A.
1) Spunem ca algoritmul A are complexitate (comportare) polinomial
a (sau ca este polinomial sau ca apartine clasei P ) daca
p > 0 astfel ncat T (n) = O (np ).
2) In particular, daca T (n) = O (n) atunci spunem ca algoritmul A are
complexitate (comportare) liniar
a (sau ca este liniar).
Observatia 1.3.6. Algoritmii polinomiali sunt, n general, acceptabili n practica. Algoritmii care necesita un timp de calcul exponential sunt utilizati
numai n cazuri exceptionale si doar pentru date de intrare de dimensiuni
relativ mici.
Definitia 1.3.8. Timpul de executie T (n) al unui algoritm poate avea una
din urmatoarele semnificatii:
1) timpul n cazul cel mai defavorabil, care ofera o limita superioara
a timpului de executie;
2) timpul n cazul cel mai favorabil, care ofera o limita inferioara a
timpului de executie;
3) timpul mediu, care se obtine ca raport dintre suma timpilor de executie
pentru toate seturile de date de intrare posibile si numarul acestor seturi.
Observatia 1.3.7. In general, n analiza complexitatii unui algoritm se are n
vedere timpul n cazul cel mai defavorabil deoarece:
acest timp ofera certitudinea ca, pentru orice set de date de intrare,
algoritmul nu va dura mai mult decat atat;
situatiile cele mai favorabile se ntalnesc destul de rar;
timpul mediu este dificil de calculat si, de cele mai multe ori, acesta
este foarte apropiat, ca valoare estimata, de timpul n cazul cel mai
defavorabil.

22

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

1.4

Determinarea maximului dintr-un vector

Problema determin
arii maximului dintr-un vector este urmatoarea:
Se considera un vector A = (a1 , a2 , . . . , an ), n 1. Se cere sa se determine
maximul dintre elementele a1 , a2 , . . . , an si prima pozitie pe care acesta apare,
adica perechea (m, k), unde
m = max{ai | 1 i n},
k = min{i | 1 i n, ai = m}.
Observatia 1.4.1. In practica, problema consta n gasirea primei nregistrari
ntr-un fisier sau baza de date dupa valoarea maxima a unui camp, numit
cheie.
Algoritmul 1.4.1 (Determinarea maximului dintr-un vector). Descrierea
n pseudocod a algoritmului are urmatoarea forma.
MAX(A, n, m, k) :
// Timp de executie
Nr. de executii
k 1;
//
c1
1
m A[1];
//
c2
1
//
c3
n
for i = 2, n do
if m < A[i] then
//
c4
n1
m A[i];
//
c2
?
k i;
//
c1
?
Analiza complexit
atii algoritmului:
1) Timpul de executie n cazul cel mai favorabil, si anume cand elementul a1
este maxim:
Tf av (n) = 1 c1 + 1 c2 + n c3 + (n 1) c4 + 0 (c2 + c1 )
= (c3 + c4 ) n + (c1 + c2 c4 ) .
| {z }
{z
}
|
constant
a

constant
a

Rezulta ca

T (n) = (n).

(1.4.1)

2) Timpul de executie n cazul cel mai defavorabil si anume cand a1 < a2 <
< an :
Tdef (n) = 1 c1 + 1 c2 + n c3 + (n 1) c4 + (n 1) (c2 + c1 )
= (c1 + c2 + c3 + c4 ) n + (c4 ) .
| {z }
{z
}
|
constant
a

constant
a

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

23

Rezulta ca
T (n) = O (n).

(1.4.2)

Din relatiile (1.4.1) si (1.4.2) obtinem ca


T (n) = (n).

(1.4.3)

3) Timpul de executie mediu:


Pentru orice set arbitrar fixat A = (a1 , a2 , . . . , an ) de valori ale elementelor vectorului A, blocul de instructiuni
m A[i];
ki
se executa de cel mult j 1 ori, unde j este primul indice pe care
maximul apare, adica
j = min{i | 1 i n, ai = max ak }.
k=1, n

Evident, j poate lua oricare dintre valorile


1, 2, . . . , n,
iar toate aceste situatii sunt echiprobabile, sub presupunerea ca domeniul de valori pentru elementele vectorului este un interval [a, b] de
numere reale (caz n care pentru orice variabile aleatoare independente
X1 , X2 , . . . , Xn cu valori a1 , a2 , . . . , respectiv an din intervalul [a, b],
evenimentul Xi = Xl are probabilitatea nula pentru orice i 6= l, deci
pentru orice j {1, 2, . . . , n} evenimentul
(Xj > X1 , . . . , Xj > Xj1 , Xj Xj+1 , . . . Xj Xn )
are aceeasi probabilitate cu evenimentul
(Xj > X1 , . . . , Xj > Xj1 , Xj > Xj+1 , . . . Xj > Xn ),
deci aceasta probabilitate nu depinde de indicele j, deci este egala cu
1/n). Daca domeniul este o multime finita, atunci vom presupune
n plus ca elementele vectorului sunt distincte doua cate doua (caz
n care, daca multimea are p elemente {b1 , b2 , . . . , bp }, cu b1 < b2 <
. . . < bp , p n, atunci vectorul A = (a1 , a2 , . . . , an ) poate fi ales n Anp
moduri, iar, pentru orice j {1, 2, . . . , n}, cazurile n care j este primul

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

24

indice pe care maximul apare n vectorul A sunt cele n care exista


i {n, n + 1, . . . , p} astfel ncat aj = bi si a1 , . . . aj1 , aj+1, . . . , an
p
P
n1
Ai1
, deci
{b1 , b2 , . . . , bi1 }, deci numarul acestor cazuri este egal cu
i=n

probabilitatea ca primul indice pe care maximul apare n vectorul A sa


fie j este
p
P

i=n

n1
Ai1

Anp

(n 1)!

p
P

i=n
n! Cpn

n1
Ci1

(n 1)! Cpn
1
= ,
n
n! Cp
n

deci, din nou, aceasta probabilitate nu depinde de indicele j).


Daca notam cu Tj (n) timpul de executie efectiv, n cazul n care j este
primul indice pe care maximul apare, atunci timpul de executie mediu
este dat de

Tmed (n) =

n
P

Tj (n)

j=1

Dar
Tj (n) 1 c1 + 1 c2 + n c3 + (n 1) c4 + (j 1) (c2 + c1 )
= (c3 + c4 ) n + (c1 + c2 ) j c4 .
Atunci

Tmed (n)
=


n 
P
(c3 + c4 ) n + (c1 + c2 ) j c4

j=1

(c3 + c4 ) n2 + (c1 + c2 )
n
(c3 + c4 ) n2 + (c1 + c2 )

n
P

j=1

j c4 n

n (n + 1)
c4 n
2

n+1
c4
= (c3 + c4 ) n + (c1 + c2 )



2
c1 + c2
c1 + c2
=
+ c3 + c4 n +
c4
2
2
|
|
{z
}
{z
}
constant
a

constant
a

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

25

In toate cele trei variante, s-a obtinut o dependenta liniara a timpului de executie fata de dimensiunea datelor de intrare. Astfel am justificat
urmatorul rezultat.
Propozitia 1.4.1. Algoritmul 1.4.1 are complexitatea (n), deci este un
algoritm liniar.
Observatia 1.4.2. O justificare imediata a acestui rezultat este data de relatia
(1.4.3), deci nu necesita o estimare mai buna a timpului de executie mediu.
Am dorit, nsa, si o exemplificare a modului de evaluare a acestui timp.
Observatia 1.4.3. In contextul evaluarii de mai sus a timpului de executie
mediu n cazul n care domeniul este o multime finita, daca renuntam la
presupunerea ca elementele vectorului sunt distincte doua cate doua, atunci
probabilitatea ca primul indice pe care maximul apare n vectorul A sa fie
j nu mai este aceeasi pentru toti indicii j {1, 2, . . . , n}. Intr-adevar, sa
consideram din nou ca multimea are p elemente {b1 , b2 , . . . , bp }, cu b1 <
b2 < . . . < bp , p N . Acum vectorul A = (a1 , a2 , . . . , an ) poate fi ales
n pn moduri, iar, pentru orice j {1, 2, . . . , n}, cazurile n care j este
primul indice pe care maximul apare n vectorul A sunt cele n care exista i {1, 2, . . . , p} astfel ncat aj = bi , a1 , . . . aj1 {b1 , b2 , . . . , bi1 } si
aj+1 , . . . , an {b1 , b2 , . . . , bi }, deci numarul acestor cazuri este egal cu
p
X
i=1

(i 1)j1 inj

(cu conventia ca 00 = 1), deci probabilitatea ca primul indice pe care maximul


apare n vectorul A sa fie j este de aceasta data

tj =

p
P

i=1

(i 1)j1 inj
pn

Aceasta probabilitate depinde de indicele j. Se observa ca

tj tj+1 =

p
P

i=1

deci t1 > t2 > > tn .

(i 1)j1 inj1
pn

> 0, j {1, 2, . . . , n 1},

TEMA 1. ELEMENTE DE COMPLEXITATEA ALGORITMILOR

26

Optimalitatea algoritmului:
Vom analiza eficienta algoritmului prin prisma numarului de comparatii efectuate si care invoca elemente ale vectorului.
Evident, Algoritmul 1.4.1 efectueaza n1 asemenea comparatii, de forma
m < A[i].
Din acest punct de vedere, rezultatul urmator justifica optimalitatea acestui algoritm.
Propozitia 1.4.2. Pentru determinarea maximului dintre n numere, n
N , sunt necesare n 1 comparatii.
Demonstratie. Notam proprietatea din enunt cu P (n) si i demonstram valabilitatea prin inductie dupa n.
P (1): Pentru n = 1 sunt necesare 0 = 1 1 comparatii, deci P (1) este
adevarata.
P (k 1) P (k): Fie k N, k 2. Presupunem afirmatia adevarata
pentru orice k 1 numere si o demonstram pentru k numere.
Fie a1 , a2 , ..., ak1 , ak aceste numere.
Fie ai si aj , i 6= j, numerele care sunt supuse primei comparatii.
Presupunem ca ai aj (rationamentul este similar n cazul cand aj ai ).
Atunci
max{a1 , a2 , ..., ak1 , ak } = max{a1 , a2 , ..., aj1, aj+1 , ..., ak1 , ak },
adica avem de determinat n continuare maximul dintre k 1 numere (celelalte k 2 numere si ai ). Pentru aceasta, conform ipotezei de inductie, sunt
necesare nca k 2 comparatii. Deci obtinem un total de 1 + (k 2) = k 1
comparatii.
Demonstratia prin inductie este astfel ncheiata.
Urmatorul rezultat este o consecinta directa a propozitiei anterioare.
Propozitia 1.4.3. Algoritmul 1.4.1 este optim (n clasa algoritmilor bazati
pe comparatii de chei).

Tema 2
Metoda Greedy
2.1

Descrierea metodei. Algoritmi generali

Metoda Greedy (a optimului local) presupune elaborarea unor strategii


de rezolvare a problemelor de optim, n care se urmareste maximizarea sau
minimizarea unei functii obiectiv.
Se aplica problemelor n care se da o multime finita A = {a1 , a2 , . . . , an }
(multimea de candidati), continand n date de intrare, pentru care se cere
sa se determine o submultime B A care sa ndeplineasca anumite conditii
pentru a fi acceptata. Aceasta submultime se numeste solutie posibil
a
(solutie admisibil
a, pe scurt solutie).
Deoarece, n general, exista mai multe solutii posibile, trebuie avut n
vedere si un criteriu de selectie, conform caruia, dintre acestea, sa fie aleasa
una singura ca rezultat final, numita solutie optim
a.
Solutiile posibile au urmatoarele proprietati:
multimea vida este ntotdeauna solutie posibila;
daca B este solutie posibila si C B, atunci si C este solutie posibila.
In continuare sunt prezentate doua scheme de lucru, care urmeaza aceeasi
idee, diferentiindu-se doar prin ordinea de efectuare a unor operatii:
Algoritmul 2.1.1 (Metoda Greedy, varianta I).
Se pleaca de la solutia vida ();
Se alege, pe rand, ntr-un anumit fel, un element din A neales la pasii
precedenti.

27

TEMA 2. METODA GREEDY

28

Daca includerea elementului ales n solutia partiala construita anterior conduce la o solutie posibila, atunci construim noua solutie prin
adaugarea elementului ales.
GREEDY1(A, n, B) :
B ;
for i = 1, n do
x ALEGE(A, i, n);
if SOLUTIE POSIBILA (B, x) then
B B {x};
Observatia 2.1.1.
Functia ALEGE(A, i, n) returneaza un element x = aj {ai , . . . , an }
si efectueaza interschimbarea ai aj ;
Functia SOLUTIE POSIBILA(B, x) verifica daca B{x} este solutie
posibila a problemei.
Functia ALEGE este cea mai dificil de realizat, deoarece trebuie sa
implementeze criteriul conform caruia alegerea la fiecare pas a cate
unui candidat sa conduca n final la obtinerea solutiei optime.
Algoritmul 2.1.2 (Metoda Greedy, varianta a II-a).
Metoda e asemanatoare primeia, cu exceptia faptului ca se stabileste de
la nceput ordinea n care trebuie analizate elementele din A.
GREEDY2(A, n, B) :
PRELUCREAZA (A, n);
B ;
for i = 1, n do
if SOLUTIE POSIBILA (B, ai ) then
B B {ai };
Observatia 2.1.2. Prin apelul procedurii PRELUCREAZA(A, n) se efectueaza o permutare a elementelor multimii A, stabilind ordinea de analiza a
acestora. Aceasta este procedura cea mai dificil de realizat.
Observatia 2.1.3.

29

TEMA 2. METODA GREEDY

Metoda Greedy nu cauta sa determine toate solutiile posibile si apoi


sa aleaga pe cea optima conform criteriului de optimizare dat (ceea ce
ar necesita n general un timp de calcul si spatiu de memorie mari), ci
consta n a alege pe rand cate un element, urmand sa-l nghita eventual n solutia optima. De aici vine si numele metodei (Greedy = lacom).
Astfel, daca trebuie determinat maximul unei functii de cost depinzand
de a1 , . . . , an , ideea generala a metodei este de a alege la fiecare pas acel
element care face sa creasca cat mai mult valoarea acestei functii. Din
acest motiv metoda se mai numeste si a optimului local.
Optimul global se obtine prin alegeri succesive, la fiecare pas, ale optimului local, ceea ce permite rezolvarea problemelor fara revenire la
deciziile anterioare (asa cum se ntampla la metoda backtracking).
In general metoda Greedy ofera o solutie posibila si nu ntotdeauna
solutia optima. De aceea, daca problema cere solutia optima, algoritmul trebuie sa fie nsotit si de justificarea faptului ca solutia generata
este optima. Pentru aceasta, este frecvent ntalnit urmatorul procedeu:
se demonstreaza prin inductie matematica faptul ca pentru orice
pas i {0, 1, . . . , n}, daca Bi este solutia posibila construita la
pasul i, atunci exista o solutie optima B astfel ncat Bi B ;

se arata ca pentru solutia finala, Bn , incluziunea Bn B devine


egalitate, Bn = B , deci Bn este solutie optima.

Exemplul 2.1.1. Se da o multime A = {a1 , a2 , . . . , an } cuPai R, i = 1, n. Se


cere sa se determine o submultime B A, astfel ncat
b sa fie maxima.
bB

Rezolvare. Daca B A si b0 B, cu b0 0, atunci


X
X
b
b.
bB

bB\{b0 }

Rezulta ca putem ntelege prin solutie posibil


a o submultime B a lui A
cu toate elementele strict pozitive.
Vom aplica metoda Greedy, n varianta I, n care
functia ALEGE furnizeaza x = ai ;
functia SOLUTIE POSIBILA returneaza 1 (adevarat) daca x > 0
si 0 (fals) n caz contrar.


30

TEMA 2. METODA GREEDY


ALEGE (A, i, n) :
x ai ;
returneaz
a x;
SOLUTIE POSIBILA(B, x) :
if x > 0 then
returneaz
a 1;
else
returneaz
a 0;

2.2

// adev
arat
// fals

O problem
a de maxim/minim

Se considera sirurile de numere reale


a1 , a2 , . . . , an si b1 , b2 , . . . , bn , n 1.
Se cere sa se determine doua permutari , Sn (Sn = grupul permutarilor
de ordin n) astfel ncat:
n
X
a)
a(i) b(i) sa fie maxima;
i=1

b)

n
X
i=1

a(i) b(i) sa fie minima.

Pentru rezolvarea acestei probleme, vom demonstra mai ntai urmatoarea


lema.
Lema 2.2.1. Fie sirurile crescatoare de numere reale
a1 a2 . . . an si b1 b2 . . . bn , n 1.
Atunci n
n
X
X
ak b(k) ;
a)
ak bk = max
b)

k=1
n
X
k=1

Sn

k=1

ak bnk+1 = min

Sn

n
X
k=1

ak b(k) .

Demonstratie. a) Vom arata ca maximul din relatia de demonstrat se atinge


si pentru permutarea identica.
Pentru o permutare Sn , vom folosi notatia
S() =

n
X
k=1

ak b(k) .

31

TEMA 2. METODA GREEDY


Fie Sn astfel ncat
S() = max
Sn

n
X
k=1

ak b(k) ,

(2.2.1)

adica este o permutare pentru care se realizeaza maximul.


Presupunem ca 6= e (permutarea identica). Rezulta ca
i, j astfel ncat i < j si (i) > (j).

(2.2.2)

(Obs. Pentru permutarea identica, e Sn , avem e(i) < e(j) , i < j).
|{z} |{z}
i

Din (2.2.2), deoarece sirurile date sunt crescatoare, rezulta ca


b(i) b(j) .

(2.2.3)

Pornind de la , construim permutarea Sn




1
2
...
i
... j
...
n

,
=
(1) (2) . . . (j) . . . (i) . . . (n)
adica
(k) = (k), k cu k 6= i si k 6= j,
(i) = (j),
(j) = (i).
Calculam

S() S( ) =

n
X
k=1

ak b(k)

n
X
k=1

ak b (k) =

= ai b(i) + aj b(j) ai b (i) aj b (j) =


= ai b(i) + aj b(j) ai b(j) aj b(i) =


= ai b(i) b(j) + aj b(j) b(i) =

= b(i) b(j) (ai aj ) 0.
|
{z
} | {z }
0

Rezulta ca S() S( ). Insa, din (2.2.1), nu putem avea inegalitate


stricta. Prin urmare S() = S( ). In plus, (k) = (k), k cu k 6=
i si k 6= j, si (i) < (j).

32

TEMA 2. METODA GREEDY

In continuare, daca 6= e, se reia rationamentul precedent pentru permutarea , obtinandu-se o permutare pentru care
S() = S( ) = S( ).
Dupa un numar finit de pasi, se va obtine permutarea identica e pentru care
vom avea ca
n
n
X
X
ak bk .
ak be(k) =
S() = S(e) =
k=1

k=1

T
inand seama de relatia (2.2.1), obtinem ca
n
X
k=1

ak bk = max
Sn

n
X
k=1

ak b(k) .

b) Se demonstreaza n mod analog.


Observatia 2.2.1. Lema anterioara poate fi reformulata astfel:
Fie sirurile crescatoare de numere reale
a1 a2 . . . an si b1 b2 . . . bn , n 1.
Atunci, pentru orice permutare Sn , avem
n
X
k=1

ak bnk+1

n
X
k=1

ak b(k)

n
X
k=1

ak bk .

Aceasta proprietate este cunoscuta sub numele de inegalitatea rearanjamentelor.


Lema 2.2.1 justifica urmatoarea strategie Greedy pentru rezolvarea problemei:
a) La fiecare pas (pentru obtinerea celor n termeni ai sumei) se vor lua
(pentru mperechere):
cel mai mic dintre termenii sirului (ai )i=1,n neales la pasii precedenti;

cel mai mic dintre termenii sirului (bj )j=1,n neales la pasii precedenti.

b) La fiecare pas (pentru obtinerea celor n termeni ai sumei) se vor lua:


cel mai mic (mare) dintre termenii sirului (ai )i=1,n neales la pasii
precedenti;
cel mai mare (mic) dintre termenii sirului (bj )j=1,n neales la pasii
precedenti.

33

TEMA 2. METODA GREEDY

2.3

Memorarea optimal
a a textelor pe benzi

Se da o banda magnetica suficient de lunga pentru a memora n texte (fisiere)


de lungimi date (n octeti):
L1 , L2 , . . . , Ln .
De fiecare data, pentru a citi un anumit text de pe banda, trebuie citite si
textele aflate naintea lui. Presupunand ca frecventa de citire a celor n texte
este aceeasi, se cere sa se determine ordinea de pozitionare (memorare) a
acestora pe banda, astfel ncat timpul mediu de citire sa fie optim (cat mai
mic).
Modelarea problemei
Timpul de citire a unui text este direct proportional cu lungimea lui.
Prin urmare, putem presupune ca timpul de citire efectiva a unui text
este egal cu lungimea lui.
Fiecarei pozitionari pe banda a celor n texte i corespunde o permutare
p Sn . Asadar, textul k apare al p(k)lea, fiind precedat de textele cu
numerele de ordine p(1), p(2),...,p(k 1).
Citirea textului k necesita timpul Tk =

k
X

Lp(i) , adica la timpul de

i=1

citire efectiva a textului k trebuie adaugati si timpii de citire a textelor


precedente.
Rezulta ca timpul mediu de citire va fi

Tmediu =

n
X
k=1

Tk
=

n X
k
X
k=1 i=1

Lp(i)
.

Deoarece numitorul are valoare constanta n, va trebui sa obtinem o


valoare minima pentru numarator.

34

TEMA 2. METODA GREEDY

Pentru o permutare p Sn , notam (p) :=


(p) =
=

n X
k
X

n X
k
X

Lp(i) . Atunci

k=1 i=1

Lp(i) =

k=1 i=1
n
X
k=1


Lp(1) + Lp(2) + + Lp(k) =




= Lp(1) + Lp(1) + Lp( 2) + + Lp(1) + Lp(2) + + Lp(n) =
= n Lp(1) + (n 1) Lp(2) + + 2 Lp(n1) + 1 Lp(n) =
n
X
(n k + 1) Lp(k) .
=
k=1

Propozitia 2.3.1. Daca L1 L2 . . . Ln , atunci pozitionarea pe banda


corespunzatoare permutarii identice (notata cu e) este optima.
Demonstratie. Avem
(e) =

n
X
k=1

n
X
k=1

(n k + 1) Le(k) =

n
X
k=1

(n k + 1) Lk =

Lk (n k + 1).

Aplicand Lema 2.2.1 b) pentru sirurile L1 L2 . . . Ln si 1, 2, . . . , n,


obtinem
(e) = min ().
Sn

Propozitia justifica urmatoarea strategie Greedy:


La fiecare pas este ales textul de lungime minima dintre cele ramase la
pasii precedenti, care va fi apoi memorat pe banda;
Deci textele vor fi memorate pe banda n ordinea crescatoare a lungimilor lor.

35

TEMA 2. METODA GREEDY

2.4

Problema rucsacului, varianta continu


a

Problema rucsacului (Knapsack) este urmatoarea:


Se considera un rucsac n care se poate ncarca greutatea maxima G,
unde G > 0, si n obiecte O1 , . . . , On , n N . Pentru fiecare obiect Oi ,
i {1, . . . , n}, se cunoaste greutatea sa, gi , unde gi > 0, si castigul obtinut
la transportul sau n ntregime, ci , unde ci > 0.
Se cere sa se determine o modalitate de incarcare a rucsacului cu obiecte
astfel ncat castigul total al obiectelor ncarcate sa fie maxim.
In varianta continu
a (fractionar
a) a problemei, pentru fiecare obiect
Oi poate fi ncarcata orice parte (fractiune) xi [0, 1] din el, castigul obtinut
fiind proportional cu partea ncarcata, adica este egal cu xi ci .
Modelarea problemei
O solutie (solutie posibila ) a problemei este orice vector x = (x1 , . . . , xn )
astfel ncat

xi [0, 1], i {1, . . . , n},


n
P
xi gi G,
i=1

ultima inegalitate exprimand faptul ca greutatea totala ncarcata n


rucsac nu trebuie s depaseasca greutatea maxima.

Castigul (total ) corespunzator solutiei x = (x1 , . . . , xn ) este


f (x) =

n
X

xi ci .

i=1

O solutie optima a problemei este orice solutie x = (x1 , . . . , xn ) astfel


ncat
f (x ) = max{f (x) | x = solutie a problemei}.
Daca suma greutatilor tuturor obiectelor este mai mica decat greutatea
n
P
maxima a rucsacului, adica
gi < G, atunci problema este triviala,
i=1

solutia x = (1, 1, . . . , 1), corespunzatoare ncarcarii integrale a tuturor


celor n obiecte n rucsac, fiind evident singura solutie optima.
Astfel n continuare putem presupune ca
n
X
i=1

gi G.

(2.4.1)

36

TEMA 2. METODA GREEDY


Pentru orice solutie optima x = (x1 , . . . , xn ) avem
n
X

xi gi = G

(2.4.2)

i=1

(adica rucsacul trebuie ncarcat complet). Demonstram aceasta afirn


P
xi gi < G, cum
matie prin reducere la absurd. Intr-adevar, daca
n
P

i=1

i=1

gi > G. rezulta ca exista un indice k {1, . . . , n} a.. xk < 1.

Considerand vectorul x = (x1 , . . . , xn ) definit prin


(
xi , daca i 6= k,
xi =
xi + u, daca i = k,
unde

1
u = min 1 xk ,
gk
avem u > 0, xk 1,
si f (x ) =

n
P

i=1

xi ci =

n
P

i=1
n
P

i=1

xi gi =

n
P

i=1

n
X

xi gi

i=1

xi gi +ugk

n
P

i=1

!)

xi gi +G

n
P

i=1

xi gi = G

xi ci + uck = f (x ) + uck , deci x este o solutie

a problemei si f (x ) > f (x ), ceea ce contrazice optimalitatea solutiei


x .
Prezentam n continuare un algoritm Greedy pentru rezolvarea problemei.
Algoritmul 2.4.1. Vom utiliza urmatoarea strategie Greedy:
Ordonam obiectele descrescator dupa castigul lor unitar:
c1
c2
cn

.
g1
g2
gn

(2.4.3)

Incarcam obiectele n rucsac, n aceasta ordine, cat timp nu se depaseste


greutatea maxima G. Incarcarea obiectelor se face n ntregime, cat
timp este posibil; n acest fel doar ultimul obiect adaugat poate fi
ncarcat partial.
Descrierea n pseudocod a algoritmului are urmatoarea forma.

TEMA 2. METODA GREEDY

37

RUCSAC (G, n, g, c, x, C) :

// g = (g1 , . . . , gn ), c = (c1 , . . . , cn )
// C = c^
as
tigul total
SORTARE(g, c, n);
// se sorteaz
a obiectele descresc
ator
// dup
a c^
as
tigul lor unitar
R G;
// R = greutatea disponibil
a pentru rucsac
C 0;
i 1;
while R > 0 do
// rucsacul nu este plin
if g[i] R then
// obiectul curent ^
ncape ^
n ^
ntregime, deci
// se adaug
a
^n rucsac
x[i] 1;
C C + c[i];
R R g[i];
// actualiz
am greutatea disponibil
a
i i + 1;
// trecem la obiectul urm
ator
else
// obiectul curent nu ^
ncape ^
n ^
ntregime, deci
// se adaug
a exact acea parte din el care
// umple rucsacul
si ^
nc
arcarea se
^ncheie
R
x[i] g[i] ;
C C + x[i]c[i];
R 0;
for j = i + 1, n do x[i] 0;
AFISARE(C, x, n);

// se afi
seaz
a c^
as
tigul total maxim C
//
si solut
ia optim
a x = (x1 , . . . , xn )

Teorema 2.4.1 (de corectitudine a Algoritmului 2.4.1). In contextul Algoritmului 2.4.1, vectorul x = (x1 , . . . , xn ) calculat de algoritm este o
solutie optim
a a problemei rucsacului.
Demonstratie. Evident, vectorul x = (x1 , . . . , xn ) calculat de algoritm verifica
relatiile

xi [0, 1], i {1, . . . , n},


n
P
xi gi = G,
i=1

deci este o solutie a problemei. Ramane sa demonstram optimalitatea acestei


solutii.
Demonstram prin inductie dupa k {0, 1, . . . , n} ca exista o solutie optima x = (x1 , . . . , xn ) a problemei pentru care
xi = xi , i a.. 1 i k.

(2.4.4)

38

TEMA 2. METODA GREEDY

Pentru k = 0 afirmatia este evidenta, luand x orice solutie optima a


problemei.
Presupunem (2.4.4) adevarata pentru k 1, adica exista o solutie optima
x = (x1 , . . . , xn ) a problemei pentru care
xi = xi , i a.. 1 i k 1
si o demonstram pentru k (k {1, 2, . . . , n}).
Cum
k1
k1
n
X
X
X

xi gi + xk gk =
xi gi + xk gk
xi gi = G,
i=1

i=1

i=1

din descrierea algoritmului (alegerea maximala a lui xk ) rezulta ca


xk xk .
Avem doua cazuri.
Cazul 1) xk = xk . Atunci xi = xi , i {1, . . . , k}, deci (2.4.4) este
adevarata pentru k.
Cazul 2) xk > xk . In acest caz avem k < n, deoarece daca, prin reducere
la absurd, am avea k = n, atunci ar rezulta ca
f (x) =

n
X
i=1

xi ci =

n1
X

xi ci

+ xn cn >

n1
X

xi ci + xn cn = f (x ),

i=1

i=1

ceea ce contrazice optimalitatea solutiei x .

Definim vectorul x = (x
1 , . . . , xn ) prin
(
xi , daca 1 i k,
x
i =
xi , daca k + 1 i n,

(2.4.5)

unde [0, 1) este o solutie a ecuatiei


h() = 0, unde h() =

k
X
i=1

xi gi +

n
X

i=k+1

xi gi G.

(2.4.6)

39

TEMA 2. METODA GREEDY


O astfel de solutie exista, deoarece
h(0) =

k
X
i=1

h(1) =

k
X

xi gi G
n
X

xi gi +

i=1

n
X
i=1

n
X
i=1

xi gi G = G G = 0,

xi gi

i=k+1

G =

k1
X

xi gi

+ xk gk +

i=1

n
X

i=k+1

xi gi G

xi gi xk gk + xk gk G = G + gk (xk xk ) G

= gk (xk xk ) > 0,
iar h este o functie continua pe intervalul [0, 1].
Conform (2.4.5) si (2.4.6) rezulta ca x
si
i [0, 1], i {1, . . . , n}
n
X

x
i gi

k
X

xi gi +

i=1

i=1

n
X

xi gi = h( ) + G = 0 + G = G,

i=k+1

deci vectorul x = (x
ie a problemei.
1 , . . . , xn ) este o solut
Avem

f (x ) f (x ) =

k1
X

xi ci

+ xk ck +

i=1

= xk ck +
= xk ck +

n
X

i=k+1
n
X

i=k+1

n
X

i=k+1
n
X

xi ci
xi ci

n
X

xi ci

i=1

xi ci

i=k

xk ck

= ck (xk xk ) (1 )
=

xi ci

n
X

n
X

xi ci

i=k+1

xi ci

i=k+1

n
X
ck
ci
(xk gk xk gk ) (1 )
xi gi .
gk
g
i
i=k+1

(2.4.7)

Conform (2.4.3) rezulta ca


ci
ck
, i {k + 1, . . . , n}.
gi
gk

(2.4.8)

40

TEMA 2. METODA GREEDY


Din (2.4.7) si (2.4.8) obtinem ca
#
"
n
X
c
k
xi gi
(xk gk xk gk ) (1 )
f (x ) f (x )
gk
i=k+1
ck
=

gk

xk gk xk gk
"

ck
xk gk
=
gk
=

ck

gk

ck

=
gk

n
X
i=1

xk gk G +
k
X

k1
X

xi gi

i=1

i=1

i=k+1

xi gi

i=k+1

k1
X

xi gi +

n
X

n
X

xi gi +

i=k+1

xi gi

xi gi +

i=1

n
X

n
X

n
X

!
xi gi

i=k+1

xi gi

i=k+1

xi gi G ,

si conform (2.4.6) rezulta ca


f (x ) f (x )

ck
h( ) = 0,
gk

deci
f (x ) f (x ).

Cum x este solutie optima, rezulta ca si x este solutie optima (si, n plus,
f (x ) = f (x )). Conform (2.4.5) avem
xi = x
i , i {1, . . . , k},
deci relatia (2.4.4) este adevarata pentru k, ceea ce ncheie demonstratia prin
inductie a acestei relatii.
Luand k = n n aceasta relatie rezulta ca exista o solutie optima x =

(x1 , . . . , xn ) pentru care


xi = xi , i {1, . . . , n},
deci x = x si astfel x este o solutie optima a problemei.
Exemplul 2.4.1. Consideram un rucsac n care se poate ncarca o greutatea
mazima G = 40, din n = 10 obiecte ce au greutatile si castigurile date n
urmatorul tabel:
Obiect
Greutate gi
Castig ci

O1
10
27

O2
7
9

O3
10
40

O4
5
20

O5
6
11

O6
10
20

O7
8
50

O8
15
22

O9
3
4

O10
12
33

41

TEMA 2. METODA GREEDY

Ordinea descrescatoare a obiectelor dupa castigul unitar ci /gi este evidentiata


n urmatorul tabel:
Obiect
Castig ci
Greutate gi

O7
50
8

O3
40
10

O4
20
5

O10
33
12

O1
27
10

O6
20
10

O5
11
6

O8
22
15

O9
4
3

O2
9
7

Aplicarea strategiei Greedy (algoritmul de mai sus) conduce la solutia optima


x = (1, 1, 1, 1, 5/10, 0, 0, 0, 0, 0),
adica umplem rucsacul ncarcand, n ordine, obiectele:
O7 , dupa care greutatea disponibila devine R = 40 8 = 32,
O3 , dupa care R = 32 10 = 22,
O4 , dupa care R = 22 5 = 17,
O10 dupa care R = 17 12 = 5,
5/10 din O1 , dupa care R = 5 5 = 0.
Castigul (total) obtinut este
f (x) = 50 + 40 + 20 + 33 +

5
27 = 156,5.
10

Observatia 2.4.1. Algoritmul 2.4.1 are complexitatea O (n ln n), deoarece


este necesara sortarea obiectelor descrescator dupa castigul unitar iar blocul
while se executa de cel mult n ori (cate o data pentru fiecare obiect) si
necesita de fiecare data o comparatie si 3 operatii aritmetice.
Observatia 2.4.2. In varianta discret
a a problemei rucsacului, fiecare
obiect Oi poate fi ncarcat doar n ntregime. In aceasta varianta, solutia
produs
a de strategia Greedy (de mai sus) nu este neap
arat optim
a!
De eemplu, pentru datele din exemplul anterior, aplicarea strategiei Greedy
conduce la solutia
x = (1, 1, 1, 1, 0, 0, 0, 0, 1, 0),
adica ncarcam n rucsac, n ordine, obiectele:
O7 , dupa care greutatea disponibila devine R = 40 8 = 32,
O3 , dupa care R = 32 10 = 22,
O4 , dupa care R = 22 5 = 17,

TEMA 2. METODA GREEDY

42

O10 dupa care R = 17 12 = 5,


O9 , dupa care R = 5 3 = 2 si nu mai exista niciun obiect care sa mai
ncapa n rucsac, deci ncarcarea se ncheie.
Castigul (total) obtinut este
f (x) = 50 + 40 + 20 + 33 + 4 = 147.
Solutia obtinuta nu este optima, o solutie mai buna fiind
x = (1, 1, 1, 0, 1, 0, 1, 0, 0, 0),
corespunzatoare ncarcarii obiectelor O7 , O3 , O4 , O1 si O5 , avand greutatea
totala 8 + 10 + 5 + 10 + 6 = 39 (deci rucsacul nu este plin) si castigul (total)
f (x ) = 50 + 40 + 20 + 27 + 11 = 148.

2.5

Problema planific
arii spectacolelor

Problema planific
arii spectacolelor este urmatoarea:
Se considera n spectacole S1 , . . . , Sn , n N . Pentru fiecare spectacol Si ,
i {1, . . . , n}, se cunoaste intervalul orar Ii = [ai , bi ] de desfasurare, unde
ai < bi .
O persoana doreste sa vizioneze cat mai multe dintre aceste n spectacole.
Fiecare spectacol trebuie vizionat integral, nu pot fi vizionate simultan mai
multe spectacole, iar timpii necesari deplasarii de la un spectacol la altul sunt
nesemnificativi (egali cu zero).
Se cere sa se selecteze un numar cat mai mare de spectacole ce pot fi
vizionate de o singura persoana, cu respectarea cerintelor de mai sus.
Modelarea problemei
O solutie (solutie posibila ) a problemei este orice submultime P
{I1 , . . . , In } astfel ncat
Ii Ij = , Ii , Ij P, i 6= j
(adica orice submultime de intervale disjuncte doua cte doua).
O solutie optima a problemei este orice solutie P {I1 , . . . , In } astfel
ncat
card (P ) = max{card (P ) | P = solutie a problemei}.

43

TEMA 2. METODA GREEDY

Prezentam n continuare doi algoritmi Greedy pentru rezolvarea problemei.


Algoritmul 2.5.1. Vom utiliza urmatoarea strategie Greedy:
Ordonam spectacolele crescator dupa timpul lor de ncheiere:
b1 b2 bn .

(2.5.1)

Parcurgem spectacolele, n aceasta ordine, si:


selectam primul spectacol;
de fiecare data, spectacolul curent, Si , se selecteaza doar daca
nu se suprapune cu niciunul dintre spectacolele selectate anterior,
adica daca timpul sau de ncepere este mai mare decat timpul de
ncheiere al ultimului spectacol Sj selectat:
ai > bj .
Pentru memorarea solutiei utilizam un vector caracteristic c = (c1 , . . . , cn ),
cu semnificatia
(
1, daca intervalul Ii a fost selectat,
ci =
0, n caz contrar.
Descrierea n pseudocod a algoritmului are urmatoarea forma.
SPECTACOLE1 (a, b, n, c, m) : // a = (a1 , . . . , an ), b = (b1 , . . . , bn )
// c = (c1 , . . . , cn ), m = num
arul de spectacole selectate
SORTARE(a, b, n);
// se sorteaz
a spectacolele cresc
ator
// dup
a timpul lor de
^ncheiere bi
m 0;
// init
ializ
ari
for i = 1, n do c[i] 0;
t a[1] 1;
// t = timpul de ^
ncheiere al ultimului
// spectacol selectat
// parcurgem spectacolele
for i = 1, n do
if a[i] > t then
c[i] 1; // select
am intervalul (spectacolul) curent
m m + 1;
t b[i];
// actualiz
am t
AFISARE(m, c, n);
// se afi
seaz
a num
arul s
i
// submult
imea intervalelor (spectacolelor) selectate

44

TEMA 2. METODA GREEDY


Functia de afisare este
AFISARE (m, c, n) :
afiseaz
a m;
for i = 1, n do
if c[i] = 1 then afiseaz
a [a[i], b[i]];

Teorema 2.5.1 (de corectitudine a Algoritmului 2.5.1). In contextul


Algoritmului 2.5.1, submultimea intervalelor (spectacolelor) selectate de algoritm este o solutie optima a problemei planificarii spectacolelor.

Demonstratie. Fie P = {I1 , . . . , Im


} submultimea de intervale calculata de
algoritm, unde

I1 = [a1 , b1 ], I2 = [a2 , b2 ], . . . , Im
= [am , bm ]

sunt intervalele selectate, n aceasta ordine, de algoritm.


Evident, m 1 (dupa sortare, primul interval este ntotdeauna selectat).
Din descrierea algoritmului (alegerea intervalului curent Ii ) rezulta ca
ai > bi1 , i {2, . . . , m},
deci
a1 < b1 < a2 < b2 < < am < bm .
Rezulta ca
Ii Ij = , i, j {1, . . . , m}, i 6= j,

deci submultimea P = {I1 , . . . , Im


} a intervalelor selectate de algoritm este
o solutie a problemei. Ramane sa demonstram optimalitatea acestei solutii.
Demonstram prin inductie dupa k {0, 1, . . . , m} ca exista o solutie
optima P = {I1 , . . . , Ip } a problemei, p N , cu

I1 = [a1 , b1 ], I2 = [a2 , b2 ], . . . , Ip = [ap , bp ],

b1 < b2 < < bp ,

(2.5.2)

pentru care
Ii = Ii , i a.. 1 i k.

(2.5.3)

Ii = Ii , i a.. 1 i k 1.

(2.5.4)

Pentru k = 0 afirmatia este evidenta, luand P orice solutie optima a


problemei (si sortand intervalele componente Ii crescator dupa extremitatile
bi ).
Presupunem (2.5.3) adevarata pentru k 1, adica exista o solutie optima

P = {I1 , . . . , Ip } a problemei, ce verifica (2.5.2), pentru care

45

TEMA 2. METODA GREEDY


si o demonstram pentru k (k {1, 2, . . . , m}).
Din optimalitatea solutiei P = {I1 , . . . , Ip } rezulta ca p m, deci
p m k.

Avem doua cazuri.


Cazul 1) Ik = Ik . Atunci Ii = Ii , i {1, . . . , k}, deci (2.5.3) este
adevarata pentru k.
Cazul 2) Ik 6= Ik , adica [ak , bk ] 6= [ak , bk ]. In acest caz, pentru k 2

avem ak > bk1 (deoarece Ik Ik1


= si bk > bk1 ) si bk1 = bk1 (deoarece

Ik1
= Ik1
), deci
ak > bk1 .
Atunci, din descrierea algoritmului, deoarece Ik = [ak , bk ] este primul interval

selectat dupa intervalul Ik1


= [ak1 , bk1 ], rezulta ca
bk bk .

(2.5.5)

Din descrierea algoritmului, aceasta inegalitate este valabila si pentru k = 1,


deoarece I1 = [a1 , b1 ] este primul interval selectat.
Definim submultimea de intervale P = {I1 , . . . , Ip } prin
(
Ii , daca i 6= k,

(2.5.6)
Ii = [a
,
b
]
=
i
i
Ii , daca i = k.
Deoarece P = {I1 , . . . , Ip } este solutie a problemei si verifica (2.5.2), rezulta
ca
a1 < b1 < a2 < b2 < < ak1 < bk1 < ak < bk <
< ak+1 < bk+1 < < ap < bp .

(2.5.7)

Pentru k 2 avem ak > bk1 (din descrierea algoritmului) si bk1 = bk1

(deoarece Ik1
= Ik1
), deci
ak > bk1 .
(2.5.8)
Din (2.5.7), (2.5.8) si (2.5.5) rezulta ca
a1 < b1 < a2 < b2 < < ak1 < bk1 < ak < bk <
< ak+1 < bk+1 < < ap < bp
(inegalitate valabila si pentru k = 1), deci submultimea P = {I1 , . . . , Ip },
definita de (2.5.6), este o solutie a problemei si

b
1 < b2 < < bp .

46

TEMA 2. METODA GREEDY


Cum
card (P ) = p = card (P )
si P este solutie optima, rezulta ca si P este solutie optima.
Conform (2.5.6) si (2.5.4) avem
Ii = Ii , i {1, . . . , k},

deci relatia (2.5.3) este adevarata pentru k, ceea ce ncheie demonstratia prin
inductie a acestei relatii.
Luand k = m n aceasta relatie rezulta ca exista o solutie optima P =
{I1 , . . . , Ip } pentru care
Ii = Ii , i {1, . . . , m}.
Demonstram ca p = m prin reducere la absurd. Intr-adevar, daca p > m

atunci ar exista intervalul Im+1


= [am+1 , bm+1 ] astfel ncat
am+1 > bm = bm
ceea ce ar contrazice faptul ca algoritmul se ncheie cu selectarea intervalului

Im
= [am , bm ].
Astfel p = m, deci

P = {I1 , . . . , Im
} = {I1 , . . . , Ip } = P

si astfel submultimea P este o solutie optima a problemei.


Exemplul 2.5.1. Consideram n = 14 spectacole ce au timpii de ncepere si
de ncheiere dati n urmatorul tabel (n ordinea crescatoare a timpilor de
ncepere ai ):
Spectacol
S1
Timp de ncepere ai 8:00
Timp de ncheiere bi 9:10
Spectacol
S8
Timp de ncepere ai 10:45
Timp de ncheiere bi 12:00

S2
8:10
9:00
S9
11:00
12:30

S3
S4
S5
S6
S7
8:15 8:50 9:10 9:20 9:20
9:00 10:20 10:40 10:30 11:00
S10
S11
S12
S13
S14
12:00 12:10 12:30 13:00 13:40
13:30 14:00 13:50 14:30 15:00

Ordonarea spectacolele crescator dupa timpul lor de ncheiere bi este


evidentiata n urmatorul tabel:

47

TEMA 2. METODA GREEDY


Spectacol
S2
Timp de ncepere ai 8:10
Timp de ncheiere bi 9:00
Spectacol
S8
Timp de ncepere ai 10:45
Timp de ncheiere bi 12:00

S3
8:15
9:00
S9
11:00
12:30

S1
S4
S6
S5
S7
8:00 8:50 9:20 9:10 9:20
9:10 10:20 10:30 10:40 11:00
S10
S12
S11
S13
S14
12:00 12:30 12:10 13:00 13:40
13:30 13:50 14:00 14:30 15:00

Aplicarea strategiei Greedy din algoritmul de mai sus conduce la solutia


optima data de selectarea (vizionarea), n ordine, a spectacolelor:
S2 (primul, n ordinea impusa),
S6 (primul situat dupa S2 si care are timpul de ncepere mai mare decat
timpul de ncheiere al lui S2 ),
S8 (primul situat dupa S6 si care are timpul de ncepere mai mare decat
timpul de ncheiere al lui S6 ),
S12 (primul situat dupa S8 si care are timpul de ncepere mai mare
decat timpul de ncheiere al lui S8 ), dupa care nu mai urmeaza niciun
spectacol care sa nceapa dupa ncheierea lui S12 , deci selectarea se
termina.
Numarul maxim de spectacole ce pot fi vizionate este deci egal cu 4.
Observatia 2.5.1. Algoritmul 2.5.1 are complexitatea O (n ln n), deoarece este
necesara sortarea spectacolelor crescator dupa timpul lor de ncheiere, iar
blocul for prin care se parcurg spectacolele se executa de n ori (cate o
data pentru fiecare spectacol) si necesita de fiecare data o comparatie, cel
mult o adunare si cel mult 3 operatii de atribuire.
Algoritmul 2.5.2. O alta rezolvare a problemei spectacolelor se obtine prin
utilizarea urmatoarei strategie Greedy, similara cu cea de mai sus.
Ordonam spectacolele descrescator dupa timpul lor de ncepere:
a1 a2 an .
Parcurgem spectacolele, n aceasta ordine, si:
selectam primul spectacol;
de fiecare data, spectacolul curent, Si , se selecteaza doar daca
nu se suprapune cu niciunul dintre spectacolele selectate anterior,
adica daca timpul sau de ncheiere este mai mic decat timpul de
ncepere al ultimului spectacol Sj selectat:
bi < aj .

TEMA 2. METODA GREEDY

48

Pentru memorarea solutiei se utilizeaza din nou un vector caracteristic


c = (c1 , . . . , cn ), cu aceeasi semnificatie ca n algoritmul de mai sus.
Descrierea n pseudocod a noului algoritm are urmatoarea forma.
SPECTACOLE2 (a, b, n, c, m) : // a = (a1 , . . . , an ), b = (b1 , . . . , bn )
// c = (c1 , . . . , cn ), m = num
arul de spectacole selectate
SORTARE(a, b, n);
// se sorteaz
a spectacolele cresc
ator
// dup
a timpul lor de
^ncepere ai
m 0;
// init
ializ
ari
for i = 1, n do c[i] 0;
t b[n] + 1;
// t = timpul de ^
ncepere al ultimului
// spectacol selectat
for i = n, 1, 1 do
// parcurgem spectacolele
^n ordinea
// descresc
atoare a timpilor de
^ncepere
if b[i] < t then
c[i] 1; // select
am intervalul (spectacolul) curent
m m + 1;
t a[i];
// actualiz
am t
AFISARE(m, c, n);
// se afi
seaz
a num
arul s
i
// submult
imea intervalelor (spectacolelor) selectate
Functia de afisare este aceeasi ca n Algoritmul 2.5.1.
Observatia 2.5.2. Demonstratia corectitudinii si evaluarea complexitatii Algoritmului 2.5.2 sunt analoage cu cele ale Algoritmul 2.5.1.
Exemplul 2.5.2. Pentru spectacolele din Exemplul 2.5.1, ordonate crescator
dupa timpii lor de ncepere ai n primul tabel, aplicarea strategiei Greedy
din Algoritmul 2.5.2 conduce la solutia optima data de urmatoarea selectare
(vizionare n ordine inversa) a spectacolelor:
S14 (ultimul, n ordinea crescatoare a timpilor de ncepere),
S10 (ultimul situat nainte de S14 si care are timpul de ncheiere mai
mic decat timpul de ncepere al lui S14 ),
S7 (ultimul situat nainte de S10 si care are timpul de ncheiere mai mic
decat timpul de ncepere al lui S10 ),
S3 (ultimul situat nainte de S7 si care are timpul de ncheiere mai mic
decat timpul de ncepere al lui S7 ), nainte de care nu mai avem niciun
spectacol care sa se ncheie nainte de nceperea lui S3 , deci selectarea
se termina.
Numarul maxim de spectacole ce pot fi vizionate este egal, din nou, cu 4.

49

TEMA 2. METODA GREEDY

2.6

Arbori partiali de cost minim

Definitia 2.6.1. Fie (G, c) un graf ponderat, G = (V, E).


a) Daca H = (U, F ) este un subgraf al lui G, atunci costul (ponderea)
lui H este
X
c(H) =
c(e)
eF

(adica suma costurilor muchiilor sau arcelor sale).

b) Un arbore partial T = (V, F ) al lui G cu proprietatea ca


c(T ) = min{c(T )|T = arbore partial al lui G}
se numeste arbore partial de cost minim (APM) al grafului ponderat (G, c).
Observatia 2.6.1. Un graf ponderat are arbori partiali de cost minim daca si
numai daca este conex.
Problema determinarii arborilor partiali de cost minim are numeroase
aplicatii practice. Prezentam n continuare doi algoritmi fundamentali pentru
rezolvarea acestei probleme.
Algoritmul 2.6.1 (Kruskal). Fie (G, c) un graf ponderat conex cu G =
(V, E), V = {v1 , . . . , vn }. Algoritmul are n 1 pasi.
La pasul i, i = 1, n 1, dintre muchiile neselectate la pasii anteriori
se selecteaza o muchie ei E de cost minim cu proprietatea ca nu
formeaza cicluri cu muchiile {e1 , . . . , ei1 } selectate la pasii anteriori.
Algoritmul 2.6.2 (Prim). Fie (G, c) un graf ponderat conex cu G = (V, E),
V = {v1 , . . . , vn }. Algoritmul are n pasi.
La pasul 0 se selecteaza un nod arbitrar x0 V .
La pasul i, i = 1, n 1, se selecteaza o muchie ei = [xj , xi ] E de cost
minim cu proprietatea ca are ca extremitati un nod xj V selectat la
un pas anterior si celalalt nod xi V neselectat la pasii anteriori; se
selecteaza si nodul xi .
Teorema 2.6.1 (de corectitudine a algoritmilor Kruskal si Prim). In
contextul Algoritmilor Kruskal sau Prim, fie F = {e1 , . . . , en1 } multimea
muchiilor selectate. Atunci T = (V, F ) este un arbore partial de cost minim
al grafului ponderat (G, c).

TEMA 2. METODA GREEDY

50

Demonstratie. Vom prezenta o demonstratie comuna a corectitudinii celor


doi algoritmi. Fie T0 = (V, ) si Ti = (V, {e1 , . . . , ei }), i {1, 2, . . . , n 1},
unde e1 , e2 , . . . , en1 sunt muchiile selectate, n aceasta ordine, de Algoritmul
Kruskal sau de Algoritmul Prim.
Graful G fiind conex, selectarea muchiei ei este posibila la fiecare pas i,
iar Ti este o padure partiala a lui G (afirmatie evidenta pentru Algoritmul
Kruskal, iar pentru Algoritmul Prim este o consecinta a faptului ca nodurile
neselectate la pasul i sunt izolate n Ti ).
Demonstram prin inductie dupa i {0, 1, . . . , n 1} ca exista un APM
T = (V, F ) astfel ncat
Ti T (adica {e1 , . . . , ei } F ).

(2.6.1)

Pentru i = 0 afirmatia este evidenta, luand T orice APM (exista, deoarece


G este conex).
Presupunem (2.6.1) adevarata pentru i 1, adica exista T = (V, F )
APM cu Ti1 T si o demonstram pentru i (i {1, 2, . . . , n 1}).
Fie ei = [xj , xi ] muchia selectata de Algoritmul Kruskal sau de Algoritmul
Prim la pasul i. In cazul Algoritmului Prim, xj este nodul selectat la un pas
anterior (j i 1). Avem doua cazuri.
Cazul 1) ei F . Atunci {e1 , . . . , ei } F , deci Ti T .
Cazul 2) ei 6 F . Conform Teoremei numarului ciclomatic, graful H =
T + ei = (V, F {ei }) obtinut din T prin adaugarea muchiei ei contine un
ciclu elementar unic
Ci = [xj , w0 , . . . , wk , xi , xj ]
avand ultima muchie chiar muchia ei . Cum Ti = Ti1 + ei este o padure,
rezulta ca xj si xi sunt n componente conexe diferite ale lui Ti1 (n caz
contrar Ti ar contine un ciclu de forma [xj , y0, . . . , yr , xi , xj ] avand ultima
muchie ei ). Rezulta ca lantul elementar
i = [xj , w0 , . . . , wk , xi ]
(obtinut din ciclul Ci prin eliminarea muchiei ei ) contine o muchie ei = [x , y ]
astfel ncat x este n aceeasi componenta conexa cu xj n padurea Ti1 , iar y
nu este n aceasta componenta conexa. Evident, rezulta ca ei nu este muchie
a lui Ti1 , adica ei 6 {e1 , . . . , ei1 }, iar graful Ti = Ti1 + ei nu contine
cicluri. De asemenea, ei 6= ei , deci ei F .
Pe de o parte, din descrierea Algoritmului Kruskal deducem ca
c(ei ) c(ei )

TEMA 2. METODA GREEDY

51

(deoarece muchia ei nu formeaza cicluri cu {e1 , . . . , ei1 }, deci ei fiind muchia


selectata la pasul i verifica aceasta inegalitate).
Pe de alta parte, din descrierea Algoritmului Prim deducem ca la pasul
i nodul x era deja selectat la un pas anterior (fiind n aceeasi componenta
conexa cu xj n Ti1 ), iar nodul y nu era selectat la un pas anterior (nefiind
n acea componenta conexa), deci din nou avem
c(ei ) c(ei )
(ei fiind muchia selectata la pasul i verifica aceasta inegalitate).
Continuam demonstratia comuna pentru cei doi algoritmi. Fie
T = (T + ei ) ei
graful partial al lui G obtinut din T prin adaugarea muchiei ei si eliminarea
muchiei ei , adica T = (V, F ), unde F = F {ei } \ {ei }.
Evident, T este conex (T este conex iar ntre nodurile x si y dupa eliminarea muchiei ei ramane lantul obtinut din ciclul Ci prin eliminarea acestei
muchii) si are n1 muchii (deoarece T are n1 muchii). Conform Teoremei
numarului ciclomatic rezulta ca T este un arbore partial al grafului G.
Deoarece c(ei ) c(ei ) obtinem
c(T ) c(T )
si cum T este un APM rezulta ca si T este un APM (si, n plus, c(T ) =
c(T )). Cum Ti T , demonstratia prin inductie a relatiei (2.6.1) este
completa.
Luand i = n 1 n aceasta relatie obtinem ca T T , unde T = Tn1 =
(V, F ), F = {e1 , . . . , en1 } (multimea muchiilor selectate de algoritm) iar T
este un APM. Dar T si T au fiecare cate n 1 muchii, deci T = T si astfel
T este un APM al grafului dat.
Exemplul 2.6.1. Fie graful ponderat (G, c) reprezentat n Figura 2.6.1, unde
costul fiecarei muchii este scris langa segmentul corespunzator acesteia.

52

TEMA 2. METODA GREEDY

30

50

100

3
20

60

70

90

70

120

5
10
7

100

80

40
9

30

15

110

130

10

Figura 2.6.1:
Aplicarea Algoritmului Kruskal este evidentiata n urmatorul tabel:
Pas
1
2
3
4
5
6
7
8
9

Muchia selectata
[5, 8]
[3, 6]
[1, 2]
[8, 9]
[2, 3]
[2, 5]
[4, 6]
[7, 8]
[4, 10]

Costul ei
10
20
30
30
50
60
90
100
120

Arborele partial de cost minim obtinut este reprezentat n Figura 2.6.2. Costul acestui APM este de 510.
1

30

50

4
20

60

90
120

5
10
7

100

30

Figura 2.6.2:

10

53

TEMA 2. METODA GREEDY

Aplicarea Algoritmului Prim pentru acelasi graf este evidentiata n urmatorul tabel:
Pas Muchia selectata Costul ei Nodul selectat
0
1
1
[1, 2]
30
2
2
[2, 3]
50
3
3
[3, 6]
20
6
4
[2, 5]
60
5
5
[5, 8]
10
8
6
[8, 9]
30
9
7
[6, 4]
90
4
8
[8, 7]
100
7
9
[4, 10]
120
10
Arborele partial de cost minim obtinut este deci acelasi cu cel obtinut
prin aplicarea Algoritmului Kruskal.
Observatia 2.6.2. Algoritmii Kruskal si Prim sunt specifici metodei de
programare Greedy. Algoritmul Kruskal selecteaza muchii, n ordinea
crescatoare a costurilor, subgrafurile induse pe parcurs de acestea nefiind
neaparat conexe. Algoritmul Prim selecteaza muchii si noduri, nu neaparat
n ordinea crescatoare a costurilor muchiilor, iar subgrafurile induse pe parcurs de muchiile selectate sunt conexe.
In implementari optime, se poate arata ca Algoritmul Kruskal are complexitatea O (m ln n) (fiind necesara sortarea muchiilor dupa cost), iar Algoritmul Prim are complexitatea O (n2 ) n cazul memorarii grafului prin matricea de adiacenta (o astfel de implementare va fi prezentata n continuare),
unde n si m reprezinta numerele de noduri, respectiv de muchii ale grafului
dat. Graful fiind conex, m n 1.
Pentru grafuri simple, m n(n1)
. Folosind si inegalitatea ln n n 1,
2
obtinem ca Algoritmul Kruskal este mai eficient pentru grafuri sarace n
muchii, iar Algoritmul Prim este mai eficient pentru grafuri bogate n
muchii.
Observatia 2.6.3. Pentru implementarea Algoritmului Kruskal, memoram
graful ponderat conex (G, c), unde G = (V, E), V = {1, . . . , n}, E =
{e1 , . . . , em }, ntr-o matrice cu 3 linii si m coloane P = (pik ) i = 1, 3 avand
k = 1, m

semnificatia:
daca ek = [xk , yk ] E, atunci p1k = xk , p2k = yk si p3k = c(ek ).

TEMA 2. METODA GREEDY

54

Utilizam un vector S cu semnificatia



1, daca ek a fost selectata,
S[k] =
0, n caz contrar,
k {1, . . . , m} si un vector CC cu semnificatia
CC[i] = numarul componentei conexe n care se afla nodul i n graful
indus de muchiile selectate, i {1, . . . , n}.
Astfel o muchie [x, y] nu formeaza cicluri cu muchiile selectate daca si numai
daca
CC[x] 6= CC[y].
Descrierea n pseudocod a algoritmului are urmatoarea forma.
KRUSKAL :
SORTARE(P );
// se sorteaz
a coloanele matricei P
// cresc
ator dup
a costurile muchiilor
for i = 1, m do S[i] 0;
for i = 1, n do CC[i] i;
cost 0;
// costul APM
poz 0;
// c
autarea urm
atoarei muchii ek ce va fi
// selectat
a ^
ncepe de pe pozit
ia poz + 1
for l = 1, n 1 do
// pasul l
k poz;
repeat
k k + 1; x p1k ; y p2k ; c p3k ;
while (CC[x] = CC[y]);
S[k] 1;
// select
am ek = [x, y]
cost cost + c; poz k;
aux CC[y]; // actualiz
am vectorul CC prin unificarea
// componentelor conexe ale lui x s
i y
for i = 1, n do
if (CC[i] = aux) then CC[i] CC[x];

Observatia 2.6.4. Pentru implementarea Algoritmului Prim, memoram graful


ponderat conex si simplu (G, c), unde G = (V, E), V = {1, . . . , n}, E =
{e1 , . . . , em }, cu ajutorul unei matrice C = (cij )i,j=1,n a costurilor (directe)
avand semnificatia

c([i, j]), daca [i, j] E,


0, daca i = j,
cij =
(2.6.2)

, n rest,

TEMA 2. METODA GREEDY

55

i, j {1, . . . , n}. Pentru grafuri neorientate, matricea C este simetrica. In


cazul grafurilor nesimple putem lua
cij = min{c(e)|e = [i, j] E}.
Utilizam un vector S cu semnificatia

1, daca nodul i a fost selectat,
S[i] =
0, n caz contrar
si doi vectori t si T AT A avand semnificatia
t[i] = costul minim al unei muchii [i, j] de la nodul i la un nod selectat j,
T AT A[i] = nodul j ce atinge minimul n t[i], i {1, . . . , n}.
Descrierea n pseudocod a algoritmului are urmatoarea forma.
PRIM :
S[1] 1;
// select
am nodul 1
cost 0;
// costul APM
for i = 2, n do
// init
ializ
ari
S[i] 0; t[i] ci1 ; T AT A[i] 1;
for l = 1, n 1 do
// c
aut
am nodul y
si muchia [x, y]
// ce vor fi selectate la pasul l
min ;
for i = 2, n do
if (S[i] = 0) and (t[i] < min) then
min t[i]; y i;
S[y] 1;
// select
am nodul y
x T AT A[y];
//
si muchia [x, y]
cost cost + cxy ;
for i = 2, n do
// actualiz
am vectorii t s
i T AT A
if (S[i] = 0) and (t[i] > ciy ) then
t[i] ciy ; T AT A[i] y;

2.7

Distante si drumuri minime. Algoritmul


lui Dijkstra

Problema determinarii distantelor si drumurilor minime ntre nodurile unui


graf ponderat apare n numeroase aplicatii practice. In continuare vom
prezenta un algoritm clasic pentru rezolvarea acestei probleme.

56

TEMA 2. METODA GREEDY

Definitia 2.7.1. Fie (G, c) un graf ponderat, unde G = (V, E), V = {v1 , . . . ,
vn } iar c : E R+ .
a) Daca = (x0 , e1 , x1 , . . . , xk1 , ek , xk ) este un drum al grafului G, unde
x0 , x1 , . . . , xk V , e1 , . . . , ek E, k N, atunci costul (ponderea)
lui este

0, daca k = 0,
k
P
c() =
c(ei ), daca k 1

i=1

(adica suma costurilor arcelor sau muchiilor sale).

b) Fie x, y V . Un drum = (x, . . . , y) n graful G cu proprietatea ca


c( ) = min{c()| este drum de la x la y n G}
se numeste drum minim (drum de cost minim, drum de pondere minim
a) de la x la y n graful ponderat (G, c). Costul c( )
al acestui drum minim se numeste distanta minim
a de la x la y n
graful (G, c).
Observatia 2.7.1. Eliminand eventualele circuite C1 , . . . , Cp dintr-un drum
de la nodul x la nodul y obtinem un drum elementar de la x la y cu
p
P
c(Ck ) c().
proprietatea ca c( ) = c()
k=1

Daca drumul este minim atunci si drumul elementar este minim si


c(e) = 0 pentru orice muchie sau arc e al circuitelor C1 , . . . , Cp . Deci existenta
unui drum minim de la x la y implica existenta unui drum minim elementar
de la x la y. Astfel distanta minima de la x la y poate fi considerata ca fiind
costul minim al unui drum elementar de la x la y. Mai mult, daca functia
cost c este strict pozitiva, atunci orice drum minim este elementar.
Observatia 2.7.2. Multimea drumurilor elementare fiind evident finita, avem
echivalenta: exista drumuri minime de la x la y daca si numai daca exista
drumuri de la x la y.
Observatia 2.7.3. Distanta minima de la un nod x la el nsusi este egala cu
zero, drumul minim elementar de la x la x fiind drumul de lungime zero,
= (x).
Observatia 2.7.4. Daca = (x0 , x1 , . . . , xk ) este un drum minim de la x0 la
xk , atunci orice subdrum = (xi , xi+1 , . . . , xj ) (0 i j k) al sau este
un drum minim de la xi la xj (principiul optimalit
atii al lui Bellman).
Afirmatia poate fi justificata usor prin reducere la absurd.

57

TEMA 2. METODA GREEDY


Exemplul 2.7.1. Fie graful ponderat (G, c) reprezentat n Figura 2.7.1.

15

10

10

2
Figura 2.7.1:
Drumurile elementare de la nodul 1 la nodul 5 sunt 1 = (1, 3, 5), avand
costul c(1 ) = 10 + 5 = 15, 2 = (1, 4, 5), avand costul c(2 ) = 5 + 5 = 10,
deci 2 este un drum minim de la 1 la 5. Astfel distanta minima de la nodul
1 la nodul 5 este c(2 ) = 10.
Definitia 2.7.2. Fie (G, c) un graf ponderat, unde G = (V, E), V = {v1 , . . . ,
vn }, c : E R+ .
a) Matricea distantelor (costurilor) directe asociata grafului (G, c)
este matricea C = (cij )i,j=1,n definita prin

0, daca i = j,
min{c(e)|e = (vi , vj ) E}, daca i 6= j si (vi , vj ) E,
cij =

, daca i 6= j si 6 (vi , vj ) E
(pentru grafuri neorientate (vi , vj ) desemnand de fapt muchia [vi , vj ]).

b) Matricea distantelor (costurilor) minime asociata grafului (G, c)


este matricea C = (cij )i,j=1,n definita prin

c( ), = drum minim de la vi la vj ,
daca = (vi , . . . , vj ) drum n G,
cij =

, n caz contrar.

Observatia 2.7.5. Evident, pentru orice graf neorientat atat matricea distantelor directe cat si matricea distantelor minime sunt matrice simetrice.

58

TEMA 2. METODA GREEDY

Observatia 2.7.6. Conform Observatiei 2.7.1, putem sa nlocuim termenul de


drum cu cel de drum elementar n definitia anterioara.
Conform Observatiei 2.7.2, punctul b) din definitia anterioara este o extindere a definitiei distantei minime de la punctul b) al Definitiei 2.7.1.
Conform Observatiei 2.7.3, cii = 0 i {1, . . . , n}.
Exemplul 2.7.2. Matricele distantelor directe, respectiv minime asociate grafului din Exemplul 2.7.1 sunt

0 15 10 5 10
0 15 10 5
0
0

, C = 10 5 0 15 5 .

5
0

5
C=

10 10 20 0 5
10 0 5
5 5 15 10 0
5 5 0

Vom expune n continuare un algoritm pentru determinarea distantelor


minime si a drumurilor minime de la un nod fixat, numit si nod sursa, la
toate nodurile grafului ponderat dat.
Algoritmul 2.7.1 (Dijkstra). Fie (G, c) un graf ponderat, G = (V, E), V =
{v1 , v2 , . . . , vn }, c : E R+ . Fie C = (cij )i,j=1,n matricea distantelor directe asociata grafului (G, c) si fie vs V un nod arbitrar fixat, numit nod
surs
a. Distantele minime de la nodul vs la nodurile grafului sunt calculate
si memorate ntr-un vector t = (t1 , . . . , tn ) astfel:
La pasul 1 se selecteaza nodul sursa vs si se ia ts = 0;
La pasul k, 2 k n, se cunosc nodurile vi1 , . . . , vik1 selectate la
pasii anteriori si distantele corespondente ti1 , . . . , tik1 .
a) Daca nu mai exista nici-o muchie sau arc de la un nod selectat
vj {vi1 , . . . , vik1 } la un nod neselectat vi V \{vi1 , . . . , vik1 }, atunci
se ia ti = pentru orice nod neselectat vi V \ {vi1 , . . . , vik1 } si
algoritmul se ncheie.
b) In caz contrar se selecteaza un nod vik V \ {vi1 , . . . , vik1 } cu
proprietatea ca exista un nod selectat vjk {vi1 , . . . , vik1 } astfel ncat

tjk + cjk ik = min{tj + cji |vj {vi1 , . . . , vik1 }, vi V \ {vi1 , . . . , vik1 }}.
(2.7.1)
Se ia
tik = tjk + cjk ik
si se trece la pasul k + 1.

(2.7.2)

59

TEMA 2. METODA GREEDY


Observatia 2.7.7. Evident, algoritmul executa cel mult n pasi.

Teorema 2.7.1 (de corectitudine a Algoritmului Dijkstra). In contextul Algoritmului Dijkstra, avem
ti = csi , i {1, . . . , n}
(adica distanta ti calculata de algoritm este chiar distanta minima de la vs
la vi ).
Demonstratie. Vom demonstra prin inductie dupa k ca nodul vik selectat la
pasul k si distanta corespondenta tik calculata la acel pas verifica egalitatea
din enunt, adica
tik = csik ,
si, n plus, tik < .
Pentru k = 1 afirmatia este evidenta deoarece
vi1 = vs , ti1 = 0 = css .
Presupunem adevarata afirmatia pentru orice pas mai mic decat k si o
demonstram pentru pasul k. Fie vjk {vi1 , . . . , vik1 } un nod ce verifica egalitatea (2.7.1). Din descrierea algoritmului si din ipoteza de inductie (nodul
vjk fiind selectat la un pas anterior), rezulta ca tjk = csjk < si cjk ik < ,
deci tik < (conform (2.7.2)).
Daca (vs , . . . , vjk ) este un drum minim de la vs la vjk (exista, deoarece

csjk < ), atunci = (vs , . . . , vjk , vik ) este un drum de la vs la vik , avand
costul c() = csjk + cjk ik = tjk + cjk ik = tik (conform (2.7.2)), deci
csik tik < .

(2.7.3)

Rezulta ca exista drumuri minime de la vs la vik . Fie


= (vs = x0 , x1 , . . . , xp1 , xp = vik )
un drum elementar minim de la vs la vik . Fie l {0, 1, . . . , p 1} indicele
maxim astfel ncat xl {vi1 , . . . , vik1 } (exista, deoarece x0 = vs = vi1 ).
Fie xl = vir , 1 r k 1, si fie xl+1 = viq , q k.
Din descrierea pasului q al algoritmului, conform relatiilor (2.7.1) si (2.7.2)
rezulta ca
tiq tir + cir iq ,

60

TEMA 2. METODA GREEDY


iar conform ipotezei de inductie pentru r avem
tir = csir < .
Deci
tiq csir + cir iq = csiq

(2.7.4)

(conform principiului optimalitatii al lui Bellman pentru subdrumurile dintre


x0 = vs si xl = vir , respectiv dintre x0 = vs si xl+1 = viq ale drumului minim
).
Cazul 1) Daca l = p 1. atunci xl+1 = vik , deci q = k si din (2.7.3) si
(2.7.4) rezulta ca tik = csik < .
Cazul 2) Daca l < p 1, deci q 6= k, demonstram ca
tik = csik
prin reducere la absurd. Intr-adevar, n caz contrar conform (2.7.3) am avea
csik < tik .
Cum q > k, din descrierea algoritmului avem tiq tik (deoarece valorile
tik sunt monoton crescatoare de la un pas la altul, inductie!). Utilizand
(2.7.4) am obtine
csik < tik tiq csiq ,
ceea ce contrazice faptul ca are loc inegalitatea csiq csik (conform principiului optimalitatii al lui Bellman pentru subdrumul dintre vs si viq al drumului
minim ).
Demonstratia prin inductie este ncheiata.
Evident, pentru orice nod vi ramas neselectat n urma executarii ultimului
pas al algoritmului avem ti = = csi .
Intr-adevar, daca ar exista un drum elementar minim
= (vs = y0 , y1 , . . . , yp = vi ),
luand l {0, 1, . . . , p 1} indicele maxim pentru care yl este selectat (exista,
deoarece y0 = vs este selectat) atunci yl+1 ar fi neselectat desi exista o muchie
sau un arc de la yl la yl+1 , contradictie cu descrierea modului de ncheiere a
algoritmului.
Exemplul 2.7.3. Pentru graful ponderat din Exemplul 2.7.1, luand ca nod
sursa nodul 1, aplicarea Algoritmului Dijkstra este evidentiata n urmatorul
tabel:

61

TEMA 2. METODA GREEDY


Pas Nodul selectat
1
1
2
4
3
3
4
5
5
2

Distanta minima
0
5
10
10
15

De exemplu, la pasul 3 avem deja selectate nodurile i1 = 1 si i2 = 4, cu


distantele minime t1 = c11 = 0 si t4 = c14 = 5. Se selecteaza nodul i3 = 3,
cu distanta minima t3 = 10, deoarece
min{t1 + c12 , t1 + c13 , t1 + c15 , t4 + c42 , t4 + c43 , t4 + c45 }
= min{0 + 15, 0 + 10, 0 + , 5 + 10, 5 + , 5 + 5} = 10 = t1 + c13 .
Observatia 2.7.8. Algoritmul Dijkstra este specific metodei de programare
Greedy, el selectand nodurile n ordinea crescatoare a distantei fata de nodul
sursa.
Observatia 2.7.9. Pentru implementarea Algoritmului Dijkstra, consideram
ca V = {1, . . . , n} si ca nodul sursa este s V . Utilizam un vector S avand
semnificatia

1, daca nodul i a fost selectat,
i {1, . . . , n}
S[i] =
0, n caz contrar,
si un vector t avand semnificatia
t[i] = distanta minima de la nodul sursa s la nodul i, i {1, . . . , n},
calculat conform (2.7.1) si (2.7.2).
Pentru determinarea drumurilor minime de la nodul s la nodurile grafului
vom utiliza si un vector T AT A avand semnificatia
T AT A[i] = nodul j ce este predecesorul direct al nodului i pe drumul
minim de la s la i, i {1, . . . , n}.
Astfel n vectorul T AT A se memoreaza un arbore compus din drumuri
minime de la nodul sursa la nodurile grafului, numit arborele drumurilor
minime.
Daca i = ik este nodul selectat la pasul k, atunci j = jk se determina
conform egalitatii (2.7.1).
Descrierea n pseudocod a algoritmului are forma urmatoare.

62

TEMA 2. METODA GREEDY

DIJKSTRA(s) :
for i = 1, n do
// init
ializ
ari
S[i] 0; t[i] ; T AT A[i] ;
t[s] 0; T AT A[s] 0;
// s este nodul surs
a
repeat
// select
am urm
atorul nod x, ^
n ordinea cresc
atoare
// a distant
elor minime de la s la x
min ;
for i = 1, n do
if (S[i] = 0) and (t[i] < min) then
min t[i];
x i;
if (min < ) then
// exist
a x,
^l select
am
S[x] 1;
for i = 1, n do
// actualiz
am vectorii t s
i T AT A
if (S[i] = 0) and (cxi < ) then
if (t[i] > t[x] + cxi ) then
t[i] t[x] + cxi ;
T AT A[i] x;
while (min < );

Exemplul 2.7.4. Pentru graful ponderat din Exemplul 2.6.1, luand ca nod
sursa nodul s = 1, aplicarea Algoritmului Dijkstra este evidentiata n urmatorul
tabel:
Pas Nodul selectat x T AT A[x]
1
1
0
2
2
1
3
5
1
4
3
2
5
8
5
6
6
3
7
7
1
8
9
5
9
4
3
10
10
9

Distanta minima t[x]


0
30
70
80
80
100
110
110
180
240

Arborele drumurilor minime, memorat n vectorul T AT A, este reprezentat n Figura 2.7.2.

63

TEMA 2. METODA GREEDY

30

50

100

20
6

70
110
5
10
7

40

130

10

Figura 2.7.2:
Deci drumurile minime determinate de algoritm sunt:
de la 1 la 1: [1];
de la 1 la 2: [1, 2];
de la 1 la 3: [1, 2, 3];
de la 1 la 4: [1, 2, 3, 4];
de la 1 la 5: [1, 5];
de la 1 la 6: [1, 2, 3, 6];
de la 1 la 7: [1, 7];
de la 1 la 8: [1, 5, 8];
de la 1 la 9: [1, 5, 9];
de la 1 la 10: [1, 5, 9, 10].
Observatia 2.7.10. Implementarea anterioara necesita O (n2 ) operatii (deoarece blocul repeat se executa de cel mult n ori si necesita de fiecare data
cel mult n comparatii pentru determinarea nodului selectat x si cel mult n
comparatii si n adunari pentru actualizarea vectorilor t si T AT A). Aceasta
este de fapt si complexitatea Algoritmului Dijkstra (n implementarea optima) n cazul memorarii grafului prin matricea distantelor directe.

Tema 3
Metoda Backtracking
3.1

Descrierea metodei. Algoritmi generali

Metoda Backtracking (metoda c


aut
arii cu revenire) se aplica problemelor a caror solutie se poate reprezenta sub forma unui vector
x = (x1 , x2 , . . . , xn ) S1 S2 Sn ,
unde:
S1 , S2 , . . . , Sn sunt multimi finite si nevide, elementele lor aflandu-se
ntr-o relatie de ordine bine stabilita;
ntre componentele x1 , x2 , . . . , xn ale vectorului x sunt precizate anumite relatii, numite conditii interne.
Observatia 3.1.1. Pentru unele probleme, numarul de componente n al solutiilor nu este de la nceput cunoscut, el urmand a fi determinat pe parcurs.
De asemenea, pentru unele probleme, doua solutii pot avea numere diferite
de componente.
Definitia 3.1.1. Multimea finita S = S1 S2 Sn se numeste spatiul
solutiilor posibile.
Un vector x = (x1 , . . . , xn ) S se numeste solutie posibil
a.
Solutiile posibile care satisfac conditiile interne se numesc solutii rezultat.
Observatia 3.1.2. Metoda Backtracking si propune sa determine:
fie o solutie rezultat,
fie toate solutiile rezultat.
64

TEMA 3. METODA BACKTRACKING

65

Obtinerea tuturor solutiilor rezultat poate constitui o etapa intermediara


n rezolvarea unei alte probleme, urmand ca, n continuare, dintre acestea sa
fie alese solutiile care optimizeaza (minimizeaza sau maximizeaza) o anumita
functie obiectiv data.
Observatia 3.1.3. O varianta de determinare a solutiilor rezultat ar putea fi
urmatoarea metoda, numita metoda fortei brute:
se genereaza succesiv toate solutiile posibile, adica toate elementele produsului cartezian S1 S2 Sn ;
pentru fiecare solutie posibila se verifica daca sunt satisfacute conditiile
interne;
se retin cele care satisfac aceste conditii.
Aceasta varianta are dezavantajul ca timpul de executie este foarte mare.
De exemplu, daca card (Si ) = 2, i = 1, n, atunci spatiul solutiilor posibile
ar avea 2n elemente, iar complexitatea ar fi de ordinul (2n ) (nesatisfacatoare!!).
Metoda Backtracking urmareste sa evite generarea tuturor solutiilor posibile,
ceea ce duce la scurtarea timpului de executie.
Definitia 3.1.2. Fie k {1, . . . , n}. Un set de relatii definite pentru componenta xk Sk prin intermediul unor eventuale componente ale vectorului
(x1 , . . . , xk1 ) S1 S2 Sk1 repreinta conditii de continuare
pentru xk mpreuna cu (x1 , . . . , xk1 ) daca:
1. aceste relatii sunt necesare pentru existenta unei solutii rezultat de
forma
(x1 , . . . , xk1 , xk , xk+1 , . . . , xn ),
adica nendeplinirea acestor conditii implica faptul ca oricum am alege
xk+1 Sk+1 , . . . , xn Sn vectorul x = (x1 , . . . , xn ) nu poate fi o solutie
rezultat (nu verifica conditiile interne);
2. pentru k = n conditiile de continuare coincid cu conditiile interne.
Orice vector (x1 , . . . , xk ) S1 S2 Sk , cu 1 k n, care satisface
conditiile de continuare, se numeste solutie partial
a (solutie valid
a).
De asemenea, vectorul vid (fara elemente) este considerat ca fiind solutie
partiala.

TEMA 3. METODA BACKTRACKING

66

Mecanismul metodei Backtracking


Prin metoda Backtracking solutia se construieste pas cu pas (componenta cu
componenta) pe principiul stivei.

La fiecare nivel k, se caut


a un element din multimea de nivel Sk ,
care s
a fie atribuit componentei xk
si care mpreun
a cu (x1 , . . . , xk1 ) s
a verifice conditiile de continuare

Mai precis, avem urmatorii pasi:


1. Se ncepe cu solutia partiala data de vectorul x vid.
2. Se ia primul element din multimea S1 si se atribuie lui x1 .
3. Presupunand generate elementele (x1 , x2 , . . . , xk1 ), xi Si , i = 1, k 1,
se avanseaz
a la nivelul k si se cauta primul element disponibil din Sk
a carui valoare sa fie atribuita lui xk .
Avem urmatoarele cazuri:
3.1. A fost gasit n Sk un element disponibil v. Atunci:
l atribuim lui xk ;
se verifica daca acesta mpreuna cu elementele deja generate
x1 , . . . , xk1 ndeplineste conditiile de continuare.
Avem urmatoarele subcazuri:
3.1.1. xk verifica conditiile de continuare. Spunem ca v este o
valoare valid
a pentru componenta xk .
Atunci:
se extinde solutia partiala la (x1 , . . . , xk1 , xk );
se verifica daca k = n:
3.1.1.1. Daca da, atunci s-a obtinut o solutie rezultat.

TEMA 3. METODA BACKTRACKING

67

Acum, fie ne oprim, fie continuam cu cautarea altei solutii


rezultat, reluand algoritmul (cu pasul 3.), considerand generate (x1 , . . . , xk1 ) si cautand n continuare pentru xk
un element netestat din Sk .
3.1.1.2. Daca nu (k < n), se reia algoritmul cu pasul 3.,
cautand extinderea solutiei partiale (x1 , . . . , xk1 , xk ) cu
testarea primului element din Sk+1 (se avanseaz
a).
3.1.2. xk nu verifica conditiile de continuare. Atunci, oricum am
alege urmatoarele componente pentru x (adica pe xk+1 , . . . , xn ),
nu vom obtine o solutie rezultat. Prin urmare, se va relua algoritmul (cu pasul 3.), avand generate x1 , . . . , xk1 si cautand
extinderea solutiei cu urmatorul element netestat din Sk (continua c
autarea).
3.2. Nu a fost gasit n Sk un element disponibil (netestat). Atunci se
considera generate x1 , . . . , xk2 (se revine) si se reia c
autarea cu
urmatorul element din Sk1 netestat, pentru extinderea solutiei
partiale (x1 , . . . , xk2 ) (pas 3.).
Observatia 3.1.4. Algoritmul se termina atunci cand nu mai exista nici un
element din S1 netestat.
Observatia 3.1.5. Dupa avansare, c
autarea se va face ncepand cu testarea
primului element din multimea de nivel Sk corespunzatoare.
Observatia 3.1.6. Dupa revenire, c
autarea se va face ncepand cu urmatorul
element netestat (la etapele anterioare) din multimea de nivel Sk corespunzatoare.
Observatia 3.1.7. Conditiile de continuare sunt necesare pentru existenta
unei solutii rezultat, iar ideal este ca ele sa fie si suficiente, ceea ce, de obicei,
este imposibil!
Alegerea acestor conditii este esentiala n utilizarea metodei Bactracking,
deoarece cu cat conditiile de continuare sunt mai restrictive, cu atat se limiteaza mai mult numarul de cautari (n consecinta si numarul de avansari si
reveniri), deci metoda este mai eficienta.
De obicei conditiile de continuare sunt restrictiile conditiilor interne la
primele k omponente.
Observatia 3.1.8. In general, problemele rezolvate cu Backtracking necesita
un timp foarte mare de executie. De aceea, metoda se utilizeaza atunci cand
nu avem la dispozitie un algoritm mai eficient. Problemele tipice care se pot
rezolva utilizand aceasta metoda sunt cele nedeterminist-polinomial complete
(NP -complete).

TEMA 3. METODA BACKTRACKING

68

In continuare consideram cazul particular n care multimile Sk , k =


1, n, contin termeni succesivi ai unor progresii aritmetice. Pentru fiecare k,
k = 1, n, multimea Sk va fi data de:
ak primul termen al progresiei;
rk > 0 ratia progresiei;
bk ultimul termen al progresiei,
adica
Sk = {ak , ak + rk , ak + 2rk , . . . , bk }, k = 1, n.
Pentru acest caz particular, vom prezenta n continuare sase variante pentru schema Backtracking: si anume doua variante iterative si patru variante
recursive.
Algoritmul 3.1.1 (Schema Backtracking iterativ
a, varianta 1).
BACKTRACKING1 :
k 1;
x[1] a[1] r[1];// preg
atim introducerea valorii init
iale a1
// pentru x1
while k > 0 do
if x[k] < b[k] then
// mai exist
a valori netestate pentru xk
x[k]
autare
 x[k] + r[k];
 // C
if (x[1], . . . , x[k]) verifica conditiile de continuare then
if k = n then
// (x1 , . . . , xn ) este solut
ie rezultat

PRELUCREAZA(x[1], . . . , x[n]);
(*)
// STOP, dac
a se dore
ste
// o singur
a solut
ie rezultat,
// sau k k 1 (revenire fort
at
a) dac
a
// nu mai exist
a valori valide pentru xn
else
k k + 1;
// Avansare
x[k] a[k] r[k];
// preg
atim introducerea
// valorii init
iale ak pentru xk
else
k k 1;

// nu mai exist
a valori netestate pentru xk
// Revenire

TEMA 3. METODA BACKTRACKING

69

Observatia 3.1.9. Daca dupa determinarea si prelucrarea solutiei rezultat nu


mai exista valori valide pentru componenta x[n], atunci n loc de () se poate
forta revenirea (k k 1).
Urmatoarea schema este echivalenta cu cea de mai sus.
Algoritmul 3.1.2 (Schema Backtracking iterativ
a, varianta 2).
BACKTRACKING2 :
k 1;
x[1] a[1] r[1];// preg
atim introducerea valorii init
iale a1
// pentru x1
while k > 0 do
if k n then
if x[k] < b[k] then
// mai exist
a valori netestate pentru xk
x[k]

x[k]
+
r[k];
// C
autare

if (x[1], . . . , x[k]) verifica conditiile de continuare then
k k + 1;
// Avansare
x[k] a[k] r[k];
// preg
atim introducerea
// valorii init
iale ak pentru xk
else
k k 1;

// Revenire

else

// (x1 , . . . , xn ) este solut


ie rezultat

PRELUCREAZA(x[1],
. . . , x[n]);
(*)
// STOP, dac
a se dore
ste
// o singur
a solut
ie rezultat
k k 1;
// Revenire, dac
a se doresc
// toate solut
iile rezultat
Observatia 3.1.10. Schemele Backtracking de mai sus genereaza toate solutiile
problemei date. Daca se doreste obtinerea unei singure solutii, atunci n loc
de () se poate insera o comanda de oprire (STOP).
Algoritmul 3.1.3 (Schema Backtracking recursiv
a, varianta 1).

TEMA 3. METODA BACKTRACKING


BACKR1(k) :
x[k] a[k] r[k];

70

// se genereaz
a (x[k], . . . , x[n])
// preg
atim introducerea valorii init
iale
// a[k] pentru x[k]

while x[k] < b[k] do


x[k]
// C
autare
 x[k] + r[k];

if (x[1], . . . , x[k]) verifica conditiile de continuare then
if k = n then
// (x[1], . . . , x[n]) este solut
ie rezultat

PRELUCREAZA(x[1],
. . . , x[n]);
else
BACKR1(k + 1);
// Avansare, adic
a
// se genereaz
a, RECURSIV, (x[k + 1], . . . , x[n]).
// La ^
ncheierea apelului BACKR1(k + 1) se produce
// revenirea la funct
ia BACKR1(k)
Apelare: BACKR1(1).
Urmatoarea schema este echivalenta cu cea de mai sus.
Algoritmul 3.1.4 (Schema Backtracking recursiv
a, varianta 2).
BACKR2(k) :
if k n then
x[k] a[k] r[k];
while x[k] < b[k] do
x[k]
 x[k] + r[k];

if (x[1], . . . , x[k]) verifica conditiile de continuare then
BACKR2(k + 1);
else

PRELUCREAZA(x[1],
. . . , x[n]);
Apelare: BACKR2(1).
Algoritmul 3.1.5 (Schema Backtracking recursiv
a, varianta 3).

TEMA 3. METODA BACKTRACKING

71

BACKR3(k) :
for v = a[k], b[k], r[k] do
// C
autarea lui x[k] ^
n mult
imea Sk
x[k]
 v;

if (x[1], . . . , x[k]) verifica conditiile de continuare then
if k = n then
// (x[1], . . . , x[n]) este solut
ie rezultat

PRELUCREAZA(x[1],
. . . , x[n]);
else
BACKR3(k + 1);
// Avansare, adic
a
// se genereaz
a, RECURSIV, (x[k + 1], . . . , x[n]).
// La ^
ncheierea apelului BACKR3(k + 1) se produce
// revenirea la funct
ia BACKR3(k)
Apelare: BACKR3(1).
Urmatoarea schema este echivalenta cu cea de mai sus.
Algoritmul 3.1.6 (Schema Backtracking recursiv
a, varianta 4).
BACKR4(k) :
if k n then
for v = a[k], b[k], r[k] do
x[k]
 v;

if (x[1], . . . , x[k]) verifica conditiile de continuare then
BACKR4(k + 1);
else

PRELUCREAZA(x[1],
. . . , x[n]);
Apelare: BACKR4(1).
Observatia 3.1.11. Schemele Backtracking din Algoritmii 3.1.1, 3.1.2, 3.1.3 si
3.1.4 pot fi usor adaptate si pentru situati n care elementele fiecarei multimi
Sk nu sunt n progresie aritmetica.
Observatia 3.1.12. In oricare din cele sase scheme de mai sus, verificarea
(validarea) conditilor de continuare
[(x[1], x[2], . . . , x[k]) verifica conditiile de continuare]
se face adesea prin intermediul unei functii VALID(x, k).
Observatia 3.1.13. Daca, n oricare din cele sase scheme de mai sus, se renunta
la testul
[(x[1], x[2], . . . , x[k]) verifica conditiile de continuare],

TEMA 3. METODA BACKTRACKING

72

considerandu-se astfel ca orice solutie posibila verifica conditiile interne, atunci se vor obtine ca solutii rezultat ale problemei toate elementele produsului cartezian S1 S2 Sn .

3.2

Colorarea grafurilor

Problema color
arii grafurilor este urmatoarea:
Se considera un graf neorientat fara bucle G = (V, E), cu multimea
nodurilor
V = {1, 2, . . . , n},
si un numar de m culori, numerotate cu 1, 2, . . . , m.
Se cere sa se determine toate modalitatile de colorare ale nodurilor grafului, utilizand cele m culori, astfel ncat oricare doua noduri adiacente sa fie
colorate cu culori diferite.
Modelarea problemei
Orice solutie a problemei se poate scrie sub forma
x = (x1 , x2 , . . . , xn ),
unde xi este culoarea atasata nodului i, xi {1, 2, . . . , m}.
Avem
x = (x1 , x2 , . . . , xn ) S1 S2 Sn ,
unde
S1 = S2 = = Sn = {1, 2, . . . , m}.
Asadar multimile Sk contin termenii succesivi ai unei progresii aritmetice,
n care

ak = 1,
rk = 1, k = 1, n.

bk = m,
Conditiile interne:

Orice doua noduri adiacente sunt colorate diferit, adica


xi 6= xj , [i, j] E.

TEMA 3. METODA BACKTRACKING

73

Conditiile de continuare:
Daca x1 , . . . , xk1 sunt deja alese, atunci xk verifica conditiile de continuare
(este valid ) daca
xi 6= xk , i {1, . . . , k 1} cu [i, k] E.
Altfel spus, xk nu verifica conditiile de continuare (nu este valid ), daca
exista i {1, 2, . . . , k 1} astfel ncat [i, k] E si xi = xk .

Observatia 3.2.1. Pentru reprezentarea grafului utilizam matricea de adiacenta


A = (aij )i,j=1,n .
Graful fiind neorientat, matricea de adiacenta este simetrica.
Obtinem urmatorul algoritm Backtracking, descris n pseudocod, pentru
rezolvarea problemei.
Algoritmul 3.2.1.
COLORARE(A, n, m) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < m then
x[k] x[k] + 1;
if VALID(x, k) then
if k = n then
AFISARE(x);
else
k k + 1;
x[k] 0;
else
k k 1;
Functia de verificare (validare) a conditiilor de continuare este
VALID(x, k) :
for i = 1, k 1 do
if (aik 1 and x[i] = x[k]) then
returneaz
a 0;
returneaz
a 1;

74

TEMA 3. METODA BACKTRACKING

Aplicatie: colorarea h
artilor
Problema color
arii h
artilor este urmatoarea:
Se considera o harta si un numar de culori. Se cere sa se coloreze fiecare
tara cu cate una din culori astfel ncat orice doua tari ce au frontiera comuna
sa fie colorate diferit.
Modelarea problemei
Oricarei harti i se poate asocia un graf neorientat simplu astfel:
fiecarei tari i corespunde un nod;
ntre doua noduri exista muchie daca si numai daca ele corespund unor
tari ce au frontiera comuna.
O astfel de corespondenta este evidentiata n Figura 3.2.1.
2
1

1
5

3
5

Figura 3.2.1:
Astfel problema colorarii unei harti se reduce la problema colorarii grafului asociat.
Observatia 3.2.2. Graful asociat unei harti este planar, adica exista o reprezentare grafica n plan a acestuia astfel ncat muchiile sa nu se intersecteze
decat n noduri.
Avem urmatorul rezultat celebru.
Teorema 3.2.1 (Teorema celor 4 culori). Pentru colorarea unui graf
planar sunt suficiente patru culori.
Observatia 3.2.3. Celebritatea problemei colorarii hartilor a constat n faptul
ca n toate exemplele ntalnite colorarea s-a putut face cu numai 4 culori, dar
teoretic se demonstrase ca sunt suficiente 5 culori.

TEMA 3. METODA BACKTRACKING

75

Problema a aparut n 1852, cand un matematician amator, Fracis


Guthrie, a ncercat sa coloreze harta comitatelor britanice, folosind
numai 4 culori.
In anul 1976, Wolfgang Haken si Kenneth Appel, de la Universitatea
Illinois (SUA), au demonstrat ca pentru colorare sunt suficiente 4 culori.
Demonstratia s-a efectuat cu ajutorul calculatorului electronic, analizandu-se 1482 configuratii n circa 1200 ore calculator.

3.3

Problema celor n dame pe tabla de sah

Problema celor n dame este urmatoarea:


Se considera o tabla de sah de dimensiune n n, n 2. Se cere sa se
determine toate modalitatile de aranjare a n dame astfel ncat oricare doua
dame sa nu se atace reciproc (pe linii, coloane sau diagonale).
Observatia 3.3.1. Prin conventie, orice patratel al tablei este reprezentat prin
coordonatele sale (l, c), unde l reprezinta linia, iar c reprezinta coloana acestuia. Liniile tablei sunt numerotate cu 1, 2, . . . , n de sus n jos, iar coloanele
sunt numerotate cu 1, 2, . . . , n de la stanga la dreapta.
Propozitia 3.3.1. Pe o tabla de dimensiune n n nu putem aseza mai mult
de n dame astfel ncat oricare doua sa nu se atace reciproc.
Demonstratie. Oricum asezam mai mult de n dame, cum tabla are n linii
rezulta ca exista cel putin doua dame asezate pe aceeasi linie, si acestea se
ataca reciproc.
Modelarea problemei
In orice solutie rezultat, conform demonstratiei propozitiei anterioare obtinem
ca pe fiecare linie a tablei se afla exact o dama. Rezulta ca orice solutie pentru
problema celor n dame se poate reprezenta sub forma unui vector
x = (x1 , x2 , . . . , xn ),
unde xi reprezinta coloana pe care se afla dama de pe linia i, pentru i = 1, n.
De exemplu, pentru n = 5 o solutie rezultat este
x = (1, 3, 5, 2, 4),
corespunzatoare aranjarii damelor din Figura 3.3.1.

TEMA 3. METODA BACKTRACKING

76

Figura 3.3.1:
Pentru cazul general, avem
x = (x1 , x2 , . . . , xn ) S1 S2 Sn ,
unde
S1 = S2 = = Sn = {1, 2, . . . , n}.

Asadar multimile Sk contin termenii succesivi ai unei progresii aritmetice,


n care

ak = 1,
rk = 1, k = 1, n.

bk = n,
Conditiile interne:

Damele de pe liniile i si j (i 6= j) nu se pot afla pe aceeasi coloana:


xi 6= xj , i 6= j, i, j = 1, n;
Damele de pe liniile i si j (i 6= j) nu se pot afla pe o aceeasi diagonala:
|ij| =
6 | xi xj |, i 6= j, i, j = 1, n
sau, echivalent,
j i 6= | xj xi |, i, j a.. 1 i < j n.
Conditiile de continuare:
Daca avem solutia partiala (x1 , . . . , xk1 ), atunci xk verific
a conditiile de
continuare (este valid ) daca
xk 6= xi si k i 6= | xk xi |, i = 1, k 1.

77

TEMA 3. METODA BACKTRACKING

Altfel spus, daca avem solutia partiala x = (x1 , . . . , xk1 ), atunci xk nu


verifica conditiile de continuare (nu este valid ) daca
i {1, 2, . . . , k 1} astfel ncat xk = xi sau k i = | xk xi |.
Obtinem urmatorul algoritm Backtracking, descris n pseudocod, pentru
rezolvarea problemei.
Algoritmul 3.3.1.
DAME (n) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < n then
x[k] x[k] + 1;
if VALID(x, k) then
if k = n then
AFISARE(x);
k k 1;
// fort

am revenirea, deoarece
// nu mai exist
a valori valide pentru x[n]
else
k k + 1;
x[k] 0;
else
k k 1;
Functia de verificare (validare) a conditiilor de continuare este
VALID(x, k) :
for i = 1, k 1 do
if (x[k] = x[i] or k i = | x[k] x[i] |) then
returneaz
a 0;
returneaz
a 1;

// fals

// adev
arat

Consideratii
Pentru n = 2 problema nu are solutie, deoarece doua dame asezate
pe linii si coloane diferite se afla pe aceeasi diagonala, deci se ataca
reciproc.
Nici pentru n = 3 problema nu are solutie, deoarece orice doua dame
asezate pe o aceeasi culoare se ataca reciproc.

TEMA 3. METODA BACKTRACKING

78

Pentru n 4 avem urmatorul rezultat celebru.


Teorema 3.3.1 (E. Pauls, 1874). Pentru orice n 4 problema celor n
dame are cel putin o solutie.
Demonstratie. Avem urmatoarele cazuri.
Cazul 1) n = 6k sau n = 6k + 4. Atunci o solutie este data de asezarea
celor n dame n patratelele de coordonate (l, c) ce apartin multimii
n
no n
n
no
(2i, i) | 1 i
(2i 1, + i) | 1 i
.
2
2
2

Cazul 2) n = 6k +1 sau n = 6k +5. Atunci o solutie este data de asezarea


celor n dame n patratelele de coordonate (l, c) ce apartin multimii

 

n1
n+1
n1
(2i 1,
.
{(n, 1)} (2i, i + 1) | 1 i
+ i) | 1 i
2
2
2
Cazul 3) n = 6k + 2. Atunci o solutie este data de asezarea celor n dame
n patratelele de coordonate (l, c) ce apartin multimii
o
n
n
n
n
n
(4, 1), (n, 1), (2, ), (n 1, + 1), (1, + 2), (n 3, n)
2 n
2
2
2 o
n
(n 2i, i + 1) | 1 i 3
2
n
o
n
n
(n 2i 3, + i + 2) | 1 i 3 .
2
2

Cazul 4) n = 6k + 3. Atunci o solutie este data de asezarea celor n dame


n patratelele de coordonate (l, c) ce apartin multimii


n1
n1
n1
(1, n), (5, 1), (n,
1), (3,
), (n 1,
+ 1)
2
2
2
 


n1
n1
+ 2), (n 3, n 1) (n 2i, i + 1) | 1 i
3
(2,
2
2


n1
n1
(n 2i 3,
+ i + 2) | 1 i
3 ,
2
2

adica se aseaza o dama n coltul din dreapta sus (patratelul de coordonate


(1, n)) iar celelalte n 1 dame se aseaza conform Cazului 3 n subtabla de
dimensiune (n 1) (n 1) ramasa prin eliminarea primei linii si ultimei
coloane.
Conform Teoremei 3.3.1, Propozitiei 3.3.1 si cazurilor n = 2 si n = 3
considerate mai sus obtinem urmatorul rezultat.

TEMA 3. METODA BACKTRACKING

79

Corolarul 3.3.1. Numarul maxim de dame ce pot fi asezate pe o tabla de sah


de dimensiune n n astfel ncat oricare doua dame sa nu se atace reciproc
este egal cu
(
n 1, daca n {2, 3},
n,
daca n 4.
Problema a fost expusa initial pentru tabla de sah obisnuita 8 8 n
anul 1848 de catre sahistul german Max Bezzel.
Prima rezolvare a problemei celor 8 dame a fost publicata de catre Franz
Nauck n anul 1850, care a gasit toate cele 92 de solutii ale problemei.
Acesta a propus si varianta generalizata la tabla de dimensiune n n.
Problema a fost imediat studiata de multi matematicieni, printre care
si celebrul matematician Carl Friedrich Gauss.
Emil Pauls a fost primul care a demonstrat existenta solutiei pentru
orice n 4, n anul 1874, prin constructia din demonstratia teoremei
de mai sus.

3.4

Problema nebunilor pe tabla de sah

Problema nebunilor este urmatoarea:


Se considera o tabla de sah de dimensiune n n, n 2. Se cere sa
se determine toate modalitatile de aranjare a n 1 nebuni pe patratele de
aceeasi culoare astfel ncat oricare doi nebuni sa nu se atace reciproc (pe
diagonale).
Observatia 3.4.1. Utilizam n continuare conventia din Observatia 3.3.1. Tot
prin conventie, patratelul situat n coltul din stanga sus al tablei, de coordonate (1, 1), este colorat cu alb.
Propozitia 3.4.1. Pe o tabla de dimensiune n n nu putem aseza mai mult
de n 1 nebuni pe patr
atele de aceeasi culoare astfel ncat oricare doi nebuni
sa nu se atace reciproc.
Demonstratie. Multimea N a patratelelor de culoare neagra poate fi partitionata n urmatoarele diagonale (cu directia stanga-jos dreapta-sus, ordonate crescator dupa distanta fata de coltul din stanga-sus):
N = D1 D2 Dn1 , unde
Dk = {(l, c) | l + c = 2k + 1, 1 l n, 1 c n}, k = 1, n 1. (3.4.1)

80

TEMA 3. METODA BACKTRACKING

Rezulta ca oricum asezam mai mult de n 1 nebuni pe patratele de culoare


neagra exista cel putin doi nebuni asezati pe o aceeasi diagonala Dk , si acestia
se ataca reciproc.
Pe de alta parte, multimea A a patratelelor de culoare alba poate fi partitionata n urmatoarele diagonale (avand, de asemenea, directia stanga-jos
dreapta-sus si ordonate crescator dupa distanta fata de coltul din stanga-sus):
A = D1 D2 D n , unde

D k = {(l, c) | l + c = 2k, 1 l n, 1 c n}, k = 1, n.

(3.4.2)

Rezulta ca oricum asezam mai mult de n 1 nebuni pe patratele de culoare


alba, fie exista cel putin doi nebuni asezati pe o aceeasi diagonala D k si acestia
se ataca reciproc, fie exista cate cel putin un nebun pe fiecare diagonala D k
si atunci nebunii de pe diagonalele D1 = {(1, 1)} si Dn = {(n, n)} se ataca
reciproc.

Modelarea problemei
Cazul 1) Consideram cazul asezarii celor n 1 nebuni pe patratele de culoare
neagra.
Pentru orice solutie rezultat, conform demonstratiei propozitiei anterioare
obtinem ca pe fiecare din cele n 1 diagonale Dk definite prin relatia (3.4.1)
se afla exact un nebun.
Fiecare diagonala Dk , k = 1, n 1. poate fi rescrisa astfel
Dk = {(l, c) | l + c = 2k + 1, 1 l n, 1 c n}
= {(l, 2k + 1 l) | 1 l n, 1 2k + 1 l n}
= {(l, 2k + 1 l) | 1 l n, 2k + 1 n l 2k}
= {(l, 2k + 1 l) | max{2k + 1 n, 1} l min{2k, n}},
deci

hni

,
{(l, 2k + 1 l) | 1 l 2k}, daca 1 k
2
Dk =
h i

{(l, 2k + 1 l) | 2k + 1 n l n}, daca n < k n 1


2

([t] reprezinta partea ntreaga a numarului t R).


Pentru orice k {1, 2, . . . , n 1}, coloana pe care se afla nebunul de pe
diagonala Dk este
c = 2k + 1 l,

TEMA 3. METODA BACKTRACKING

81

deci este bine determinata de linia l a acestuia.


Rezulta ca orice solutie se poate reprezenta sub forma unui vector
x = (x1 , x2 , . . . , xn1 ),
unde xk reprezinta linia pe care se afla nebunul de pe diagonala Dk , pentru
k = 1, n 1.
De exemplu, pentru n = 5 o solutie rezultat este
x = (1, 4, 2, 5),
corespunzatoare aranjarii nebunilor din Figura 3.4.1.

Figura 3.4.1:
Pentru cazul general, avem
x = (x1 , x2 , . . . , xn1 ) S1 S2 Sn1 ,
unde

h i
{1, 2, . . . , 2k}, daca 1 k n ,
2
h i
Sk =
{2k n + 1, 2k n + 2, . . . , n}, daca n + 1 k n 1.
2

Asadar multimile Sk contin termenii succesivi ai unei progresii aritmetice,


n care

ak = 1,
hni
rk = 1, k = 1,
,

2
bk = 2k,

ak = 2k n + 1,
hni
rk = 1,
k =
+ 1, n 1.

2
bk = n,

TEMA 3. METODA BACKTRACKING

82

Conditiile interne:
Pentru orice i 6= j, cei doi nebuni de pe diagonalele Di si Dj , asezati
deci pe liniile xi respectiv xj , si pe coloanele ci = 2i + 1 xi respectiv
cj = 2j + 1 xj , nu se pot afla nici pe o aceeasi diagonala avand directia
stanga-sus dreapta-jos:
xi xj 6= ci cj , i 6= j, i, j = 1, n 1,
sau, echivalent,
xi xj 6= 2i + 1 xi 2j 1 + xj , i 6= j, i, j = 1, n 1,
adica
xi xj 6= i j, i 6= j, i, j = 1, n 1.
Conditiile de continuare:
Daca avem solutia partiala (x1 , . . . , xk1 ), atunci xk verific
a conditiile de
continuare (este valid ) daca
xk xi 6= k i, i = 1, k 1.
Altfel spus, daca avem solutia partiala x = (x1 , . . . , xk1 ), atunci xk nu
verifica conditiile de continuare (nu este valid ) daca
i {1, 2, . . . , k 1} astfel ncat xk xi = k i.
Obtinem urmatorul algoritm Backtracking, descris n pseudocod, pentru
rezolvarea problemei.
Algoritmul 3.4.1.

83

TEMA 3. METODA BACKTRACKING

NEBUNI1 (n) :
k 1;
x[1] 0;
ult 2;
// ult este valoarea final
a bk pentru xk
while k > 0 do
if x[k] < ult then
x[k] x[k] + 1;
if VALID1(x, k) then
if k = n 1 then
AFISARE(x);
else
k k + 1;
// preg
atim introducerea valorii init
iale ak s
i
// actualiz
am valoarea final
a bk pentru xk
n
if k then
2
x[k] 0;
ult 2k;
else
x[k] 2k n;
ult n;
else
k k 1;

// actualiz
am valoarea final
a bk pentru xk
n
if k then
2
ult 2k;
else
ult n;

Functia de verificare (validare) a conditiilor de continuare este


VALID1(x, k) :
for i = 1, k 1 do
if x[k] x[i] = k i then
returneaz
a 0;
returneaz
a 1;

// fals

// adev
arat

Cazul 2) Consideram acum cazul asezarii celor n 1 nebuni pe patratele


de culoare alba.
Pentru orice solutie rezultat, conform demonstratiei propozitiei anterioare
obtinem ca un prim nebun se aseaza fie pe patratelul (1, 1) ce formeaza

TEMA 3. METODA BACKTRACKING

84

diagonala D 1 , fie pe patratelul (n, n) ce formeaza diagonala Dn , iar restul


de n 2 nebuni se aseaza cate unul pe fiecare din diagonalele D2 , . . . , Dn1
definite prin relatia (3.4.2).
Fiecare diagonala Dk , k = 2, n 1. poate fi rescrisa astfel
Dk = {(l, c) | l + c = 2k, 1 l n, 1 c n}
= {(l, 2k l) | 1 l n, 1 2k l n}
= {(l, 2k l) | 1 l n, 2k n l 2k 1}
= {(l, 2k l) | max{2k n, 1} l min{2k 1, n}},
deci



n+1

,
{(l, 2k l) | 1 l 2k 1}, daca 2 k
2
Dk =



n+1

< k n 1.
{(l, 2k l) | 2k n l n}, daca
2

Pentru orice k {2, . . . , n 1}, coloana pe care se afla nebunul de pe


diagonala D k este
c = 2k l,
deci este bine determinata de linia l a acestuia.
Rezulta ca orice solutie se poate reprezenta sub forma unui vector
y = (y1, y2 , . . . , yn1),
unde
(
1, daca primul nebun se afla pe patratelul (1, 1),
y1 =
n, daca primul nebun se afla pe patratelul (n, n),
iar pentru k {2, . . . , n 1} yk reprezinta linia pe care se afla nebunul de
pe diagonala D k .
Avem
y = (y1 , y2 , . . . , yn1 ) S1 S2 Sn1 ,
unde

{1, n}, daca k = 1,




n+1
,
Sk = {1, 2, . . . , 2k 1}, daca 2 k
2



n+1

{2k n, 2k n + 1, . . . , n}, daca


+ 1 k n 1.
2

TEMA 3. METODA BACKTRACKING

85

Pentru k {2, . . . , n 1} multimile Sk contin termenii succesivi ai unei


progresii aritmetice, n care



ak = 1,
n+1
rk = 1,
k = 2,
,

2
bk = 2k 1,



ak = 2k n,
n+1
rk = 1,
+ 1, n 1.
k =

2
bk = n,

Conditiile interne:
Analog cazului 1) obtinem:

yi yj 6= i j, i 6= j, i, j = 2, n 1.
In plus,
y1 {1, n}.
Conditiile de continuare:
Daca avem solutia partiala (y1 , . . . , yk1 ), cu k 2, atunci yk verific
a
conditiile de continuare (este valid ) daca
yk yi 6= k i, i = 2, k 1.
Altfel spus, daca avem solutia partiala (y1 , . . . , yk1 ), cu k 2, atunci yk
nu verifica conditiile de continuare (nu este valid ) daca
i {2, . . . , k 1} astfel ncat yk yi = k i.
Obtinem urmatorul algoritm Backtracking, descris n pseudocod, pentru
rezolvarea problemei.
Algoritmul 3.4.2.

86

TEMA 3. METODA BACKTRACKING

NEBUNI2 (n) :
// presupunem c
a n3
k 2;
y[2] 0;
ult 3;
// ult este valoarea final
a bk pentru yk
while k > 1 do
if y[k] < ult then
y[k] y[k] + 1;
if VALID2(y, k) then
if k = n 1 then
y[1] 1;
// primul nebun pe p
atr
a
telul (1, 1)
AFISARE(y);
y[1] n;
// primul nebun pe p
atr
a
telul (n, n)
AFISARE(y);
else
k k + 1;
// preg
atim introducerea valorii init
iale ak s
i
// actualiz
am valoarea final
a bk pentru yk
n+1
if k
then
2
y[k] 0;
ult 2k 1;
else
y[k] 2k n 1;
ult n;
else
k k 1;

// actualiz
am valoarea final
a bk pentru yk
n+1
if k
then
2
ult 2k 1;
else
ult n;

Functia de verificare (validare) a conditiilor de continuare este


VALID2(y, k) :
for i = 2, k 1 do
if y[k] y[i] = k i then
returneaz
a 0;
returneaz
a 1;

// fals

// adev
arat

TEMA 3. METODA BACKTRACKING

87

Consideratii
Teorema 3.4.1. Pentru orice n 2 problema nebunilor are cel putin o
solutie.
Demonstratie. Avem din nou urmatoarele doua cazuri.
Cazul 1) Cei n 1 nebuni trebuie asezati pe patratele de culoare neagra.
Atunci o solutie este data de asezarea celor n 1 nebuni n patratelele de
coordonate (l, c) ce apartin multimii
 


n1
n1
(n, 2i) | 1 i
, daca n este impar,
(1, 2i) | 1 i
2
2
respectiv multimii
n
no n
no
(1, 2i) | 1 i
(n, 2i 1) | 2 i
, daca n este par.
2
2

Cazul 2) Cei n 1 nebuni trebuie asezati pe patratele de culoare alba.


Atunci o solutie este data de asezarea celor n 1 nebuni n patratelele de
coordonate (l, c) ce apartin multimii

 

n+1
n1
(1, 2i 1) | 1 i
(n, 2i 1) | 2 i
, daca n este
2
2

impar, respectiv multimii


n
no n
no
(1, 2i 1) | 1 i
(n, 2i 2) | 2 i
, daca n este par.
2
2
Conform Teoremei 3.4.1 si Propozitiei 3.4.1 obtinem urmatorul rezultat.
Corolarul 3.4.1. Numarul maxim de nebuni ce pot fi asezati pe patratele de
aceeasi culoare ale unei table de sah de dimensiune n n, n 2, astfel ncat
oricare doi nebuni sa nu se atace reciproc este egal cu n 1.

Evident, orice doi nebuni asezati pe patratele de culori diferite nu se ataca


reciproc. Astfel, conform corolarului anterior obtinem urmatorul rezultat.

Corolarul 3.4.2. Numarul maxim de nebuni ce pot fi asezati pe o tabla de


sah de dimensiune n n, n 2, astfel ncat oricare doi nebuni sa nu se
atace reciproc este egal cu 2n 2.
Observatia 3.4.2. Pentru generarea tuturor modalitatilor de aranjare a 2n2
nebuni pe o tabla de sah de dimensiune n n astfel ncat oricare doi nebuni
sa nu se atace reciproc putem proceda astfel:

TEMA 3. METODA BACKTRACKING

88

se genereaza toate modalitatile de asezare a n 1 nebuni pe patratelele


de culoare alba astfel ncat oricare doi nebuni sa nu se atace reciproc;
pentru fiecare astfel de asezare, se genereaza toate modalitatile de
asezare a restului de n 1 nebuni pe patratelele de culoare neagra
astfel ncat oricare doi din acestia sa nu se atace reciproc.
Pentru aceasta putem utiliza functia NEBUNI2 (n) din Algoritmul 3.4.2
n care nlocuim functia AFISARE(y) cu functia NEBUNI1 (n) din Algoritmul 3.4.1.

3.5
3.5.1

Generarea obiectelor combinatoriale


Preliminarii

In continuare vom prezenta formule de numarare si algoritmi de generare


(enumerare) pentru cele mai cunoscute familii de obiecte combinatoriale:
produs cartezian, submultimi, aranjamente (fara repetitie sau cu repetitie),
combinari (fara repetitie sau cu repetitie), permutari (fara repetitie sau cu
repetitie).
Reamintim pentru nceput cateva notiuni uzuale.
Definitia 3.5.1. Fie A un alfabet (adica o multime finita) si n N . O
secventa de forma
a = a1 a2 . . . an , cu a1 , a2 , . . . , an A,
se numeste cuv
ant de lungime n peste alfabetul A. Lungimea cuvantului
a se noteaza cu |a|.
Observatia 3.5.1. Evident, cuvantul a1 a2 . . . an poate fi identificat cu vectorul
(a1 , a2 , . . . , an ).
Definitia 3.5.2. Fie x R si n N. Notam

1, daca n = 0,
x(x 1) . . . (x n + 1), daca n 1,
[x]n =
{z
}
|
n factori

1, daca n = 0,
n
x(x + 1) . . . (x + n 1), daca n 1.
[x] =
{z
}
|
n factori

[x]n se numeste polinomul factorial descresc


ator de gradul n, iar [x]n
se numeste polinomul factorial cresc
ator de gradul n.

TEMA 3. METODA BACKTRACKING

3.5.2

89

Produs cartezian

Definitia 3.5.3. Produsul cartezian al multimilor A1 , A2 , . . . , An (n


N ) este multimea
A1 A2 . . . An = {(x1 , x2 , . . . , xn )|x1 A1 , x2 A2 , . . . , xn An }.
Exemplul 3.5.1. {a, b}{+, }{c} = {(a, +, c), (a, , c), (b, +, c), (b, , c)}.

Propozitia 3.5.1 (de num


arare a produsului cartezian). Fie n N si
A1 , A2 , . . . , An multimi finite. Atunci card (A1 A2 . . . An ) = card (A1 )
card (A2 ) . . . card (An ).
Demonstratie. Se utilizeaza metoda inductiei matematice dupa n.
Algoritmul 3.5.1 (de generare a produsului cartezian prin metoda
Backtracking). Fie multimile standard
A1 = {1, 2, . . . , m1 }, A2 = {1, 2, . . . , m2 }, . . . , An = {1, 2, . . . , mn }.
Vom utiliza metoda Backtracking. Avem
x = (x1 , x2 , . . . , xn ) S1 S2 Sn ,
unde
S1 = A1 , S2 = A2 , , Sn = An .

Asadar, multimile Sk , contin termeni succesivi ai unei progresii aritmetice, n care

ak = 1,
rk = 1,
k = 1, n.

bk = mk ,
Conform Observatiei 3.1.13, eliminam verificarea conditiilor de continuare.
PRODUS CARTEZIAN(n, m) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < m[k] then
x[k] x[k] + 1;
if k = n then
AFISARE(x, n);
else
k k + 1;
x[k] 0;
else
k k 1;

TEMA 3. METODA BACKTRACKING

90

Functia de afisare este


AFISARE(x, n) :
for i = 1, n do
afiseaz
a x[i];
Observatia 3.5.2. Pentru generarea produsului cartezian A1 A2 . . . An
al unor multimi finite arbitrare
A1 = {a11 , a12 , . . . , a1m1 },
A2 = {a21 , a22 , . . . , a2m2 },
...,
An = {an1 , an2 , . . . , anmn }
se poate folosi algoritmul anteriori, bazati pe generarea indicilor, nlocuind
afisarea indicilor xi cu afisarea elementelor corespunzatoare aixi din multimile
Ai , adica nlocuind functia AFIS
ARE(x, n) cu functia
AFISARE(x, a, n) :
for i = 1, n do
afiseaz
a a[i, x[i]];

3.5.3

Submultimi

Propozitia 3.5.2 (de num


arare a submultimilor). Fie A o multime
finita si P(A) multimea tuturor submultimilor (partilor) lui A. Atunci
card (P(A)) = 2card (A) .
Demonstratie. Fie A = {a1 , a2 , . . . , an }, n N . Notam
{1, 2}n = {1, 2} . . . {1, 2} .
|
{z
}
de n ori

Definim functiile : P(A) {1, 2}n si : {1, 2}n P(A) prin:



1, daca ai B,
B P(A), (B) = (x1 , x2 , . . . , xn ), unde xi =
2, daca ai 6 B;
(x1 , x2 , . . . , xn ) {1, 2}n, (x1 , x2 , . . . , xn ) = {ai |xi = 1, i {1, . . . , n}}.
Functiile si sunt inverse una celeilalte, deci sunt bijective si
card (P(A)) = card ({1, 2}n ) = 2n .

91

TEMA 3. METODA BACKTRACKING

Exemplul 3.5.2. Pentru A = {a, b, c}, corespondenta submultimi produs


cartezian din demonstratia anterioara este redata n urmatorul tabel:
(x1 , x2 , x3 ) {1, 2}3
(1,1,1)
(1,1,2)
(1,2,1)
(1,2,2)
(2,1,1)
(2,1,2)
(2,2,1)
(2,2,2)

B P(A)
{a, b, c}
{a, b}
{a, c}
{a}
{b, c}
{b}
{c}

Deci A are 23 = 8 submultimi.


Fie multimea A = {a1 , a2 , . . . , an }. Conform demonstratiei anterioare,
putem genera produsul cartezian {1, 2}n cu Algoritmul 3.5.1 nlocuind afisarea elementelor (x1 , . . . , xn ) cu afisarea submultimilor corespunzatoare
B = {ai |xi = 1, i {1, . . . , n}}.
Obtinem urmatorul algoritm descris n pseudocod.
Algoritmul 3.5.2 (de generare a submultimilor, folosind metoda Backtracking).
SUBMULT
IMI(a, n) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < 2 then
x[k] x[k] + 1;
if k = n then
AFISARE(x, a, n);
else
k k + 1;
x[k] 0;
else
k k 1;

Functia de afisare este


AFISARE(x, a, n) :
for i = 1, n do
if x[i] = 1 then afiseaz
a a[i];

TEMA 3. METODA BACKTRACKING

3.5.4

92

Aranjamente cu repetitie

Propozitia 3.5.3 (de num


arare a aranjamentelor cu repetitie). Fie
m, n N. Atunci numarul de cuvinte de lungime n peste un alfabet cu m
litere este egal cu mn .
Demonstratie. Fie B = {1, 2, . . . , m} si C = {(x1 , x2 , . . . , xn )|xi B i}.
Cum C = B n , conform Propozitiei 3.5.1 avem card (C) = mn .
Definitia 3.5.4. Cuvintele numarate n propozitia anterioara se numesc
aranjamente cu repetitie de m luate cate n. Prin abuz de limbaj, si
numarul lor, adica mn , se numeste tot aranjamente cu repetitie de m
luate c
ate n.
Exemplul 3.5.3. Pentru m = 2 si n = 3, aranjamente cu repetitie sunt, n
ordine lexicografica:
(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2), (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2).
Deci avem 23 = 8 aranjamente cu repetitie.
Algoritmul 3.5.3 (de generare a aranjamentelor cu repetitie). Pentru multimea standard B = {1, 2, . . . , m}, conform demonstratiei anterioare
putem genera produsul cartezian B n , cu Algoritmul 3.5.1 luand m1 = m2 =
= mn = m.
Observatia 3.5.3. Pentru o multime A = {a1 , a2 , . . . , an } oarecare putem
genera indicii (x1 , . . . , xn ) cu algoritmul anterior si afisa elementele corespunzatoare acestor indici (ax1 , . . . , axn ).

3.5.5

Aranjamente

Propozitia 3.5.4 (de num


arare a aranjamentelor). Fie m, n N.
Atunci numarul de cuvinte de lungime n cu litere distincte peste un alfabet cu m litere este egal cu [m]n .
Demonstratie. Fie A = {1, 2, . . . , m} si
C1 = {(x1 , x2 , . . . , xn )|xi A i, xi 6= xj i 6= j}.

TEMA 3. METODA BACKTRACKING

93

Avem
n
C1 = (x1 , x2 , . . . , xn )|x1 {1, . . . , m},

x2 {1, . . . , m} \ {x1 },
x3 {1, . . . , m} \ {x1 , x2 },
...,
o
xn {1, . . . , m} \ {x1 , . . . , xn1 } ,

deci card (C1 ) = m(m 1)(m 2) . . . (m n + 1) = [m]n .

Definitia 3.5.5. Cuvintele numarate n propozitia anterioara se numesc


aranjamente (f
ar
a repetitie) de m luate cate n. De asemenea si numarul
lor, adica [m]n , se numeste tot aranjamente (f
ar
a repetitie) de m luate
n
c
ate n si se mai noteaza cu Am .
Observatia 3.5.4. Pentru n > m avem
[m]n = m . . . (m m) . . . (m n + 1) = 0.
Exemplul 3.5.4. Pentru m = 4 si n = 2, aranjamentele sunt, n ordine lexicografica:
(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3).
Deci avem [4]2 = 4 3 = 12 aranjamente.
Algoritmul 3.5.4 (de generare a aranjamentelor prin metoda Backtracking, varianta 1). Fie multimea standard A = {1, 2, . . . , m} si n m.
Vom utiliza metoda Backtracking. Avem
x = (x1 , x2 , . . . , xn ) S1 S2 Sn ,
unde
S1 = S2 = = Sn = A.
Asadar, multimile Sk , contin termeni succesivi ai unei progresii aritmetice, n care

ak = 1,
rk = 1, k = 1, n.

bk = m,
Conditiile interne:

xi 6= xj , i 6= j, i, j = 1, n.

TEMA 3. METODA BACKTRACKING

94

Conditiile de continuare:
Daca avem solutia partiala (x1 , . . . , xk1 ), atunci xk verific
a conditiile de
continuare daca
xk 6= xi , i = 1, k 1.
Altfel spus, daca avem solutia partiala x = (x1 , . . . , xk1 ), atunci xk nu
verifica conditiile de continuare daca
i {1, 2, . . . , k 1} astfel ncat xk = xi .
ARANJAMENTE1(m, n) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < m then
x[k] x[k] + 1;
if VALID(x, k) then
if k = n then
AFISARE(x, n);
else
k k + 1;
x[k] 0;
else
k k 1;
VALID(x, k) :
for i = 1, k 1 do
if x[k] = x[i] then
returneaz
a 0;
returneaz
a 1;

// fals
// adev
arat

Functia de afisare este, din nou:


AFISARE(x, n) :
for i = 1, n do
afiseaz
a x[i];
Algoritmul 3.5.5 (de generare a aranjamentelor prin metoda Backtracking, varianta 2). Putem mbunatati algoritmul anterior prin utilizarea unui vector (y1 , y2 , . . . , ym ) cu semnificatia: daca avem solutia partiala
(x1 , . . . , xk1 ), atunci
(
1, daca i {x1 , . . . , xk1 },
yi =
i = 1, m.
0, daca i 6 {x1 , . . . , xk1 },

TEMA 3. METODA BACKTRACKING

95

Astfel xk verifica conditiile de continuare daca si numai daca


yxk = 0.
Obtinem urmatorul algoritm:
ARANJAMENTE2(m, n) :
for i = 1, m do y[i] 0;
// init
ial, solut
ia part
ial
a este
// vectorul vid
k 1;
x[1] 0;
while k > 0 do
if x[k] < m then
x[k] x[k] + 1;
if y[x[k]] = 0 then
// x[k] verific
a condit
iile
// de continuare
if k = n then
AFISARE(x, n);
else
y[x[k]] 1;
// ^
nainte de avansare, se adaug
a
// x[k] la solut
ia part
ial
a
k k + 1;
x[k] 0;
else
k k 1;
y[x[k]] 0;

// dup
a revenire, se elimin
a
// x[k] din solut
ia part
ial
a

Functia de afisare este aceeasi ca n algoritmul anterior.


Observatia 3.5.5. Pentru generarea aranjamentelor de m luate cate n ale unor
multimi finite arbitrare
A = {a1 , a2 , . . . , am }
se pot folosi algoritmii anteriori, bazati pe generarea indicilor, nlocuind
afisarea indicilor xi cu afisarea elementelor corespunzatoare axi din multimile
Ai , adica nlocuind functia AFIS
ARE(x, n) cu functia
AFISARE(x, a, n) :
for i = 1, n do
afiseaz
a a[x[i]];

TEMA 3. METODA BACKTRACKING

3.5.6

96

Permut
ari

Propozitia 3.5.5 (de num


arare a permut
arilor). Fie n N. Atunci
numarul de cuvinte ce contin exact o data fiecare litera a unui alfabet cu n
litere este egal cu n!, unde
n! = 1 2 3 n (n factorial), 0! = 1.
Demonstratie. Luam m = n n Propozitia 3.5.4 si folosim egalitatea [n]n =
n(n 1) . . . 1 = n!.
Definitia 3.5.6. Cuvintele numarate n propozitia anterioara se numesc
permut
ari (f
ar
a repetitie) de ordinul n. De asemenea si numarul lor,
adica n!, se numeste tot permut
ari (f
ar
a repetitie) de n.
Exemplul 3.5.5. Pentru n = 3, permutarile multimii standard {1, 2, 3} sunt,
n ordine lexicografica:
(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1).
Deci avem 3! = 1 2 3 = 6 permutari.
Algoritmul 3.5.6 (de generare a permut
arilor prin metoda Backtracking, varianta 1). Fie multimea standard A = {1, 2, . . . , n}. Luand m = n
n Algoritmul 3.5.4 de generare a aranjamentelor si fortand revenirea dupa
determinarea fiecarei permutari (deoarece dupa determinarea unei permutari
(x1 , x2 , . . . , xn ) nu mai exista alte valori valide pentru componenta xn ) obtinem urmatorul algoritm.

PERMUTARI1(n)
:
k 1;
x[1] 0;
while k > 0 do
if x[k] < n then
x[k] x[k] + 1;
if VALID(x, k) then
if k = n then
AFISARE(x, n);
k k 1;
// fort

am revenirea, deoarece
// nu mai exist
a valori valide pentru x[n]
else
k k + 1;
x[k] 0;
else
k k 1;

TEMA 3. METODA BACKTRACKING


VALID(x, k) :
for i = 1, k 1 do
if x[k] = x[i] then
returneaz
a 0;
returneaz
a 1;

97

// fals
// adev
arat

Functia de afisare este, din nou:


AFISARE(x, n) :
for i = 1, n do
afiseaz
a x[i];
Algoritmul 3.5.7 (de generare a permut
arilor prin metoda Backtracking, varianta 2). Luand m = n n Algoritmul 3.5.5 de generare a aranjamentelor si fortand din nou revenirea dupa determinarea fiecarei permutari
obtinem urmatorul algoritm.

PERMUTARI2(n)
:
for i = 1, n do y[i] 0;
k 1;
x[1] 0;
while k > 0 do
if x[k] < n then
x[k] x[k] + 1;
if y[x[k]] = 0 then
if k = n then
AFISARE(x, n);
k k 1;
y[x[k]] 0;
else
y[x[k]] 1;
k k + 1;
x[k] 0;
else
k k 1;
y[x[k]] 0;
Functia de afisare este aceeasi ca n algoritmul anterior.
Observatia 3.5.6. Pentru generarea permutarilor unei multimi arbitrare A =
{a1 , a2 , . . . , an } nlocuim afisarea indicilor (x1 , . . . , xn ) cu afisarea elementelor
corespunzatoare (ax1 , . . . , axn ).

TEMA 3. METODA BACKTRACKING

3.5.7

98

Combin
ari

Propozitia 3.5.6 (de num


arare a combin
arilor). Fie m, n N. Atunci
numarul de cuvinte strict crescatoare de lungime n peste un alfabet (ordonat) cu m litere
= numarul 
de submult
imi cu n elemente ale unei multimi cu m elemente

[m]n def m
.
=
=
n
n!
Demonstratie. Fie A = {1, 2, . . . , m}. Notam multimile din enunt astfel:
C3 = {(c1 , c2 , . . . , cn )|ci A i, ci < ci+1 i}, S3 = {S|S A, card (S) = n}.
Intre aceste multimi definim functiile : C3 S3 , : S3 C3 prin:
(c1 , c2 , . . . , cn ) C3 , (c1 , c2 , . . . , cn ) = {c1 , c2 , . . . , cn };
{c1 , c2 , . . . , cn } S3 cu c1 < c2 < . . . < cn , ({c1 , c2 , . . . , cn }) =
(c1 , c2 , . . . , cn ).
Aceste functii sunt inverse una celeilalte, deci sunt bijective si astfel
card (C3 ) = card (S3 ).
Permutand fiecare combinare (c1 , c2 , . . . , cn ) C3 n toate cele n! moduri posibile, obtinem fara repetare toate aranjamentele din multimea C1 =
{(a1 , a2 , . . . , an )|ai A i, ai 6= aj i 6= j}.
Deci card (C3 ) n! = card (C1 ). Conform Propozitiei 3.5.4, card (C1 ) = [m]n ,
[m]n
deci card (C3 ) =
.
n!
Definitia 3.5.7. Oricare obiecte din cele 2 tipuri numarate n propozitia
anterioara se numesc combin
ari(f
ar
a repetitie) de m luate cate n. De
m
, se numeste tot combin
ari (f
ar
a
asemenea si numarul lor, adica
n
n
repetitie) de m luate c
ate n si se mai noteaza cu Cm
.
 
m
= 0, deoarece [m]n = 0.
Observatia 3.5.7. Pentru n > m avem
n
m!
Pentru n m, deoarece [m]n = m(m 1) . . . (m n + 1) =
avem
(m n)!
 
m!
m
=
.
n
n!(m n)!

TEMA 3. METODA BACKTRACKING

99

Exemplul 3.5.6. Pentru m = 5 si n = 3, corespondentele din demonstratia


anterioara sunt redate n urmatorul tabel:
(c1 , c2 , c3 ) C3 S S3
(1,2,3)
{1, 2, 3}
(1,2,4)
{1, 2, 4}
(1,2,5)
{1, 2, 5}
(1,3,4)
{1, 3, 4}
(1,3,5)
{1, 3, 5}
(1,4,5)
{1, 4, 5}
(2,3,4)
{2, 3, 4}
(2,3,5)
{2, 3, 5}
(2,4,5)
{2, 4, 5}
(3,4,5)
{3, 4, 5}.
 
[5]3
5
543
=
Deci avem
=
= 10 combinari.
3
3!
123
Algoritmul 3.5.8 (de generare a combin
arilor prin metoda Backtracking). Fie multimea standard A = {1, 2, . . . , m} si n m.
Vom utiliza metoda Backtracking. Fie solutia (combinarea)
x = (x1 , x2 , . . . , xn ).
Conditiile interne:
1 x1 < x2 < < xn1 < xn m,
deci
xn m, xn1 m 1, xn2 m 2, . . . , x2 m n + 2, x1 m n + 1.
Astfel
x1 S1 = {1, 2, . . . , m n + 1},
x2 S2 = {x1 + 1, x1 + 2, . . . , m n + 2},
...
xk Sk = {xk1 + 1, xk1 + 2, . . . , m n + k},
...
xn Sn = {xn1 + 1, xn1 + 2, . . . , m}.
Asadar, multimile Sk , contin termeni succesivi ai unei progresii aritmetice, n care

ak = xk1 + 1,
rk = 1,
k = 1, n,

bk = m n + k,

TEMA 3. METODA BACKTRACKING

100

considerand x0 = 0.
Prin alegerea multimilor S1 , S2 , . . . , Sn am eliminat verificarea conditiilor
de continuare.

COMBINARI(m,
n) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < m n + k then
x[k] x[k] + 1;
if k = n then
AFISARE(x, n);
else
k k + 1;
x[k] x[k 1];
else
k k 1;

Functia de afisare este, din nou:


AFISARE(x, n) :
for i = 1, n do
afiseaz
a x[i];
Observatia 3.5.8. Analog Observatiei 3.5.6, algoritmul anterior poate fi usor
adaptat pentru generarea combinarilor pentru multimi oarecare.

3.5.8

Combin
ari cu repetitie

Propozitia 3.5.7 (de num


arare a combin
arilor cu repetitie). Fie
m, n N. Atunci numarul de cuvinte crescatoare
lungime n peste un
 de
[m]n def m
.
=
alfabet (ordonat) cu m litere este egal cu
n
n!
Demonstratie. Fie B = {1, 2, . . . , m}, A = {1, 2, . . . , m + n 1},
C4 = {(c1 , c2 , . . . , cn )|ci B i, ci ci+1 i}
C3 = {(d1 , d2 , . . . , dn )|di A i, di < di+1 i}.
Definim corespondentele : C4 C3 , : C3 C4 astfel:
(c1 , c2 , c3 , . . . , cn ) = (c1 , c2 + 1, c3 + 2, . . . , cn + n 1);
(d1 , d2 , d3 , . . . , dn ) = (d1 , d2 1, d3 2, . . . , dn n + 1).

TEMA 3. METODA BACKTRACKING

101

Acestea sunt functii inverse,


deci 
utilizand Propozitia 3.5.6 avem 

[m + n 1]n
[m]n
m+n1
m
=
card (C4 ) = card (C3 ) =
.
=
=
n
n
n!
n!
Definitia 3.5.8. Cuvintele numarate n propozitia anterioara se numesc
combin
cu repetitie de m luate cate n. De asemenea si numarul lor,
ari
m
, se numeste tot combin
ari cu repetitie de m luate c
ate
adica
n
n.
Exemplul 3.5.7. Pentru m = 3 si n = 4, combinarile cu repetitie sunt, n
ordine lexicografica:
(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 2, 2), (1, 1, 2, 3),
(1, 1, 3, 3), (1, 2, 2, 2), (1, 2, 2, 3), (1, 2, 3, 3), (1, 3, 3, 3),
(2, 2, 2, 2), (2, 2, 2, 3), (2, 2, 3, 3), (2, 3, 3, 3), (3, 3, 3, 3).
 
[3]4
3456
3
=
Deci avem
=
= 15 combinari cu repetitie.
4
4!
1234
Algoritmul 3.5.9 (de generare a combin
arilor cu repetitie prin metoda
Backtracking). Fie multimea standard A = {1, 2, . . . , m} si n 1.
Vom utiliza metoda Backtracking. Fie solutia (combinarea cu repetitie)
x = (x1 , x2 , . . . , xn ).
Conditiile interne:
1 x1 x2 xn1 xn m.
Astfel
x1 S1 = {1, 2, . . . , m},
x2 S2 = {x1 , x1 + 1, . . . , m},
...
xk Sk = {xk1 , xk1 + 1, . . . , m},
...
xn Sn = {xn1 , xn1 + 1, . . . , m}.
Asadar, multimile Sk , contin termeni succesivi ai unei progresii aritmetice, n care

ak = xk1 ,
rk = 1,
k = 1, n,

bk = m,

TEMA 3. METODA BACKTRACKING

102

considerand x0 = 1.
Prin alegerea multimilor S1 , S2 , . . . , Sn am eliminat verificarea conditiilor
de continuare.

COMBINARI
CU REPETIT
IE(m, n) :
k 1;
x[1] 0;
while k > 0 do
if x[k] < m then
x[k] x[k] + 1;
if k = n then
AFISARE(x, n);
else
k k + 1;
x[k] x[k 1] 1;
else
k k 1;

Functia de afisare este, din nou:


AFISARE(x, n) :
for i = 1, n do
afiseaz
a x[i];
Observatia 3.5.9. Analog Observatiei 3.5.6, algoritmul anterior poate fi usor
adaptat pentru generarea combinarilor cu repetitie pentru multimi oarecare.

3.5.9

Permut
ari cu repetitie

Propozitia 3.5.8 (de num


arare a permut
arilor cu repetitie). Fie
m, t1 , t2 , . . . , tm N si n = t1 + t2 + + tm . Atunci numarul de cuvinte
de lungime n ce pot fi formate peste un alfabet cu m litere astfel ncat litera
numarul i sa apar
ti ori pentru orice i {1, . . . , m} este egal cu
 a de exact 
n
n!
def
.
=
t1 , t2 , . . . , tm
t1 !t2 ! . . . tm !
Demonstratie. Fie A = {1, 2, . . . , m} si
C5 = {(x1 , x2 , . . . , xn )|xi A i, card ({i|xi = j}) = tj j}.
Numaram cuvintele din C5 astfel:

alegem
 cei t1 indici (din totalul de n) ai literelor egale cu 1, rezulta
n
moduri posibile;
t1

TEMA 3. METODA BACKTRACKING

103

pentru fiecare alegere de mai sus, alegem


 cei t2 indici (din restul de
n t1
moduri posibile, deci
n t1 ) ai literelor egale cu 2, rezulta
t2

 
n t1
n
moduri posibile de alegere a indicilor literelor
obtinem
t2
t1
1 si 2;
...
pentru fiecare alegere de mai sus, alegem cei tm indici (din restul de

n t1 . . . tm1
nt1 . . .tm1 ) ai literelor egale cu m; rezulta
tm
moduri posibile, deci obtinem

 
 
n t1 . . . tm1
n t1
n
...
tm
t2
t1
moduri posibile de alegere a tuturor indicilor literelor 1, 2, . . . , m.
Astfel

 
 
n t1 . . . tm1
n t1
n
...
card (C5 ) =
tm
t2
t1
n!
(n t1 )!
(n t1 . . . tm1 )!
=

...
t1 !(n t1 )! t2 !(n t1 t2 )!
tm !(n t1 . . . tm )!
n!
=
t1 !t2 ! . . . tm !
(deoarece (n t1 . . . tm )! = 0! = 1).
Definitia 3.5.9. Cuvintele numarate n propozitia anterioara se numesc
permut
ari cu repetitie (anagrame)
de nluate cate t1 , t2 , . . . , tm . De

n
, se numeste tot permut
ari
asemenea si numarul lor, adica
t1 , t2 , . . . , tm
cu repetitie de n luate c
ate t1 , t2 , . . . , tm .
Observat
ia 3.5.10. Luand t1 = t2 = = tm = 1 obtinem n = m si

n
= n!, deci permutarile (fara repetitie) sunt un caz particu1, 1, . . . , 1
lar
permutarilor cu repetitie. Pe de alta parte, luand m = 2 obtinem
 al 
n!
n
=
, deci si combinarile (fara repetitie) sunt un caz particular
t1 , t2
t1 !t2 !
al permutarilor cu repetitie.

TEMA 3. METODA BACKTRACKING

104

Exemplul 3.5.8. Pentru m = 3 si t1 = 2, t2 = t3 = 1, deci n = 4, permutarile


cu repetitie sunt, n ordine lexicografica:
(1, 1, 2, 3), (1, 1, 3, 2), (1, 2, 1, 3), (1, 2, 3, 1), (1, 3, 1, 2), (1, 3, 2, 1),
(2, 1, 1, 3), (2, 1, 3, 1), (2, 3, 1, 1), (3, 1, 1, 2), (3, 1, 2, 1), (3, 2, 1, 1).


4!
4
=
Deci avem
= 12 permutari cu repetitie.
2, 1, 1
2!1!1!
Algoritmul 3.5.10 (de generare a permut
arilor cu repetitie prin metoda Backtracking, varianta 1). Fie multimea standard A = {1, 2, . . . , m},
t1 , t2 , . . . , tm N si n = t1 + t2 + + tm .
Vom utiliza metoda Backtracking. Avem
x = (x1 , x2 , . . . , xn ) S1 S2 Sn ,
unde
S1 = S2 = = Sn = A.
Asadar, multimile Sk , contin termeni succesivi ai unei progresii aritmetice, n care

ak = 1,
rk = 1, k = 1, n.

bk = m,
Conditiile interne:

card ({i|i = 1, n, xi = j}) = tj j = 1, m.


Conditiile de continuare:
Daca avem solutia partiala (x1 , . . . , xk1 ), atunci xk verific
a conditiile de
continuare daca
card ({i|i = 1, k 1, xi = xk }) < txk .

TEMA 3. METODA BACKTRACKING

105

CU REPETIT
IE1(n, t, m) :
PERMUTARI
n 0;
for i = 1, m do n n + t[i];
k 1;
x[1] 0;
while k > 0 do
if x[k] < m then
x[k] x[k] + 1;
p t[x[k]];
if VALID(p, x, k) then
if k = n then
AFISARE(x, n);
k k 1;
// fort

am revenirea, deoarece
// nu mai exist
a valori valide pentru x[n]
else
k k + 1;
x[k] 0;
else
k k 1;
VALID(p, x, k) :
// p = t[x[k]]
q 0;
// q reprezint
a card ({i|i = 1, k 1, x[i] = x[k]})
if p = 0 then returneaz
a 0;
for i = 1, k 1 do
if x[i] = x[k] then
q q + 1;
if q p then returneaz
a 0;
returneaz
a 1;

Functia de afisare este, din nou:


AFISARE(x, n) :
for i = 1, n do
afiseaz
a x[i];
Algoritmul 3.5.11 (de generare a permut
arilor cu repetitie prin metoda Backtracking, varianta 2). Putem mbunatati algoritmul anterior
prin utilizarea unui vector (y1, y2 , . . . , ym ) cu semnificatia: daca avem solutia
partiala (x1 , . . . , xk1 ), atunci
yj = card ({i|i = 1, k 1, xi = j}), j = 1, m.

TEMA 3. METODA BACKTRACKING

106

Astfel xk verifica conditiile de continuare daca si numai daca


yxk < txk .
Fortand din nou revenirea dupa determinarea fiecarei permutari cu repetitie,
obtinem urmatorul algoritm.

PERMUTARI
CU REPETIT
IE2(n, t, m) :
n 0;
for i = 1, m do n n + t[i];
for i = 1, m do y[i] 0;
// init
ial, solut
ia part
ial
a este
// vectorul vid
k 1;
x[1] 0;
while k > 0 do
if x[k] < m then
x[k] x[k] + 1;
if y[x[k]] < t[x[k]] then
// x[k] verific
a condit
iile
// de continuare
if k = n then
AFISARE(x, n);
k k 1;
y[x[k]] y[x[k]] 1; // dup
a fort
area revenirii,
// se elimin
a x[k] din solut
ia part
ial
a
else
y[x[k]] y[x[k]] + 1;
// ^
nainte de avansare, se
// adaug
a x[k] la solut
ia part
ial
a
k k + 1;
x[k] 0;
else
k k 1;
y[x[k]] y[x[k]] 1;

// dup
a revenire, se elimin
a
// x[k] din solut
ia part
ial
a

Functia de afisare este aceeasi ca n algoritmul anterior.


Observatia 3.5.11. Analog Observatiei 3.5.6, algoritmul anterior poate fi usor
adaptat pentru generarea permutarilor cu repetitie pentru multimi arbitrare.

Tema 4
Metoda Divide et Impera
4.1

Descrierea metodei. Algoritmi generali

Metoda Divide et Impera (mparte si st


ap
aneste) este o metoda generala de elaborare a algoritmilor care implica trei etape:
Divide: Problema data este mpartita n doua sau mai multe subprobleme de acelasi tip, dar de dimensiuni mai mici.
Impera: Stapaneste subproblemele obtinute. Subproblemele se rezolva direct, daca dimensiunea lor permite aceasta (cazuri elementare),
sau, fiind de acelasi tip, se rezolva n mod recursiv, prin acelasi procedeu.
Combin
a: Se combina solutiile tuturor subproblemelor, pentru a obtine
solutia problemei initiale.
In continuare prezentam o schema generala de lucru.
Algoritmul 4.1.1 (Metoda Divide et Impera).
Fie P (n) o problema de dimensiune n N . Presupunem ca exista n0
N , a N, a 1 si b R, b > 1 astfel ncat:
n N cu n n0 , rezolvarea problemei P (n) se poate face direct,
fara descompunere.
n
, i = 1, a,
b
astfel ncat rezolvarea problemei P (n) se poate face rezolvand succesiv
a subprobleme de acelasi tip

n N cu n > n0 , m1 , . . . , ma N cu mi

P (m1 ), . . . , P (ma )
107

TEMA 4. METODA DIVIDE ET IMPERA

108

dupa care, combinand solutiile celor a subprobleme, se obtine solutia


dorita a ntregii probleme P (n).
Algoritmul poate fi descris recursiv astfel:
DIVIMP(n, S) :
// Rezolvarea problemei P (n)
if n n0 then
PRELUCREAZA(n, S);
// Rezolvarea se face direct,
// rezult^
and solut
ia S a problemei P (n)
else
DESCOMPUNERE(n, a, m);
// Se descompune problema,
// adic
a se determin
a m1 , . . . , ma
for i = 1, a do
DIVIMP(mi , si );
// Se obt
ine solut
ia si pentru
// subproblema P (mi )
COMBINA(s, a, S);
// Se combin
a solut
iile s1 , . . . , sa ,
// rezult^
and solut
ia S a problemei P (n)
Observatia 4.1.1. Pentru orice i = 1, a avem
mi

n
<n
b

(deoarece b > 1), adica subproblemele P (m1 ), . . . , P (ma ) au dimensiuni mai


mici decat problema mare P (n).
In continuare prezentam o schema particulara de lucru.
Algoritmul 4.1.2 (Metoda Divide et Impera, variant
a vectorial
a).
Fie A = (a1 , a2 , . . . , an ), n N , un vector asupra componentelor caruia
trebuie efectuata o prelucrare. Presupunem ca exista N astfel ncat:
p, q {1, 2, . . . , n} cu q p , prelucrarea secventei (ap , . . . , aq ) se
poate face direct, fara descompunere.
p, q {1, 2, . . . , n} cu q p > , m {p, . . . , q 1} astfel ncat
prelucrarea secventei
(ap , . . . , aq )
se poate face prelucrand succesiv subsecventele
(ap , . . . , am ) si
(am+1 , . . . , aq ),
dupa care, combinand rezultatele celor doua prelucrari, se obtine prelucrarea dorita a ntregii secvente (ap , . . . , aq ).

TEMA 4. METODA DIVIDE ET IMPERA

109

Algoritmul poate fi descris recursiv astfel:


DIVIMP(p, q, S) :
// Prelucrarea secvent
ei (ap , . . . , aq )
if q p then
PRELUCREAZA(p, q, S); // Prelucrarea se face direct,
// rezult^
and solut
ia S a secvent
ei (ap , . . . , aq )
else
DESCOMPUNERE(p, q, m);
// Se descompune problema,
// adic
a se determin
a m
DIVIMP(p, m, S1);
// Se obt
ine solut
ia S1 pentru
// subsecvent
a (ap , . . . , am )
DIVIMP(m + 1, q, S2);
// Se obt
ine solut
ia S2 pentru
// subsecvent
a (am+1 , . . . , aq )
COMBINA(S1 , S2 , S);
// Se combin
a solut
iile S1 s
i S2 ,
// rezult^
and solut
ia S a secvent
ei (ap , . . . , aq )
Procedura trebuie apelata prin:
DIVIMP(1, n, S).
In acest algoritm:
reprezinta lungimea maxima a unei secvente (ap , . . . , aq ), notata prescurtat prin (p, q), pentru care prelucrarea se poate face direct, fara a
mai fi necesara mpartirea n subprobleme; procedura
PRELUCREAZA(p, q, S)
realizeaza prelucrarea secventelor de acest tip, furnizand rezultatul n
S.
Procedura

COMBINA(S1 , S2 , S)

realizeaza combinarea rezultatelor S1 , S2 ale prelucrarii celor doua subsecvente vecine (p, m) si (m + 1, q), obtinandu-se rezultatul S al prelucrarii secventei (p, q).
Valoarea m este obtinuta apeland procedura
DESCOMPUNERE(p, q, m).

TEMA 4. METODA DIVIDE ET IMPERA

4.2

110

Complexitatea metodei. Teorema Master

Definitia 4.2.1. Pentru orice numar real x, notam cu


x = [x] = max{k Z | k x}
partea ntreag
a inferioar
a (pe scurt, partea ntreag
a) a lui x, iar cu
x = min{k Z | k x}
partea ntreag
a superioar
a a lui x.
Observatia 4.2.1. Pentru orice x R avem x = x.

Definitia 4.2.2. Un arbore binar este un arbore cu radacina, reprezentat


pe nivele, n care fiecare nod x are cel mult doi descendenti (fii, succesori
directi situati pe nivelul urmator) si anume (cel mult) un descendent st
ang
(situat n stanga lui x) si (cel mult) un descendent drept (situat n dreapta
lui x), contand ordinea dintre acestia.
Nodurile cu cel putin un descendent se numesc interne (interioare),
iar nodurile fara descendenti se numesc externe (exterioare, frunze).
Definitia 4.2.3. Fie T = (V, F ) un arbore binar avand radacina r, r V .
a) Notam cu I(T ) multimea nodurilor interne si cu E(T ) multimea
nodurilor externe ale arborelui binar T .
b) Pentru orice nod x V , distanta de la nodul r
ad
acin
a r la nodul
x, notata cu DT (x) = D(x), reprezinta lungimea lantului elementar
unic de la r la x.
c) Numarul
h(T ) = max{DT (x) | x V }
se numeste n
altimea arborelui binar T .
Observatia 4.2.2. Fie T = (V, F ) un arbore binar. Evident, avem
V = I(T ) E(T ), I(T ) E(T ) = , E(T ) 6=
si
h(T ) = max{DT (x) | x E(T )}.
Deci
h(T ) = k 1,

TEMA 4. METODA DIVIDE ET IMPERA

111

unde k reprezinta numarul de nivele ale arborelui T .


Daca nivelul pe care este reprezentata radacina arborelui este numerotat
cu 0, atunci pentru orice nod x V avem
DT (x) = numarul nivelului pe care este situat nodul x,
iar naltimea arborelui T este egala cu numarului ultimului nivel al arborelui.
Definitia 4.2.4. Un arbore binar strict este un arbore binar pentru care
orice nod intern are exact doi descendenti (si anume un descendent stang si
un descendent drept).
Propozitia 4.2.1. Orice arbore binar strict cu n noduri interne, n N, are
n + 1 noduri externe.
Demonstratie. Demonstram afirmatia din enunt prin inductie dupa n.
Pentru n = 0 este evident ca arborele este format doar din nodul radacina,
deci are un singur nod si acesta este extern.
Presupunem afirmatia adevarata pentru n 1 si o demonstram pentru
n, n 1. Fie T = (V, F ) un arbore binar strict cu n noduri interne. Fie x
un nod intern al lui T situat pe penultimul nivel, deci x are ca descendenti
doua noduri externe y si z, situate pe ultimul nivel. Fie
T = T \ {y, z} = (V \ {y, z}, F \ {[x, y], [x, z]})
arborele obtinut din T prin eliminarea nodurilor externe y si z. Evident, T
ramane tot arbore binar strict si
I(T ) = I(T ) \ {x}, E(T ) = E(T ) \ {y, z} {x},
deci
card (I(T )) = card (I(T )) 1 = n 1, card (E(T )) = card (E(T )) 1.
Conform ipotezei de inductie, aplicata pentru T , rezulta ca
card (E(T )) = card (I(T )) + 1 = n,
deci
card (E(T )) = card (E(T )) + 1 = n + 1,
adica arborele T are n + 1 noduri externe. Demonstratia prin inductie este
ncheiata.

TEMA 4. METODA DIVIDE ET IMPERA

112

Propozitia 4.2.2. Pentru orice arbore binar strict T cu n noduri interne


avem
X
X
DT (v) =
DT (v) + 2n.
vE(T )

vI(T )

Demonstratie. Demonstram egalitatea din enunt prin inductie dupa n.


Pentru n = 0 este evident ca arborele T este format doar din nodul
radacina r, E(T ) = {r}, I(T ) = ,
X
X
DT (v) = DT (r) = 0,
DT (v) + 2n = 0 + 2 0 = 0,
vE(T )

vI(T )

deci egalitatea din enunt este verificata.


Presupunem egalitatea adevarata pentru n 1 si o demonstram pentru
n, n 1. Fie T = (V, F ) un arbore binar strict cu n noduri interne. Fie x
un nod intern al lui T situat pe penultimul nivel, deci x are ca descendenti
doua noduri externe y si z, situate pe ultimul nivel. Evident,
DT (y) = DT (z) = 1 + DT (x).
Fie
T = T \ {y, z} = (V \ {y, z}, F \ {[x, y], [x, z]})

arborele obtinut din T prin eliminarea nodurilor externe y si z. Evident, T


ramane tot arbore binar strict si
I(T ) = I(T ) \ {x}, E(T ) = E(T ) \ {y, z} {x},
DT (v) = DT (v), v I(T ) E(T ).

Utilizand si ipoteza de inductie, aplicata pentru T , avem


X
X
DT (v) =
DT (v) dT (x) + dT (y) + dT (z)
vE(T )

vE(T )

vI(T )

DT (v) + 2(n 1) dT (x) + 2(1 + dT (x))


DT (v) + dT (x) + 2n

vI(T )\{x}

DT (v) + 2n.

vI(T )

Demonstratia prin inductie este ncheiata.

TEMA 4. METODA DIVIDE ET IMPERA

113

Propozitia 4.2.3. Pentru orice arbore binar strict T cu n noduri interne


avem
h(T ) log2 (n + 1) .
Demonstratie. Consideram ca nivelul pe care este reprezentata radacina arborelui este numerotat cu 0. Arborele T este un arbore binar strict, cu 2n+ 1
noduri (n interne si n + 1 externe), iar pe fiecare nivel i {0, 1, . . . , h(T )} el
are cel mult 2i noduri, deci
2n + 1 1 + 2 + 22 + + 2h(T )

2n + 1 2h(T )+1 1 2h(T ) n + 1 h(T ) log2 (n + 1).


Cum h(T ) N, deducem ca h(T ) log2 (n + 1) .
Observatia 4.2.3. Pentru orice n N are loc egalitatea
log2 (n + 1) = 1 + log2 n .
Intr-adevar, notand log2 (n + 1) = k, k N , avem, succesiv,
k 1 < log2 (n + 1) k; 2k1 < n + 1 2k ;
2k1 n < 2k ; k 1 log2 n < k,

deci log2 n = k 1 = log2 (n + 1) 1.

Propozitia 4.2.4. Fie T un arbore binar strict cu n noduri interne. Daca


toate nodurile externe sunt situate pe ultimul si, eventual, pe penultimul nivel,
atunci
h(T ) = log2 (n + 1)

si

vE(T )

DT (v) = (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) .

Demonstratie. Consideram din nou ca nivelul pe care este reprezentata radacina arborelui este numerotat cu 0. Rezulta ca:
arborele are h(T ) nivele;
pe nivelele 0, 1, . . . , h(T ) 2 avem doar noduri interne, fiecare avand
cate doi descendenti;
pe penultimul nivel, h(T )1, putem avea si noduri externe, iar nodurile
interne de pe acest nivel au de asemenea cate doi descendenti;

114

TEMA 4. METODA DIVIDE ET IMPERA


pe ultimul nivel, h(T ), avem doar noduri externe;

pentru orice i {0, 1, . . . , h(T ) 1} pe nivelul i avem exact 2i noduri.

Notand cu a numarul de noduri interne de pe penultimul nivel si cu b numarul


de noduri externe de pe acelasi nivel, obtinem ca
a + b = 2h(T )1

(4.2.1)

(numarul total de noduri de pe penultimul nivel, nivelul h(T ) 1), iar


a1

(pe penultimul nivel exista cel putin un nod intern).


Pe nivelele 0, 1, . . . , h(T )2 nu avem noduri externe, pe penultimul nivel,
h(T ) 1, avem b noduri externe, iar pe ultimul nivel, h(T ), avem 2a noduri
externe (si anume descendentii celor a noduri interne de pe penultimul nivel),
deci numarul total de noduri externe ale arborelui este egal cu b+2a. Rezulta
ca
b + 2a = n + 1,
(4.2.2)
si

vE(T )

DT (v) = b(h(T ) 1) + 2a h(T ).

(4.2.3)

Din relatiile (4.2.1) si (4.2.2) obtinem ca


a = n + 1 2h(T )1 .

Dar 1 a 2h(T )1 (a doua inegalitate rezulta din (4.2.1)), deci


Rezulta ca

1 n + 1 2h(T )1 2h(T )1 .

2h(T )1 n < n + 1 si 2h(T ) n + 1,

deci

h(T ) 1 < log2 (n + 1) h(T )

si astfel h(T ) = log2 (n + 1) .


Conform (4.2.3), (4.2.2) si (4.2.4) obtinem ca
X
DT (v) = (n + 1 2a)(h(T ) 1) + 2a h(T )
vE(T )

= (n + 1)h(T ) + 2a n 1


= (n + 1)h(T ) + 2 n + 1 2h(T )1 n 1

= (n + 1)h(T ) + n + 1 2h(T )

= (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) .

(4.2.4)

TEMA 4. METODA DIVIDE ET IMPERA

115

Propozitia 4.2.5. Pentru orice arbore binar strict T cu n noduri interne


avem
X
DT (v) (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) .
vE(T )

Mai mult, egalitatea are loc daca si numai daca toate nodurile externe sunt
situate pe ultimul si, eventual, pe penultimul nivel.
Demonstratie. Notam
M = {T | T = arbore binar strict, card (I(T )) = n},
X
S(T ) =
DT (v), T M.
vE(T )

Fie T M, T = (V, F ), a..


S(T ) = min{S(T ) | T M}.
Consideram din nou ca nivelul pe care este reprezentata radacina arborelui este numerotat cu 0.
Demonstram ca arborele T nu are noduri externe pe nivelele 0,1, . . . ,
h(T ) 2 prin reducere la absurd. Sa presupunem ca arborele T ar avea un
nod extern x pe un nivel i, cu i h(T ) 2. Fie y un nod intern al lui T
situat pe penultimul nivel, nivelul h(T ) 1, si fie y1 si y2 cei doi descendenti
ai lui y, deci y1 si y2 sunt noduri externe situate pe ultimul nivel, nivelul
h(T ). Evident,
DT (x) = i, DT (y) = h(T ) 1, DT (y1 ) = DT (y2 ) = h(T ).
Fie T arborele obtinut din T prin mutarea nodurilor y1 si y2 de la
descendenti ai nodului y la descendenti ai nodului x, adica
T = (V, F \ {[y, y1], [y, y2]} {[x, y1 ], [x, y2 ]}).
Evident, T ramane un arbore binar strict, T M,
E(T ) = E(T ) \ {x} {y},
DT (y1) = DT (y2 ) = i + 1,
DT (v) = DT (v), v E(T ) \ {y1 , y2 },

TEMA 4. METODA DIVIDE ET IMPERA

116

Avem
S(T ) S(T ) =

vE(T )

DT (v)

DT (v)

vE(T )

= DT (y) + DT (y1 ) + DT (y2 ) DT (x) DT (y1 ) DT (y2 )


= h(T ) 1 + 2(i + 1) i 2h(T )
= i + 1 h(T ) < 0,
deci S(T ) < S(T ), ceea ce contrazice alegerea lui T . Demonstratia prin
reducere la absurd este ncheiata.
Deoarece arborele T nu are noduri externe pe nivelele 0,1, . . . , h(T )2,
rezulta ca toate nodurile sale externe sunt situate pe ultimul si, eventual, pe
penultimul nivel. Conform Propozitiei 4.2.4 rezulta ca
s(T ) = (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) ,
deci
min{S(T ) | T M} = (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) ,
de unde rezulta inegalitatea din enunt. Mai mult, daca toate nodurile externe
sunt situate pe ultimul si, eventual, pe penultimul nivel atunci, conform
Propozitiei 4.2.4, inegalitatea din enunt devine egalitate, iar n caz contrar,
conform demonstratiei prin reducere la absurd de mai sus, inegalitatea este
stricta.
Observatia 4.2.4. In contextul Algoritmului 4.1.1, timpul de executie T (n)
pentru rezolvarea problemei P (n) verifica relatia

tn ,
daca n n0 ,
a
P
T (n) =
(4.2.5)
T (mi ) + f (n), daca n > n0 ,

i=1

unde:

pentru n n0 , tn reprezinta timpul de executie necesar rezolvarii directe a problemei, adica timpul de executie al procedurii PRELUCREAZA(n, S);
pentru n > n0 , f (n) reprezinta timpul total de executie necesar descompunerii problemei n subprobleme si combinarii solutiilor acestor subprobleme, adica suma timpilor de executie ai procedurilor DESCOMPUNERE(n, a, m) si COMBINA(s, a, S).

117

TEMA 4. METODA DIVIDE ET IMPERA

Adesea subproblemele P (m1 ), P (m2 ), . . . , P (ma ), obtinute la descompunerea problemei P (n), au dimensiuni egale
nj n k l n mo
m1 = m2 = = ma
,
,
(4.2.6)
b
b
sau, mai general, aproape egale.

m1 , m2 , . . . , ma

nj n k l n mo
,
,
b
b

(4.2.7)

In acest caz, conform (4.2.5) rezulta ca timpul de executie T (n) pentru


rezolvarea problemei P (n) verifica relatia de recurenta
j n k
l n m
+ a2 T
+ f (n), n > n0 ,
T (n) = a1 T
b
b

unde

a1 = card

i = 1, a | mi =

j n ko
b

, a2 = card

n
l n mo
i = 1, a | mi =
,
b

a1 + a2 = a.
Observatia 4.2.5. Relatia de recurenta anterioara poate fi scrisa sub forma
T (n) = T (n/b) + + T (n/b) +f (n), n > n0 ,
{z
}
|
a termeni

jnk
lnm
unde, prin conventie, fiecare termen n/b reprezinta fie
, fie
.
b
b
Mai mult, prin abuz de notatia de nmultire, aceasta relatie este conventional rescrisa prescurtat sub forma
T (n) = aT (n/b) + f (n), n > n0 .
Urmatorul rezultat prezinta o metoda generala pentru rezolvarea acestei
relatii de recurenta.
Teorema 4.2.1 (Teorema Master). Fie T : N R o functie ce verific
a
relatia de recurenta
T (n) = aT (n/b) + f (n), n > n0

(4.2.8)

din Observatia 4.2.5 (cu conventiile de notatie stabilite acolo), unde n0 N,


a N, a 1, b R, b > 1 si f este o functie asimptotic pozitiva.
Cazul 1. Daca f (n) = O (nc ), cu c < logb a, atunci
T (n) = (nlogb a ).

TEMA 4. METODA DIVIDE ET IMPERA

118

Cazul 2. Daca f (n) = (nc logk2 n), cu c = logb a si k 0, atunci


n).
T (n) = (nlogb a logk+1
2
Cazul 3. Daca f (n) = (nc ), cu c > logb a, si exista k < 1 si n1 N
astfel ncat af (n/b) kf (n) n n1 , atunci
T (n) = (f (n)).

4.3

Problema turnurilor din Hanoi

Problema turnurilor din Hanoi este urmatoarea:


Se considera trei tije notate cu 1, 2, 3 si n 1 discuri perforate de diametre
diferite. Initial, toate discurile se afla pe tija 1, n ordinea crescatoare a
diametrelor, considerand sensul de la varf catre baza.
Se cere mutarea discurilor pe tija 2, n aceeasi ordine, utilizand tija 3 si
respectand urmatoarele reguli:
la fiecare pas se muta un singur disc;
nu este permisa asezarea unui disc peste unul cu diametru mai mic.

Modelarea problemei
Vom nota o mutare cu perechea (i, j), ceea ce semnifica faptul ca se muta un
disc de pe tija i pe tija j (i, j {1, 2, 3}).
Daca n = 1, solutia directa este mutarea (1, 2).
Daca n = 2, o solutie este formata din mutarile (1, 3), (1, 2), (3, 2).

TEMA 4. METODA DIVIDE ET IMPERA

119

Daca n > 2, problema se complica.


Notam cu H(m, i, j) sirul mutarilor necesare pentru a muta primele m
discuri de pe tija i pe tija j, folosind pentru manevre cealalta tija k := 6ij.
(Avem i + j + k = 1 + 2 + 3 = 6.)
Rezulta ca, pentru problema noastra, avem de determinat sirul H(n, 1, 2).
Avem

(i, j),
daca m = 1,
H(m, i, j) =
H(m 1, i, k), (i, j), H(m 1, k, j), daca m 2.

Asadar, pentru m 2, mutarea a m discuri de pe tija i pe tija j este


echivalenta cu:
mutarea a m 1 discuri de pe tija i pe tija k = 6 i j, utilizand
pentru manevre tija j;
mutarea discului ramas de pe tija i pe tija j;
mutarea celor m 1 discuri de pe tija k pe tija j, utilizand pentru
manevre tija i.
Deci rezolvarea unei probleme de dimensiune m 2 se reduce la rezolvarea
a trei probleme, de acelasi tip, dar de dimensiuni mai mici:
doua de dimensiune m 1, care se vor rezolva, recursiv, n acelasi mod;
una de dimensiune 1, care se rezolva direct.
Obtinem urmatorul algoritm Divide et Impera, descris n pseudocod, pentru
rezolvarea problemei.

TEMA 4. METODA DIVIDE ET IMPERA


Algoritmul 4.3.1.
HANOI(m, i, j) :
if m = 1 then
afiseaz
a(i, j);
else
k 6 i j;
HANOI(m 1, i, k);
afiseaz
a(i, j);
HANOI(m 1, k, j);

120

// se afi
seaz
a mutarea (i, j)

// se afi
seaz
a mutarea (i, j)

Procedura trebuie apelata prin:


HANOI(n, 1, 2).
Observatia 4.3.1. Pentru evaluarea complexitatii algoritmului anterior, notam cu M(n) numarul de mutari necesare (afisate). Avem
M(n) =
=

1,
daca n = 1,
M(n 1) + 1 + M(n 1), daca n 2,
1,
daca n = 1,
2 M(n 1) + 1, daca n 2.

Rescriind aceasta relatie de recurenta sub forma


M(n) + 1 = 2(M(n 1) + 1), n 2,
obtinem ca sirul (M(n) + 1)n1 este o progresie geometrica avand ratia 2 si
primul termen M(1) + 1 = 2, deci M(n) + 1 = 2n , n 1 si astfel se obtine
ca
M(n) = 2n 1, n 1.
Rezulta ca timpul de executie al algoritmului este
T (n) = (2n ),
deci algoritmul este exponential.
Propozitia 4.3.1. Orice algoritm care rezolva problema turnurilor din Hanoi
necesita cel putin 2n 1 mutari.
Demonstratie. Demonstram afirmatia din enunt prin inductie dupa n N .
Pentru n = 1, este evident ca numarul de mutari necesare este de cel
putin 1 = 21 1.
Presupunem afirmatia adevarata pentru n 1 si o demonstram pentru
n, n 2. Intr-adevar, pentru orice rezolvare a problemei, sunt necesare cel
putin urmatoarele subetape:

TEMA 4. METODA DIVIDE ET IMPERA

121

o mutare a discului n (cel mai mare) de pe tija 1 pe o alta tija i;


aceasta mutare trebuie obligatoriu precedata de mutarea primelor n1
discuri de pe tija 1 pe tija ramasa 6 1 i, deci, conform ipotezei de
inductie sunt necesare cel putin 2n1 1 mutari;
o mutare a discului n (cel mai mare) de pe o tija j 6= 2 pe tija 2, mutare
ce poate sa coincida cu mutarea descrisa la prima subetapa;
aceasta mutare trebuie obligatoriu urmata de mutarea primelor n 1
discuri de pe tija ramasa 6 2 j pe tija 2 , deci, conform ipotezei de
inductie sunt necesare nca cel putin 2n1 1 mutari.
Astfel numarul total de mutari necesare este de cel putin
1 + 2(2n1 1) = 2n 1.
Urmatorul rezultat este o consecinta directa a Observatiei 4.3.1 si propozitei
anterioare.
Propozitia 4.3.2. Algoritmul 4.3.1 este optim.

4.4

C
autarea binar
a

Problema c
aut
arii este urmatoarea:
Se considera un vector A = (a1 , a2 , . . . , an ), n 1, si o valoare x. Se cere
sa se determine daca x se afla printre componentele vectorului A.
O cautare se poate ncheia:
fie cu succes, caz n care se returneaza o pozitie n vector pe care se
afla valoarea cautata;
fie f
ar
a succes, caz n care se returneaza 1.

Observatia 4.4.1. In practica, problema cautarii consta n regasirea unei


nregistrari ntr-un fisier sau baza de date dupa valoarea unui camp, numit
cheie de c
autare.
Algoritmul 4.4.1 (C
autarea binar
a).
Presupunem ca vectorul A are elementele n ordine crescatoare
a1 a2 an .
Vom utiliza metoda Divide et Impera astfel:

TEMA 4. METODA DIVIDE ET IMPERA

122

se compara x cu elementul median (din mijloc) am , unde




1+n
m=
;
2
daca am = x, atunci cautarea se termina cu succes;
daca am > x, atunci se va cauta x n subsecventa
(a1 , . . . , am1 ) ;
daca am < x, atunci se va cauta x n subsecventa
(am+1 , . . . , an ) .
Varianta recursiv
a de implementare a algoritmului de cautare binara
este descrisa n pseudocod astfel:
CAUTBIN REC(A, n, p, u, x) :
// c
autarea valorii x ^
n subsecvent
a (ap , . . . , au ) a
// vectorului (a1 , . . . , an )
if p > u then
returneaz
a 1;
else


p+u
;
m
2
if x = A[m] then
returneaz
a m;
else
if x < A[m] then
returneaz
a CAUTBIN REC(A, n, p, m 1, x);
else
returneaz
a CAUTBIN REC(A, n, m + 1, u, x);
Procedura trebuie apelata prin:
poz CAUTBIN REC(A, n, 1, n, x).
Varianta iterativ
a de implementare a algoritmului de cautare binara
este descrisa n pseudocod astfel:

TEMA 4. METODA DIVIDE ET IMPERA

123

CAUTBIN(A, n, x) :
p 1; u n;
// (ap , . . . , au ) reprezint
a subsecvent
a curent
a
// la care se restr^
ange c
autarea
while p
u
do


p+u
;
m
2
if x = A[m] then
returneaz
a m;
else
if x < A[m] then
u m 1;
else
p m + 1;
returneaz
a 1;
Procedura trebuie apelata prin:
poz CAUTBIN(A, n, x).
Observatia 4.4.2. Pentru analiza algoritmului de cautare binara, presupunem
ca la fiecare iteratie avem o singura comparatie de chei, ntre valoarea cautata
x si un element ai al vectorului, n urma careia se poate decide ce relatie de
ordine exista ntre valorile comparate.
Prezentam cateva notiuni ajutatoare.
Definitia 4.4.1. Un arbore binar de c
autare (BST - Binary Search
Tree) este un arbore binar cu proprietatea ca orice nod intern are valoarea
(cheia) mai mare decat orice nod din subarborele sau stang si mai mica decat
orice nod din subarborele sau drept.
Observatia 4.4.3. Parcurgerea n INORDINE (ST, RAD, DR) a unui arbore
de cautare corespunde parcurgerii n ordine crescatoare a valorilor (cheilor)
nodurilor sale.
Observatia 4.4.4. Fie A un algoritm de cautare, bazat pe comparatii de chei,
a unei valori x ntr-un vector sortat cu n componente A = (a1 , a2 , . . . , an ),
a1 a2 an .
Presupunem ca algoritmul nu contine instructiuni redundante si este aplicabil pentru orice pozitionare posibila a valorii x n raport cu componentele
vectorului A, deci valoarea x este comparata exact cate o data cu fiecare
componemta ai , i = 1, n.
Atunci algoritmului A i se poate asocia un arbore binar de cautare T (A)
avand n noduri, etichetate cu numerele 1, 2, . . . , n, construit recursiv astfel:

TEMA 4. METODA DIVIDE ET IMPERA

124

daca prima comparatie efectuata de algoritm este ntre valoarea cautata x si


un element ai al vectorului, atunci
radacina arborelui este etichetata cu indicele i;
subarborele stang corespunde continuarii algoritmului n cazul x < ai ,
daca acest caz este posibil dupa prima comparatie (altfel este vid, adica
nu exista descendent stang);
subarborele drept corespunde continuarii algoritmului n cazul x > ai ,
daca acest caz este posibil dupa prima comparatie (altfel este vid, adica
nu exista descendent drept).
Reciproc, oricarui arbore binar de cautare T avand n noduri, etichetate
cu numerele 1, 2, . . . , n, i corespunde un algoritm de cautare A(T ) a valorii
x n vectorul sortat A = (a1 , a2 , . . . , an ), descris recursiv n pseudocod astfel:
A(T
 ):

if T este vid then
returneaz
a 1;
// c
autare f
ar
a succes
else
i eticheta radacinii lui T ;
if x = ai then
returneaz
a i;
else
if x < ai then
Ts subarborele stang al lui T ;
returneaz
a A(Ts );
else
Td subarborele drept al lui T ;
returneaz
a A(Td );
Corespondentele A T (A) si T A(T ) de mai sus sunt bine definite si
inverse una celeilalte, deci sunt bijectii ntre multimea algoritmilor de cautare
(bazati pe comparatii de chei) a unei valori x ntr-un vector sortat cu n
componente (a1 , a2 , . . . , an ) si multimea arborilor binari de cautare avand n
noduri etichetate cu numerele 1, 2, . . . , n.
Definitia 4.4.2. Arbore binar de cautare T (A) construit n observatia anterioara se mai numeste si arborele de decizie al algoritmului de c
autare
A.
Observatia 4.4.5. Arborele de cautare asociat algoritmului de cautare binara
este un arbore binar strict.

TEMA 4. METODA DIVIDE ET IMPERA

125

Definitia 4.4.3. Fie T un arbore binar de cautare avand n noduri, etichetate


cu numerele 1, 2, . . . , n. Extindem arborele binar T la un arbore binar strict
T astfel: pentru orice k {1, 2, . . . , n}, nodul lui T avand eticheta k este
reprezentat ntr-un cerc si devine nod intern n T prin aplicarea urmatoarelor
doua reguli:
daca nodul nu are descendent stang i se adauga un descendent stang
etichetat cu k 1 si reprezentat ntr-un patrat;
daca nodul nu are descendent drept i se adauga un descendent drept
etichetat cu k si reprezentat ntr-un patrat.
Arborele T se numeste arbore binar extins de c
autare.
Exemplul 4.4.1. In Figura 4.4.1 este reprezentat arborele binar extins de
cautare asociat algoritmului cautarii binare, pentru n = 9.

Figura 4.4.1:
Observatia 4.4.6. Arborele binar extins de cautare asociat algoritmului cautarii binare ntr-un vector sortat cu n componente poate fi construit si direct
prin urmatorul procedeu recursiv:
a) daca n = 0, arborele este constituit din nodul 0 ;
b) altfel, daca n 1, atunci:


n+1
este nod r
ad
acin
a (nodul median este radacina);

2
subarborele st
ang este arborele
binar

 corespunzator cautarii
n+1
binare ntr-un vector sortat cu
1 componente;
2

TEMA 4. METODA DIVIDE ET IMPERA

126

subarborele drept este arborele


j n k binar corespunzator cautarii
binare ntr-un vector sortat cu
componente, numerele nodu
 2
n+1
rilor fiind crescute cu
.
2
Observatia 4.4.7. Pentru orice algoritm de cautare A a valorii x n vectorul
sortat A = (a1 , a2 , . . . , an ), arborele binar extins de cautare asociat T =
T (A) este un arbore binar strict ce are
n noduri interne, etichetate cu numerele 1, 2, . . . , n reprezentate n cercuri si
n + 1 noduri externe, etichetate cu numerele 0, 1, 2, . . . , n reprezentate
n patrate,
avand semnificatia urmatoare:
pentru orice i {1, 2, . . . , n}, nodul intern etichetat cu i reprezinta
comparatia valorii cautate, x, cu elementul ai din vectorul sortat;
pentru orice i {0, 1, 2, . . . , n}, nodul extern etichetat cu i reprezinta
ncheierea fara succes a procesului de cautare, corespunzatoare situatiei:
x < a1 ,
daca i = 0,
ai < x < ai+1 , daca 1 i n 1,
x > an ,
daca i = n.
Observatia 4.4.8. In contextul observatiei anterioare, avem:
La o cautare cu succes, x = ai , numarul de comparatii de chei este egal
cu numarul de noduri (interne) care se gasesc pe lantul care uneste
nodul radacina cu nodul intern i, adica este mai mare cu 1 decat
lungimea acestui lant.
La o cautare fara succes, numarul de comparatii de chei este egal cu
numarul de noduri interne care se gasesc pe lantul care uneste nodul
radacina cu nodul extern care reprezinta sfarsitul procesului de cautare,
adica cu lungimea acestui lant.
Exemplul 4.4.2. .Pentru algoritmul de cautare binara, n = 9 si vectorul sortat
A = (2, 6, 12, 14, 16, 18, 20, 25, 50),

TEMA 4. METODA DIVIDE ET IMPERA

127

cautarea valorii x = 13 necesita 4 comparatii de chei, puse n evidenta de


lantul care uneste radacina, etichetata cu 5, cu nodul extern etichetat cu 3
din arborele binar extins de cautare asociat, reprezentat n Figura 4.4.2.

Figura 4.4.2:
Observatia 4.4.9. In cazul unei cautari fara succes, eticheta nodului extern n
care se ajunge, poate determina pozitia pe care ar trebui inserata n vector
valoarea cautata, astfel ncat vectorul sa ramana n continuare sortat.
Propozitia 4.4.1 (complexitatea algoritmilor de c
autare). Pentru orice
algoritm de cautare A, bazat pe comparatii de chei, a valorii x n vectorul
sortat A = (a1 , a2 , . . . , an ) avem:
1) numarul de comparatii de chei efectuate n cazul cel mai defavorabil
este mai mare sau egal cu
log2 (n + 1) ;
2) numarul mediu de comparatii de chei efectuate este mai mare sau egal

cu

n + 2 2 2log2 (n+1)
2n + 2
log2 (n + 1) +
.
2n + 1
2n + 1

Demonstratie. Cazul 1) Analizam cazul cel mai defavorabil.


Confurm Observatiei 4.4.8, numarul de comparatii de chei efectuate n
cazul cel mai defavorabil este egal cu naltimea h a arborelui binar extins de
cautare asociat T = T (A).
Arborele T este un arbore binar strict, cu n noduri interne (si n+1 noduri
externe), deci conform Propozitiei 4.2.3 rezulta ca
h log2 (n + 1) .

TEMA 4. METODA DIVIDE ET IMPERA

128

Cazul 2) Analizam acum cazul mediu (cazul timpului mediu de executie).


Confurm Observatiei 4.4.8, numarul mediu de comparatii de chei are valoarea
P
P
P
P
n+
D(k) +
D(k)
(1 + D(k)) +
D(k)
kI
kE
kI
kE
=
.
Nmed (n) =
2n + 1
2n + 1
unde I este multimea nodurilor interne, iar E este multimea nodurilor externe, iar, pentru fiecare nod k, D(k) reprezinta distanta de la radacina
arborelui la nodul k.
Confurm Propozitiilor 4.2.2 si 4.2.5 rezulta ca
P
D(k) n
2
kE
Nmed (n) =
2n + 1

2 (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) n

2n + 1
n + 2 2 2log2 (n+1)
2n + 2
log2 (n + 1) +
.
=
2n + 1
2n + 1

Propozitia 4.4.2. Pentru algoritmul de cautare binara ntr-un vector sortat


cu n componente, o cautare cu succes necesita cel mult h comparatii de chei,
iar o cautare fara succes necesita h 1 sau h comparatii de chei, unde
h = log2 (n + 1) = log2 n + 1.
Demonstratie. Notand cu h naltimea arborelui binar extins de cautare asociat algoritmului cautarii binare (adica lungimea maxima de la radacina la un
nod extern) si considerand ca radacina arborelui este reprezentata pe nivelul
0, rezulta ca:
arborele are h nivele, n noduri interne si n + 1 noduri externe;
pe nivelele 0, 1, . . . , h 2 avem doar noduri interne, fiecare avand cate
doi descendenti;
pe penultimul nivel, h 1, putem avea si noduri externe, iar nodurile
interne de pe acest nivel au de asemenea cate doi descendenti;
pe ultimul nivel, h, avem doar noduri externe.

TEMA 4. METODA DIVIDE ET IMPERA

129

Confurm Propozitiei 4.2.4 si Observatiei 4.2.3 rezulta ca


h = log2 (n + 1) = log2 n + 1,
iar conform Observatiei 4.4.8 rezulta ca:
o cautare cu succes necesita cel mult h comparatii de chei;
o cautare fara succes necesita h 1 sau h comparatii de chei.
Demonstratia este astfel ncheiata.
Observatia 4.4.10. Conform propozitiei anterioare rezulta ca algoritmul de
cautare binara are timpul de executie n cazul cel mai defavorabil de ordinul
(log2 n), deci timpul (mediu) de executie are ordinul O (log2 n).
Teorema 4.4.1 (complexitatea algoritmului de c
autare binar
a). Algoritmul de cautare binara ntr-un vector sortat cu n componente are complexitatea (log2 n).
Demonstratie. Fie T (n) timpul mediu de executie al algoritmului de cautare
binara. Vom demonstra ca T (n) = (log2 n) prin doua metode.
Metoda 1) Vom calcula efectiv timpul mediu de executie T (n). Conform
demonstratiei propozitiei anterioare, arborele binar extins de cautare asociat
algoritmului cautarii binare este un arbore binar strict cu n noduri interne
si n + 1 noduri externe, iar toate nodurile externe sunt situate pe ultimul si,
eventual, pe penultimul nivel.
Notam cu I multimea nodurilor interne, cu E multimea nodurilor externe,
iar pentru fiecare nod k notam cu D(k) distanta de la radacina arborelui la
nodul k.
Conform Observatiei 4.4.8, timpul mediu de executie are valoarea
P
P
P
P
(1 + D(k)) +
D(k)
n+
D(k) +
D(k)
kI
kE
kI
kE
T (n) =
=
.
2n + 1
2n + 1
Confurm Propozitiilor 4.2.2 si 4.2.4 rezulta ca
P
2
D(k) n
kE
T (n) =
2n + 1

2 (n + 1) log2 (n + 1) + n + 1 2log2 (n+1) n
=
2n + 1
2n + 2
n + 2 2 2log2 (n+1)
=
log2 (n + 1) +
.
2n + 1
2n + 1

(4.4.1)

TEMA 4. METODA DIVIDE ET IMPERA

130

Dar, conform Observatiei 4.2.3,


log2 (n + 1) = 1 + log2 n ,
deci

3n + 4 4 2log2 n
2n + 2
log2 n +
.
2n + 1
2n + 1
n
Evident, log2 n 1 < log2 n log2 n, deci < 2log2 n n. Rezulta ca
2
T (n) =

log2 n

3n 2 log2 n
n + 4 + log2 n
< T (n) < log2 n +
,
2n + 1
2n + 1

deci
1

T (n)
n + 4 + log2 n
3n 2 log2 n
<
<1+
, n 2.
(2n + 1) log2 n
log2 n
(2n + 1) log2 n

Aplicand Criteriul clestelui rezulta ca


T (n)
= 1,
n log2 n
lim

deci conform Propozitiei 1.2.2 obtinem ca T (n) = (log2 n).


Metoda 2) Vom aplica Teorema Master. Conform descrierii recursive a
algoritmului de cautare binara, timpul de executie T (n) verifica relatia de
recurenta
T (n) = T (n/2) + O (1), n > 0,

cu conventiile de notatie din Teorema Master. Conform Cazului 2 al acelei


teoreme, pentru
a = 1, b = 2, c = 0 = logb a si k = 0,
rezulta ca T (n) = (log2 n).

Teorema 4.4.2 (optimalitatea algoritmului de c


autare binar
a). Algoritmul de cautare binara este optim (n clasa algoritmilor bazati pe comparatii
de chei), atat n raport cu timpul de executie n cazul cel mai defavorabil, cat
si n raport cu timpul mediu de executie.
Demonstratie. Optimalitatea n raport cu timpul de executie n cazul cel
mai defavorabil este o consecinta directa a Propozitiei 4.4.2 si a Cazului 1
din Propozitia 4.4.1.
Optimalitatea n raport cu timpul mediu de executie este o consecinta
directa a relatiei (4.4.1) din demonstratia Teoremei 4.4.1 si a Cazului 2 din
Propozitia 4.4.1.

TEMA 4. METODA DIVIDE ET IMPERA

4.5
4.5.1

131

Algoritmi de sortare
Problema sort
arii

Problema sort
arii este urmatoarea:
Se considera un vector A = (a1 , a2 , . . . , an ), n 1. Se cere sa se ordoneze
crescator (sau descrescator) elementele acestui vector.
Observatia 4.5.1. In practica, problema apare, n general, n ordonarea crescatoare (sau descrescatoare) a unei multimi finite de articole (nregistrari)
dupa un camp (sau mai multe) numit cheie de sortare.
Observatia 4.5.2. Fie A un algoritm de sortare, bazat pe comparatii de chei,
a unui vector A = (a1 , a2 , . . . , an ), n 1.
Presupunem ca algoritmul nu contine instructiuni redundante si este aplicabil pentru orice pozitionare posibila a componentelor vectorului A, adica
pentru orice permutare a acestora.
Atunci algoritmului A i se poate asocia un arbore binar T (A) n care
fiecare nod are o eticheta de forma i?j, construit recursiv astfel: daca prima
comparatie efectuata de algoritm este ntre elementele ai si aj ale vectorului,
atunci
radacina arborelui este etichetata cu i?j;
subarborele stang corespunde continuarii algoritmului n cazul ai aj ,
daca acest caz este posibil dupa prima comparatie (altfel este vid, adica
nu exista descendent stang);
subarborele drept corespunde continuarii algoritmului n cazul ai > aj ,
daca acest caz este posibil dupa prima comparatie (altfel este vid, adica
nu exista descendent drept).
Definitia 4.5.1. Arbore binar T (A) construit n observatia anterioara se
numeste arborele de sortare sau arborele de decizie al algoritmului
de sortare A.

Definitia 4.5.2. Fie A un algoritm de sortare, bazat pe comparatii de chei,


a unui vector A = (a1 , a2 , . . . , an ), n 1, si fie T (A) arborele de sortare
corespunzator. Extindem arborele binar T (A) la un arbore binar strict T (A)
astfel: orice nod al lui T , avand eticheta i?j, este reprezentat ntr-un cerc si
devine nod intern n T (A) prin aplicarea urmatoarelor doua reguli:
daca nodul nu are descendent stang i se adauga un descendent stang,
reprezentat ntr-un dreptunghi, corespunzator cazului ai aj , si etichetat cu permutarea a multimii de indici {1, 2, . . . , n} pentru care

TEMA 4. METODA DIVIDE ET IMPERA

132

lantul de la radacina la nodul adaugat corespunde ordinii


a(1) a(2) a(n) ;
daca nodul nu are descendent drept i se adauga un descendent drept,
reprezentat ntr-un dreptunghi, corespunzator cazului ai > aj , si etichetat cu permutarea a multimii de indici {1, 2, . . . , n} pentru care
lantul de la radacina la nodul adaugat corespunde ordinii
a(1) a(2) a(n) .
Arborele T (A) se numeste arbore extins de sortare.

Observatia 4.5.3. Deoarece algoritmul A este aplicabil pentru orice permutare a vectorului A = (a1 , a2 , . . . , an ) si nu contine instructiuni redundante, rezulta ca n arborele extins de sortare T (A) fiecare permutarea
a multimii de indici {1, 2, . . . , n} apare exact o data ca eticheta a unui nod
extern, deci acest arbore are n! noduri externe si, conform Propozitiei 4.2.1,
n! 1 noduri interne.

Propozitia 4.5.1. Pentru orice algoritm de sortare A, bazat pe comparatii


de chei, a unui vector cu n componente, avem:
1) numarul de comparatii de chei efectuate n cazul cel mai defavorabil,
notat cu Ndef (n), verifica inegalitatea
Ndef (n) log2 n! ;
2) numarul mediu de comparatii de chei efectuate, notat cu Nmed (n),
verifica inegalit
atile
Nmed (n) log2 n! + 1

1
2log2 n!
log2 n! 1 + .
n!
n!

Demonstratie. Cazul 1) Analizam cazul cel mai defavorabil.


Evident, numarul de comparatii de chei efectuate n cazul cel mai defavorabil este egal cu naltimea h a arborelui extins de sortare asociat T = T (A).
Arborele T este un arbore binar strict, cu n! 1 noduri interne (si n!
noduri externe), deci conform Propozitiei 4.2.3 rezulta ca
h log2 n! .
Cazul 2) Analizam acum cazul mediu (cazul timpului mediu de executie).
Pentru fiecare din cele n! permutari ale multimii de indici {1, 2, . . . , n},
numarul de comparatii de chei efectuate de algoritmul A n cazul ordinii

TEMA 4. METODA DIVIDE ET IMPERA

133

a(1) a(2) a(n) este egal cu distanta de la radacina arborelui extins


de sortare asociat la nodul extern etichetat cu . Deci numarul mediu de
comparatii de chei are valoarea
P
D(k)
kE
Nmed (n) =
,
n!
unde E este multimea nodurilor externe, iar, pentru fiecare nod k, D(k)
reprezinta distanta de la radacina arborelui la nodul k.
Confurm Propozitiei 4.2.5 rezulta ca
n! log2 n! + n! 2log2 n!
n!
2log2 n!
= log2 n! + 1
.
n!

Nmed (n)

Cum log2 n! log2 n! < 1 + log2 n!, rezulta ca 2log2 n! < 2 n!, adica
2log2 n!
1
2log2 n! 2 n! 1, deci log2 n! + 1
log2 n! 1 + .
n!
n!
Corolarul 4.5.1. Fie A un algoritm de sortare, bazat pe comparatii de chei,
a unui vector cu n componente si fie T = T (A) arborele extins de sortare
asociat.
1) Algoritmul A este optim n raport cu timpul de executie n cazul cel mai
defavorabil daca arborele T are toate nodurile externe situate pe ultimul si,
eventual, pe penultimul nivel. Mai mult, n acest caz numarul de comparatii
de chei efectuate n cazul cel mai defavorabil, notat cu Ndef (n), verific
a egalitatea
Ndef (n) = log2 n! ;
2) Algoritmul A este optim n raport cu timpul mediu de executie daca
si numai daca arborele T are toate nodurile externe situate pe ultimul si,
eventual, pe penultimul nivel. Mai mult, n acest caz numarul mediu de
comparatii de chei efectuate, notat cu Nmed (n), verifica relatiile
Nmed (n) = log2 n! + 1

2log2 n!
1
log2 n! 1 + .
n!
n!

Demonstratie. Optimalitatea n raport cu timpul de executie n cazul cel mai


defavorabil este o consecinta directa a Cazului 1 din propozitia anterioara si
a Propozitiei 4.2.4.
Optimalitatea n raport cu timpul mediu de executie este o consecinta
directa a Cazului 2 din propozitia anterioara si a Propozitiei 4.2.5.

TEMA 4. METODA DIVIDE ET IMPERA

134

Lema 4.5.1. Pentru orice n N au loc inegalitatile:


1
1
< ln(n + 1) ln n < ;
n+1
n
n log2 n (n 1) log2 e log2 n! n log2 n.

(4.5.1)
(4.5.2)

Demonstratie. Aplicand Teorema lui Lagrange pentru functia


f : [n, n + 1] R, f (x) = ln x
(f este derivabila), rezulta ca exista c (n, n+1) a... f (n+1)f (n) = f (c),
1
1
1
1
adica ln(n + 1) ln n = . Dar
< < , deci obtinem relatia (4.5.1).
c
n+1
c
n
Din aceasta relatie rezulta ca (n + 1) ln(n + 1) n ln n < 1 + ln(n + 1),
deci
2 ln 2 ln 1
3 ln 3 2 ln 2

< 1 + ln 2,
< 1 + ln 3,
...
n ln n (n 1) ln(n 1) < 1 + ln n.
Prin adunare obtinem ca
n ln n < n 1 + ln n!, n 2,
de unde, utilizand formula log2 x = log2 e ln x, x > 0, rezulta prima
inegalitate din (4.5.2), valabila si pentru n = 1. A doua inegalitate din
(4.5.2) este o consecinta a inegalitatii evidente n! nn .
Lema 4.5.2. Avem
log2 n! n log2 n
(adica functiile log2 n! si n log2 n sunt asimptotic echivalente).
Demonstratie. Din (4.5.2) rezulta ca
1

(n 1) log2 e
log2 n!

1, n N ,
n log2 n
n log2 n

deci, aplicand Criteriul clestelui obtinem


log2 n!
= 1,
n n log2 n
lim

adica log2 n! n log2 n.

TEMA 4. METODA DIVIDE ET IMPERA

135

Urmatorul rezultat este o consecinta imediata a Corolarului 4.5.1, Lemei


4.5.2 si Propozitiei 1.2.3.
Teorema 4.5.1 (complexitatea algoritmilor de sortare). Numarul de
comparatii de chei efectuate de un algoritm optim de sortare a unui vector
cu n componente este asimptotic echivalent cu
n log2 n,
atat n cazul cel mai defavorabil, cat si n cazul mediu (cazul timpului mediu
de executie), deci n ambele cazuri un astfel de algoritm are complexitatea
(n log2 n).

4.5.2

Interclasarea a doi vectori

Problema interclas
arii este urmatoarea:
Se considera doi vectori
A = (a1 , a2 , . . . , am ), m 1,
B = (b1 , b2 , . . . , bn ), n 1,
ale caror componente sunt sortate (ordonate) crescator, adica
a1 a2 . . . am ,
b1 b2 . . . bn .
Se cere sa se construiasca un vector cu m + n componente
C = (c1 , c2 , . . . , cm+n ),
care sa contina toate componentele vectorilor A si B si care sa fie, de asemenea, sortat crescator, adica
c1 c2 . . . cm+n .
Definitia 4.5.3. Spunem ca elementele vectorului C se obtin prin interclasarea (intercalarea) elementelor vectorilor A si B.
Algoritmul 4.5.1 (Interclasarea a doi vectori).
Pentru parcurgerea componentelor celor trei vectori A, B si C vom
utiliza trei indici i, j si respectiv k.
Initial toti acesti trei indici au valoarea 1.

136

TEMA 4. METODA DIVIDE ET IMPERA


i
1
2
A
j
1
2
B
k
1
2
C

m+n

Se compara elementele curente din A si B (adica ai cu bj ), iar cel mai


mic se depune n C pe pozitia k.
Se incrementeaza k si indicele corespunzator vectorului din care s-a
facut depunerea (i sau j).
Procesul continua pana cand este epuizat unul dintre vectori. Elementele ramase n celalalt vector se vor adauga, n ordinea n care se
afla, la sfarsitul lui C.
Descrierea n pseudocod a algoritmului are urmatoarea forma.
INTERCLASARE(A, B, C, m, n) :
i 1; j 1; k 1;
while (i m and j n) do
// (1)
if A[i] B[j] then
C[k] A[i];
i i + 1;
else
C[k] B[j];
j j + 1;
k k + 1;
while i m do
C[k] A[i];
i i + 1;
k k + 1;
while j n do
C[k] B[j];
j j + 1;
k k + 1;

TEMA 4. METODA DIVIDE ET IMPERA

137

Propozitia 4.5.2 (complexitatea algoritmului de interclasare). Algoritmul de interclasare a doi vectori cu m si respectiv n componente are
complexitatea (m + n).
Demonstratie. Fie T (m, n) timpul de executie al algoritmului.
Vom numara numai operatiile de comparatie si de atribuire n care intervin elemente ale vectorilor. Celelalte operatii care se efectueaza au acelasi
ordin de crestere cu cele pe care le analizam.
Numarul de atribuiri n care intervin elemente ale vectorilor, numite si
deplas
ari, notat cu Nd (m, n), este egal cu numarul de componente ale
lui C, deci
Nd (m, n) = m + n.
(4.5.3)
Numarul de comparatii de chei (comparatii n care intervin elemente
ale vectorilor), notat cu Nc (m, n), este egal cu numarul de executii ale
ciclului while numerotat cu (1). Cu fiecare astfel de comparatie are loc
si o atribuire pentru o componenta a vectorului C, adica o deplasare.
La terminarea ciclului while numerotat cu (1) elementele unuia dintre
vectorii A sau B au fost depuse integral n C, iar n celalalt vector au
mai ramas r elemente nedepuse n C, care vor fi depuse n C dupa
ncheierea acestui ciclu. Rezulta ca
Nc (m, n) = m + n r.
Evident,
1 r max{m, n},

deci

min{m, n} Nc (m, n) m
n 1} .
| +{z
| {z }

n cazul
cel mai favorabil

(4.5.4)

n cazul
cel mai defavorabil

Notand cu c1 , c2 > 0 constantele care reprezinta costurile n timp ale


executarii unei comparatii de chei si, respectiv, ale unei deplasari, obtinem
ca
T (m, n) = c1 Nc (m, n) + c2 Nd (m, n).
Utilizand (4.5.3) si (4.5.4) rezulta ca

c1 min{m, n} + c2 (m + n) T (m, n) c1 (m + n 1) + c2 (m + n).


Deducem ca
c2 (m + n) T (m, n) (c1 + c2 ) (m + n),
deci T (m, n) = (m + n).

TEMA 4. METODA DIVIDE ET IMPERA

138

Observatia 4.5.4. In contextul demonstratiei anterioare, pentru orice r


{1, 2, . . . , max{m, n}} avem
T (m, n) = c1 Nc (m, n) + c2 (m + n)
= c1 (m + n r) + c2 (m + n)
= (c1 + c2 ) (m + n) c1 r.
Pentru a avea cazuri elementare egal posibile (egal probabile), trebuie sa
luam separat n calcul cazurile n care cele r elemente nedepuse n C sunt
din A, deci r {1, 2, . . . , m}, sau din B, deci r {1, 2, . . . , n}.
Astfel putem calcula efectiv timpul mediu de executie astfel:
m

1 nX
Tmediu (m, n) =
((c1 + c2 ) (m + n) c1 r) +
m + n r=1
n
o
X
+
((c1 + c2 ) (m + n) c1 r)
r=1

m(m + 1) + n(n + 1)
= (c1 + c2 ) (m + n) c1
2(m + n)


mn
m+n1
+ c2 (m + n).
+
= c1
2
m+n

Observatia 4.5.5. Evident, orice algoritm care rezolva problema data necesita
cel putin m + n instructiuni de atribuire pentru completarea elementelor
vectorului C, deci conform propozitiei anterioare rezulta ca algoritmul de
interclasare este asimptotic-optim.

4.5.3

Sortarea prin interclasare (mergesort)

Algoritmul 4.5.2 (Sortarea prin interclasare). Pentru a sorta crescator


vectorul A = (a1 , a2 , . . . , an ), n 1, se interclaseaza succesiv secvente ordonate crescator ale vectorului, pana se obtine secventa cu toate elementele
sortate ale vectorului.
Se utilizeaza metoda Divide et Impera:
pentru a sorta un vector cu n componente l mpartim n doi vectori
care odata sortati se interclaseaza;
un vector cu o singura componenta este sortat.
Descrierea n pseudocod a algoritmului are urmatoarea forma.

TEMA 4. METODA DIVIDE ET IMPERA


SORTINT(A, p, q) :
if p < q then


p+q
;
m
2
SORTINT(A, p, m);
SORTINT(A, m + 1, q);
INTERCLAS(A, p, q, m);

139

// sortarea secvent
ei (ap , . . . , aq )

Apel: SORTINT (A, 1, n).


Pentru interclasare vom utiliza un vector intermediar, de lucru, B. Mai
ntai se interclaseaza cele doua secvente (ap , . . . , am ) si (am+1 , . . . , aq ), rezultatul interclasarii depunandu-se n vectorul B:

Apoi rezultatul interclasarii va fi copiat din B n A, ntre pozitiile p si q:

Descrierea n pseudocod a procedurii de interclasare are urmatoarea forma.

140

TEMA 4. METODA DIVIDE ET IMPERA


INTERCLAS(A, p, q, m) :
i p;
j m + 1;
k 1;
while (i m) and (j q) do
if A[i] A[j] then
B[k] A[i];
i i + 1;
else
B[k] A[j];
j j + 1;
k k + 1;
while i m do
B[k] A[i];
i i + 1;
k k + 1;
while j q do
B[k] A[j];
j j + 1;
k k + 1;
k 1;
for i = p, q do
A[i] B[k];
k k + 1;

Exemplul 4.5.1. In Figura 4.5.1 este reprezentat arborele extins de sortare


asociat algoritmului de sortare prin interclasare pentru n = 3.
1?2

>

1?3

(1,2,3)

>
(3,1,2)

2?3

2?3

>
(1,3,2)

>
(3,2,1)

1?3

(2,1,3)

Figura 4.5.1:

>
(2,3,1)

TEMA 4. METODA DIVIDE ET IMPERA

141

Teorema 4.5.2 (complexitatea algoritmului de sortare prin interclasare). Algoritmul de sortare prin interclasare a unui vector cu n componente are complexitatea (n log2 n).
Demonstratie. Fie T (n) timpul de executie al algoritmului de sortare prin
interclasare. Vom demonstra ca T (n) = (n log2 n) prin doua metode.
Metoda 1) Vom estima efectiv timpul de executie T (n). Ca si la analiza complexitatii algoritmului de interclasare a doi vectori (Propozitia 4.5.2),
vom numara numai operatiile de comparatie de chei (comparatii n care intervin elemente ale vectorului) si de deplasare (atribuiri n care intervin elemente ale vectorului). Celelalte operatii care se efectueaza au acelasi ordin
de crestere cu cele pe care le analizam.
Avem
T (n) = c1 Nc (n) + c2 Nd (n),
(4.5.5)
unde Nc (n) si Nd (n) reprezinta numarul de comparatii de chei, respectiv
numarul de deplasari efectuate de algoritm, iar c1 , c2 > 0 sunt constante ce
reprezinta costurile n timp ale executarii unei comparatii de chei si, respectiv, ale unei deplasari.
Conform descrierii recursive a algoritmului, rezulta ca numerele Nc (n) si
Nd (n) verifica, respectiv, relatiile de recurenta
(
0,
l n m j n k daca n = 1,
l n m
j n k
Nc (n) =
Nc
+ Nc
+ Nc
,
, daca n > 1,
2
2
2
2
(4.5.6)
(
0,
j n k
l n m
l n m j n k daca n = 1,
Nd (n) =
+ Nd
+ Nd
,
, daca n > 1,
Nd
2
2
2
2
(4.5.7)
l n m j n k
l n m j n k
unde N c
,
si N d
,
reprezinta numarul de comparatii
2
2
2
2
de chei, respectiv numarul de ldeplas
ari efectuate la interclasarea celor doi
nm jnk
si
).
vectori sortati (de dimensiuni
2
2
Conform demonstratiei Propozitiei 4.5.2, si anume relatiilor (4.5.3) si
(4.5.4), avem
l n m j n k l n m j n k
Nd
,
=
+
= n,
(4.5.8)
2
2
2
2
m
j
k
nj
k
j
k
o
l n
n
n
n
,

,
+ 1, . . . , n 1 .
(4.5.9)
Nc
2
2
2
2

Notand cu Nc+ (n) numarul de comparatii de chei n cazul cel mai defavorabil,

142

TEMA 4. METODA DIVIDE ET IMPERA


din (4.5.6) si (4.5.9) rezulta relatia de recurenta
(
0,j k
daca n = 1,
l n m
n
Nc+ (n) =
+ Nc+
+ n 1, daca n > 1.
Nc+
2
2

(4.5.10)

Rezolvam aceasta relatie de recurenta.


Pentru n = numar par, adica n = 2m, m 1, avem

Nc+ (n + 1) Nc+ (n) = Nc+ (2m + 1) Nc+ (2m)




= Nc+ (m + 1) + Nc+ (m) + 2m Nc+ (m) + Nc+ (m) + 2m 1
= Nc+ (m + 1) Nc+ (m) + 1,
iar pentru n = numar impar, adica n = 2m + 1, m 1, avem
Nc+ (n + 1) Nc+ (n) = Nc+ (2m + 2) Nc+ (2m + 1)


= Nc+ (m + 1) + Nc+ (m + 1) + 2m + 1 Nc+ (m + 1) + Nc+ (m) + 2m
= Nc+ (m + 1) Nc+ (m) + 1,
deci pentru orice n > 1 avem
Nc+ (n + 1) Nc+ (n) = Nc+
Notand

j n k


j n k
+ 1 Nc+
+ 1.
2
2

u(n) = Nc+ (n + 1) Nc+ (n), n N ,


obtinem ca
u(n) =
Demonstram ca

j n1,
k
2

daca n = 1,
+ 1, daca n > 1.

u(n) = log2 (n + 1), n N ,

(4.5.11)

(4.5.12)

(4.5.13)

prin inductie.
Pentru n = 1 avem u(1) = 1 = log2 2.
Presupunem egalitatea adevarata pentru orice k {1, . . . , n 1} si o
demonstram pentru n (n 2). Intr-adev
j n k ar, folosind relatia de recurenta
avem
(4.5.12) si ipoteza de inductie pentru
2
j n k
j n k
l
m
u(n) = u
+ 1 = log2
+ 1 + 1.
2
2

143

TEMA 4. METODA DIVIDE ET IMPERA


Dar, notand log2 (n + 1) = k, avem k N , k 2 si, succesiv:
k 1 < log2 (n + 1) k; 2k1 < n + 1 2k ;
n
2k1 n < 2k ; 2k2 < 2k1 ;
jnk
j2n k
2k2
< 2k1 ; 2k2 <
+ 1 2k1;
2
2
j n k

k 2 < log2
+ 1 k 1;
j n k 2 m
l
log2
+ 1 = k 1,
2

deci

u(n) = k 1 + 1 = k = log2 (n + 1),

ceea ce ncheie demonstratia prin inductie a relatiei (4.5.13).


Din (4.5.11) si (4.5.13) rezulta ca
Nc+ (n + 1) Nc+ (n) = log2 (n + 1), n N .
Aplicand succesiv aceasta relatie avem
Nc+ (n) = Nc+ (n 1) + log2 n
= Nc+ (n 2) + log2 (n 1) + log2 n
...
= Nc+ (1) + log2 2 + log2 3 + + log2 n.

Cum Nc+ (1) = 0 obtinem ca

Nc+ (n) = log2 1 + log2 2 + + log2 n, n N .

(4.5.14)

Fie n 2 si p = log2 n, deci p N si p1 < log2 n p, deci 2p1 < n 2p .


Pentru orice i {2, 3, . . . , n} avem echivalentele
log2 i = j j 1 < log2 i j 2j1 < i 2j 2j1 + 1 i 2j .

Astfel avem
Nc+ (n)

n
X
i=2

p1
X

log2 i =
j

2
X

p1
X
j=1

2
X

log2 i +

j=1 i=2j1 +1

j+

j=1 i=2j1 +1

p1
X

n
X

i=2p1 +1

p=

p1
X
j=1

n
X

log2 i

i=2p1 +1

j(2j 2j1) + p(n 2p1 )

j 2j1 + p(n 2p1 ) = p 2p1 2p + 1 + p(n 2p1)

= np 2p + 1,

TEMA 4. METODA DIVIDE ET IMPERA

144

deci
Nc+ (n)

n
X
i=2

log2 i = nlog2 n 2log2 n + 1, n N ,

(4.5.15)

egalitatea fiind evident valabila si pentru n = 1. Dar


log2 n log2 n < log2 n + 1,
deci
n 2log2 n < 2n.
Astfel rezulta ca n cazul cel mai defavorabil numarul de comparatii de chei
verifica inegalitatile
n log2 n 2n + 1 < Nc+ (n) < n log2 n + 1, n N .

(4.5.16)

Notand cu Nc (n) numarul de comparatii de chei n cazul cel mai favorabil,


din (4.5.6) si (4.5.9) rezulta relatia de recurenta
(
0, j k j k daca n = 1,
l n m
n
n
(4.5.17)
Nc (n) =

+ Nc
+
, daca n > 1.
Nc
2
2
2

Demonstram ca sirul (Nc (n))n1 este crescator, adica


Nc (n + 1) Nc (n), n N ,

prin inductie.
Pentru n = 1 avem Nc (2) = 1 > 0 = Nc (1).
Presupunem inegalitatea adevarata pentru orice k {1, . . . , n 1} si o
demonstram pentru n (n 2). Intr-adev
l n m ar, folosind relatia de recurenta
(4.5.17), ipoteza de inductie pentru
cand n este par, respectiv pentru
2


jnk
jnk
n+1
cand n este impar, precum si inegalitatea evidenta

,
2
2
2
avem



 

n+1
n+1
n+1

Nc (n + 1) = Nc
+ Nc
+
2
2
2
j n k j n k
l n m
+ Nc
+
Nc
2
2
2

= Nc (n).
Demonstratia prin inductie este ncheiata.

145

TEMA 4. METODA DIVIDE ET IMPERA


Fie n N si

r = log2 n,

(4.5.18)

Nc (n) Nc (2r ).

(4.5.19)

deci r N si r log2 n < r + 1, deci 2r n < 2r+1 . Deoarece sirul


(Nc (n))n1 este crescator, rezulta ca

Dar, conform relatiei de recurenta (4.5.17) avem


Nc (2r ) = 2Nc (2r1 ) + 2r1 , r N .
Rescriind aceasta egalitate sub forma

Nc (2r ) r 2r1 = 2 Nc (2r1 ) (r 1)2r2 , r N ,

Aplicand succesiv aceasta relatie avem

Nc (2r ) r 2r1 = 2 Nc (2r1 ) (r 1)2r2

= 22 Nc (2r2 ) (r 2)2r3
= ...

= 2r Nc (2rr ) (r r)2rr1
Cum Nc (1) = 0 obtinem ca Nc (2r ) r 2r1 = 0, deci
Nc (2r ) = r 2r1 , r N.


(4.5.20)

Din (4.5.19), (4.5.20) si (4.5.18) rezulta ca n cazul cel mai favorabil numarul
de comparatii de chei verifica inegalitatile
Nc (n) log2 n 2log2 n1

1
n log2 n, n N .
2

(4.5.21)

Din (4.5.16) si (4.5.21) rezulta ca numarul de comparatii de chei verifica


inegalitatile
1
n log2 n Nc (n) < n log2 n + 1, n N .
2

(4.5.22)

Din relatiile (4.5.7) si (4.5.8) rezulta ca numarul de deplasari efectuate


de algoritm verifica relatia de recurenta
(
daca n = 1,
l n m 0, j n k
Nd (n) =
Nd
+ Nd
+ n, daca n > 1.
2
2

TEMA 4. METODA DIVIDE ET IMPERA

146

Aceasta relatie se rezolva analog relatiei (4.5.10), obtinandu-se


Nd (n) = nlog2 n 2log2 n + n, n N ,
deci
n log2 n 2n + n < Nd (n) < n log2 n + n, n N .

(4.5.23)

Din relatiile (4.5.5), (4.5.22) si (4.5.23) rezulta ca T (n) = (n log2 n).


Metoda 2) Vom aplica Teorema Master. Conform descrierii recursive a
algoritmului si utilizand complexitatea algoritmului de interclasare (Propozitia 4.5.2), timpul de executie T (n) verifica relatia de recurenta
T (n) = 2T (n/2) + O (n), n > 1,
cu conventiile de notatie din Teorema Master. Conform Cazului 2 al acelei
teoreme, pentru
a = 2, b = 2, c = 1 = logb a si k = 0,
rezulta ca T (n) = (n log2 n).
Urmatorul rezultat este o consecinta directa a Teoremelor 4.5.1 si 4.5.2.
Teorema 4.5.3 (optimalitatea algoritmului de sortare prin interclasare). Algoritmul de sortare prin interclasare este asimptotic-optim (n
clasa algoritmilor bazati pe comparatii de chei), atat n raport cu timpul de
executie n cazul cel mai defavorabil, cat si n raport cu timpul mediu de
executie.
Observatia 4.5.6. Mai mult, conform relatiilor (4.5.16) si (4.5.22) si Teoremei
4.5.1 rezulta ca, exact ca la algoritmii optimi de sortare bazati pe comparatii
de chei, numarul de comparatii de chei efectuate de algoritmul de sortare
prin interclasare a unui vector cu n componente este asimptotic echivalent
cu n log2 n, atat n cazul cel mai defavorabil, cat si n cazul mediu (cazul
timpului mediu de executie).
Totusi, algoritmul de sortare prin interclasare nu este optim, deoarece
arborele extins de sortare asociat nu are ntotdeauna toate nodurile externe
situate doar pe ultimul si, eventual, pe penultimul nivel. De exemplu, pentru
n = 6 exista noduri externe situate pe antepenultimul nivel.
Observatia 4.5.7. Complexitatea temporala a algoritmului de sortare prin
interclasare este una dintre cele mai bune din clasa algoritmilor de sortare
bazati pe comparatii de chei. Un dezavantaj este faptul ca se utilizeaza un
vector suplimentar de lucru.

TEMA 4. METODA DIVIDE ET IMPERA

147

Observatia 4.5.8. Se poate mbunatati procedura de interclasare, micsorand


numarul de deplasari (atribuiri n care intervin elemente ale vectorului).
T
inem seama de urmatoarele:
1) Daca primul ciclu se termina cand i > m, atunci elementele ramase n
secventa (aj , . . . , aq ) nu vor mai fi copiate n vectorul B, pentru ca apoi
sa fie readuse n A, deoarece ele ocupa deja pozitiile corecte.

2) Daca primul ciclu se termina cand j > q, atunci elementele ramase n


secventa (ai , . . . , am ) vor fi copiate direct n vectorul A, pe pozitiile
q m + i, q m + i + 1, , q,
fara a le mai transfera n B si apoi, de aici, n A.

Pentru a evita eventualele suprapuneri nedorite, copierea se va face n


ordine inversa.
Obtinem urmatoarea varianta mbunatatita, descrisa n pseudocod.

TEMA 4. METODA DIVIDE ET IMPERA

148

INTERCLAS2(A, p, q, m) :
i p;
j m + 1;
k 1;
while (i m) and (j q) do
if A[i] A[j] then
B[k] A[i];
i i + 1;
else
B[k] A[j];
j j + 1;
k k + 1;
if j q then
lim j 1;
else
lim q m + i 1;
for j = m, i, 1 do
A[q m + j] A[j];
k 1;
for i = p, lim do
A[i] B[k];
k k + 1;

4.5.4

Sortarea rapid
a (quicksort)

Denumirea algoritmului se datoreaza faptului ca s-a dovedit a fi unul dintre


cei mai performanti (rapizi) algoritmi de sortare bazati pe comparatii de chei.
In prezent, exista foarte multe variante ale acestui algoritm, menite sa
micsoreze timpul de executie n cazurile cele mai defavorabile.
Data fiind simplitatea sa, pentru nceput, vom descrie varianta clasica a
acestui algoritm.
Algoritmul 4.5.3 (Sortarea rapid
a). Pentru a sorta crescator vectorul
A = (a1 , a2 , . . . , an ), n 1, se foloseste din nou metoda Divide et Impera
pornindu-se acum de la ideea ca, pentru orice secventa
(ap , . . . , au ), p < u,
printr-un procedeu de rearanjare (interschimbari succesive) se poate ajunge
la situatia
(ap , . . . , ak , . . . , au )

TEMA 4. METODA DIVIDE ET IMPERA

149

n care
ai ak aj ,

(4.5.24)

pentru orice i si j cu p i k 1 si k + 1 j u.
Se obtin, astfel, doua secvente mai mici (numite partitii)
(ap , . . . , ak1 ) si (ak+1 , . . . , au ),
care pot fi prelucrate (sortate), n acelasi mod, independent una de alta.
Secventele de lungime 1 sau cele vide care rezulta n urma partitionarii nu
se mai prelucreaza.
Un element ak , care satisface relatia (4.5.24), se numeste pivot. El are
proprietatea ca a ajuns deja pe pozitia finala, n viitorul vectorul sortat,
deoarece
toate elementele din secventa (ap , . . . , ak1) sunt mai mici sau egale cu
el;
toate elementele din secventa (ak+1 , . . . , au ) sunt mai mari sau egale cu
el.
La final, spre deosebire de algoritmul de sortare prin interclasare, n care
la etapa de combinare se realiza interclasarea celor doua secvente sortate,
aici aceasta etapa este evitata deoarece, n urma prelucrarilor celor doua
secvente, rezulta deja toata secventa (ap , . . . , au ) sortata.

Exemplul 4.5.2.

Pentru determinarea pivotului procedam astfel:


Se compara ap , succesiv, cu au , au1 , . . . s.a.m.d. pana cand se ajunge
la o pozitie u cu ap > au . Atunci se executa urmatoarele operatii

ap au (interschimbare)
pp+1

u u

TEMA 4. METODA DIVIDE ET IMPERA

150

In continuare, se compara au , succesiv, cu ap , ap+1 , . . . s.a.m.d. pana


cand se ajunge la o pozitie p cu ap > au . Atunci se executa urmatoarele
operatii

ap au
p p

u u1

Se reiau pasii anteriori pentru noua secventa (ap , . . . , au ).


Algoritmul se termina cand avem p = u si atunci luam
k = p = u.
Descrierea n pseudocod a algoritmului are urmatoarea forma.
QUICKSORT(A, p, u) :
// sortarea secvent
ei (ap , . . . , aq )
if p < u then
k PIVOT(A, p, u); // se determin
a pozit
ia k a pivotului
QUICKSORT(A, p, k 1);
QUICKSORT(A, k + 1, u);
Apel: QUICKSORT (A, 1, n).
Procedura pentru determinarea pivotului este:

TEMA 4. METODA DIVIDE ET IMPERA


PIVOT(A, p, u) :
cp 0;
cu 1;
while p < u do
if A[p] > A[u] then
A[p] A[u];
m cp;
cp cu;
cu m;
p p + cp;
u u + cu;
k p;
returneaz
a k;

151

// pasul de cre
stere a lui p
// pasul de cre
stere a lui u

// se interschimb
a (cu semn inversat)
// valorile pa
silor de cre
stere

Teorema 4.5.4 (complexitatea algoritmului de sortare rapid


a (quicksort)). Algoritmul de sortare rapida (quicksort) a unui vector cu n componente are complexitatea

(n2 ),
pentru timpul de executie n cazul cel mai defavorabil,

(n log2 n), pentru timpul de executie n cazul cel mai favorabil,

(n log2 n), pentru timpul mediu de executie.

Demonstratie. Vom evalua doar numarul de comparatii de chei, celelalte


operatii nedepasind ordinul de crestere al acestora.
Fie N(n) numarul de comparatii de chei efectuate de algoritm pentru un
vector cu n componente.
In procedura PIVOT(A, p, u) se efectueaza u p comparatii de chei.
Conform descrierii recursive a algoritmului, rezulta ca numerele N(n)
verifica relatiile de recurenta

0,
daca n {0, 1},
N(n) =
(4.5.25)
N(k 1) + N(n k) + n 1, daca n 2,
unde k este indicele pivotului, k {1, 2, . . . , n}.
Analizam ntai cazurile extreme, n raport cu diferenta absoluta a dimensiunilor celor doua partitii rezultate dupa fixarea pivotului. Aceasta diferenta
este
|(n k) (k 1)| = |n + 1 2k|.

Cazul 1) Notam cu N + (n) numarul de comparatii de chei efectuate de


algoritm n cazul n care la fiecare partitionare cele doua partitii obtinute

TEMA 4. METODA DIVIDE ET IMPERA

152

sunt cat mai neechilibrate, adica diferenta absoluta a dimensiunilor lor


este maxima. Evident, |n + 1 2k| este maxim pentru k {1, n}, deci

0,
daca n {0, 1},
+
N (n) =
(4.5.26)
+
N (n 1) + n 1, daca n 2
(deoarece N + (0) = 0). Aceasta situatie apare atunci cand vectorul A este de
la nceput sortat crescator (deoarece procedura PIVOT va fi apelata succesiv
pentru perechile de indici (1, n), (2, n), . . . , (n 1, n)). Avem
N + (n) = N + (n 1) + n 1
= N + (n 2) + (n 2) + (n 1)
...
= N + (1) + 1 + 2 + + (n 2) + (n 1),
deci
N + (n) =

n(n 1)
, n N.
2

(4.5.27)

Demonstram ca
N(n) N + (n), n N

(4.5.28)

prin inductie.
Pentru n {0, 1} avem N(n) = N + (n) = 0.
Presupunem inegalitatea adevarata pentru orice i {0, 1, . . . , n 1} si
o demonstram pentru n (n 2). Intr-adevar, folosind relatia de recurenta
(4.5.25), ipoteza de inductie pentru k 1 si n k si relatia (4.5.27) avem
N(n) = N(k 1) + N(n k) + n 1
N + (k 1) + N + (n k) + n 1
(k 1)(k 2) (n k)(n k 1)
=
+
+n1
2
2
n(n 1)
(k 1)(n k)
=
2
n(n 1)
.

2
Mai mult, egalitatea are loc daca si numai daca k {1, n} (la fiecare
partitionare!).
Astfel Cazul 1) este cel mai defavorabil, avand numarul de comparatii
n(n 1)
N + (n) =
si, prin urmare, complexitatea (n2 ).
2
Cazul 2) Notam cu N (n) numarul de comparatii de chei efectuate de
algoritm n cazul n care la fiecare partitionare cele doua partitii obtinute

153

TEMA 4. METODA DIVIDE ET IMPERA

sunt cat mai echilibrate, adica diferenta absoluta a


dimensiunilor
  lor este

n+1
n+1
minima. Evident, |n + 1 2k| este minim pentru k
,
,
2
2
deci

N (n) =



n1
2



0,

+ N

n1
2



daca n {0, 1},


+ n 1, daca n 2,
(4.5.29)

Rezolvam aceasta relatie de recurenta.


Pentru n = numar par, adica n = 2m, m 1, avem
N (n + 1) N (n) = N (2m + 1) N (2m)


= N (m) + N (m) + 2m N (m) + N (m 1) + 2m 1
= N (m) N (m 1) + 1,
iar pentru n = numar impar, adica n = 2m + 1, m 1, avem
N (n + 1) N (n) = N (2m + 2) N (2m + 1)


= N (m + 1) + N (m) + 2m + 1 N (m) + N (m) + 2m
= N (m + 1) N (m) + 1,
deci pentru orice n 2 avem

N (n + 1) N (n) = N







n1
n1

+1 N
+ 1,
2
2

egalitatea fiind evident valabila si pentru n = 1.


Notand
v(n) = N (n + 1) N (n), n N,
obtinem ca
v(n) =
Demonstram ca



0, 
daca n = 0,
n1
+ 1, daca n 1.
2

v(n) = log2 (n + 2) 1, n N,
prin inductie.
Pentru n = 0 avem v(0) = 0 = log2 2 1.

(4.5.30)

(4.5.31)

(4.5.32)

154

TEMA 4. METODA DIVIDE ET IMPERA

Presupunem egalitatea adevarata pentru orice i {0, 1, . . . , n 1} si o


demonstram pentru n (n 1). Intr-adev
ar, folosind relatia de recurenta

n1
(4.5.31) si ipoteza de inductie pentru
avem
2





 



n1
n+1
n1
+1 = log2
+2
= log2
+1 .
v(n) = v
2
2
2
Dar, notand log2 (n + 2) = r, avem r N , r 2 si, succesiv:
r 1 < log2 (n + 2) r; 2r1 < n + 2 2r ;
n+1
2r1 n + 1 < 2r ; 2r2
< 2r1 ;
2




n+1
n+1
r1
r2
r2
<2 ; 2
<
+ 1 2r1 ;
2

2
2



n+1
r 2 < log2
+ 1 r 1;
2




n+1
+1
= r 1,
log2
2
deci
v(n) = r 1 = log2 (n + 2) 1,

ceea ce ncheie demonstratia prin inductie a relatiei (4.5.32).


Din (4.5.30) si (4.5.32) rezulta ca
N (n + 1) N (n) = log2 (n + 2) 1, n N.
Aplicand succesiv aceasta relatie avem
N (n) = N (n 1) + log2 (n + 1) 1
= N (n 2) + log2 n + log2 (n + 1) 2
...
= N (0) + log2 2 + log2 3 + + log2 (n + 1) n.
Cum N (0) = 0 obtinem ca
N (n) = log2 1 + log2 2 + + log2 (n + 1) n, n N.
Conform relatiei (4.5.15) avem
n+1
X
i=1

log2 i = (n + 1)log2 (n + 1) 2log2 (n+1) + 1,

(4.5.33)

155

TEMA 4. METODA DIVIDE ET IMPERA


deci
N (n) = (n + 1)log2 (n + 1) 2log2 (n+1) (n 1), n N.

(4.5.34)

Demonstram ca
N(n) N (n), n N

(4.5.35)

prin inductie.
Pentru n {0, 1} avem N(n) = N (n) = 0.
Presupunem inegalitatea adevarata pentru orice i {0, 1, . . . , n 1} si
o demonstram pentru n (n 2). Intr-adevar, folosind relatiile de recurenta
(4.5.25) si (4.5.29) si ipoteza de inductie pentru k 1 si n k avem


n1

N(n) N (n) = N(k 1) + N(n k) + n 1 N


2


n1
n + 1,
N
2
(k),
(4.5.36)
unde

(k) = N (k 1) + N (n k) N



n1
2





n1
2



Deoarece (k) = (n + 1 k), rezulta ca putem presupune ca k n + 1 k


adica


n1
k
+1
2

(
notand
n caz contrar,


 k = n + 1 k obtinem (k) = (k ) si k
n1
1, 2, . . . ,
+ 1 ).
2

n1
Pentru k =
+ 1 avem (k) = 0, deci N(n) N (n) 0.
2



n1
Pentru k 1, 2, . . . ,
, conform (4.5.33) avem
2

156

TEMA 4. METODA DIVIDE ET IMPERA

(k) = N (k 1) + N (n k) N
=

k
X
i=1

log2 i k + 1 +

nk+1
X
i=1



n1
2





n1
2



log2 i n + k

+1

 n1

2
X
n1
n1

log2 i +
log2 i +

2
2
i=1
i=1

n1
n1
+1
+1

k
nk+1
2
2
X
X
X

X
log2 i
log2 i
log2 i
log2 i
=
n1
2

+1

i=1

i=1

nk+1
X

i=1

i=1

+1
n1
2
X
log2 i
log2 i

+2
i= n1
2

i=k+1

+1k
+1k
n1



 n1
2
2
X 
X
n1
log2 i +
log2 (i + k)
+1

=
2
i=1
i=1

+1k





n1
2
X 
n1
log2 i +
+1
log2 (i + k)
=
2
i=1

0.

Conform (4.5.36) rezulta din nou ca N(n)N (n) 0 si astfel demonstratia


prin inductie a inegalitatii (4.5.35) este ncheiata.
Astfel Cazul 2) este cel mai favorabil, avand numarul de comparatii dat
de relatia (4.5.34) si, prin urmare, complexitatea (n log2 n).
m ca egalitatea
poate avea loc n (4.5.35) si pentru valori k 6
 Semnal
 a

n+1
n+1
,
, de exemplu pentru n = 10 si k = 4 (N (3)+N (6) =
2
2
2 + 8 = 10, N (4) + N (5) = 4 + 6 = 10).
Cazul 3) Analizam acum cazul mediu (cazul timpului mediu de executie).
Notam cu Nk (n) numarul de comparatii de chei efectuate de algoritm pentru
un vector cu n componente n cazul n care este indicele pivotului este k.
Evidenr k poate lua oricare din valorile 1, 2, . . . , n, iar toate aceste situatii
sunt echiprobabile, deci numarul mediu de comparatii de chei are valoarea

Nmed (n) =

n
P

Nk (n)

k=1

157

TEMA 4. METODA DIVIDE ET IMPERA


Conform descrierii algoritmului (a se vedea relatia (4.5.25)) avem

0,
daca n {0, 1},
Nk (n) =
Nmed (k 1) + Nmed (n k) + n 1, daca n 2,
pentru orice k {1, 2, . . . , n}, deci

0,
daca n {0, 1},

P
n
Nmed (n) =
(Nmed (k 1) + Nmed (n k) + n 1)

k=1
, daca n 2.
n

Pentru orice n 2 avem


Nmed (n) =

n
P

k=1

2
=

Nmed (k 1) +

n
P

k=1

n
P

k=1

Nmed (n k) + n(n 1)
n

Nmed (k 1) + n(n 1)
n

deci numarul mediu de comparatii de chei verifica relatia de recurenta

0,
daca n {0, 1},

P
n
2
Nmed (k 1) + n(n 1)
Nmed (n) =

k=1
, daca n 2.
n

Formula data de a doua ramura este valabila si pentru n = 1. Pentru n 2


avem
nNmed (n) = 2

n
X
k=1

(n 1)Nmed (n 1) = 2

n1
X
k=1

Nmed (k 1) + n2 n,

Nmed (k 1) + (n 1)2 (n 1),

deci prin scadere obtinem


nNmed (n) (n 1)Nmed (n 1) = 2Nmed (n 1) + 2n 2,
adica
nNmed (n) = (n + 1)Nmed (n 1) + 2n 2.

158

TEMA 4. METODA DIVIDE ET IMPERA


Aceasta egalitate poate fi rescrisa sub forma
n(Nmed (n) 2) = (n + 1)(Nmed (n 1) 2) + 2n.
Impartind prin n(n + 1) obtinem
Nmed (n 1) 2
2
Nmed (n) 2
=
+
.
n+1
n
n+1
Aplicand succesiv aceasta relatie avem
Nmed (n 1) 2
2
Nmed (n) 2
=
+
n+1
n
n+1
Nmed (n 2) 2 2
2
=
+ +
n1
n n+1
...
Nmed (1) 2 2
2
2
=
+ ++ +
.
2
3
n n+1
Cum Nmed (1) = 0, obtinem ca


1
1 1
4n, n 1.
Nmed (n) = 2(n + 1) 1 + + + +
2 3
n
Aplicand Teorema Stolz-Ces`aro pentru sirurile an = 1 +
bn = ln n (strict crescator si avand limita ) avem

(4.5.37)

1 1
1
+ + + si
2 3
n

1
1 1
+ ++
2 3
n = lim an = lim an+1 an
lim
n bn+1 bn
n bn
n
ln n
1
1
n
1
n+1
n =
= lim

= 1.
= lim
n n + 1
n ln(n + 1) ln n
ln e
1
ln 1 +
n
1+

Deducem ca
Nmed (n)
ln 2 Nmed (n)
lim
= lim
n n log2 n
n
n ln n

1 1
1
1
+
+
+

+
2(n + 1)
2 3
n 4

= ln 2 lim

n
n
ln n
ln n

= 2 ln 2,

deci Nmed (n) = (n log2 n),

(4.5.38)

TEMA 4. METODA DIVIDE ET IMPERA

159

Urmatorul rezultat este o consecinta directa a Teoremelor 4.5.1 si 4.5.4.


Teorema 4.5.5 (optimalitatea algoritmului de sortare rapid
a (quicksort)). Algoritmul de sortare rapida (quicksort) este asimptotic-optim (n
clasa algoritmilor bazati pe comparatii de chei), n raport cu timpul mediu de
executie.
Observatia 4.5.9. In cazul cel mai favorabil, conform relatiei (4.5.34) rezulta
ca numarul de comparatii de chei efectuate de algoritmul de sortare rapida
(quicksort) este asimptotic echivalent cu n log2 n.
In cazul timpului mediu de executie, conform relatiei (4.5.38) rezulta ca
numarul de comparatii de chei efectuate este asimptotic echivalent cu
2 ln 2 n log2 n.
Conform Teoremei 4.5.1, rezulta ca algoritmul de sortare rapida (quicksort)
nu este optim.
Pe de alta parte, cum 2 ln 2 1,39, rezulta ca n cazul mediu numarul de
comparatii efectuate este mai mare doar cu aproximativ 39% decat n cazul
cel mai favorabil.
Observatia 4.5.10. Algoritmul de sortare rapida (quicksort) este ineficient n
situatiile n care se ntampla ca n mod sistematic, n cele mai multe apelari
succesive, cele doua partitii care se obtin sa fie foarte neechilibrate (adica
sa aiba dimensiuni diferite, una foarte mare si cealalta foarte mica). Cu cat
dimensiunile celor doua partitii sunt mai apropiate cu atat se reduce numarul
comparatiilor de chei efectuate.
Un mod de a realiza echilibrarea consta n ncercarea de a obtine ca pivot
elementul de pe pozitia mediana a secventei de sortat.
De asemenea, n cazurile cele mai defavorabile (vector deja sortat), la
vectori de dimensiuni mari, este posibila aparitia unor erori la executie de
genul depasirea stivei (stack overflow ). Unele dintre aceste situatii pot fi
evitate, daca se elimina apelurile recursive inutile.
Obtinem urmatoarea varianta mbunatatita, descrisa n pseudocod.

TEMA 4. METODA DIVIDE ET IMPERA


QUICKSORT2(A,
p, u) :


u+p
;
k
2

160

// se determin
a pozit
ia median
a

// a secvent
ei de sortat
med A[k];
// se ret
ine elementul de pe pozit
ia median
a
min p;
max u;
repeat
while A[min] < med do
min min + 1
while A[max] > med do
max max 1
if min max then
A[min] A[max]
min min + 1;
max max 1;
while min max;
if p < max then
QUICKSORT2(A, p, max);
if u > min then
QUICKSORT2(A, min, u);

Apel: QUICKSORT2 (A, 1, n).

4.6

O problem
a de acoperire

Consideram urmatoarea problem


a de acoperire:
Se considera o suprafata patrata cu lungimea laturii n = 2k , k 1,
divizata n patrate unitare, ca o tabla de sah. Unul dintre aceste patrate
unitare este deja acoperit.
Se cere sa se determine o acoperire a suprafetei ramase cu placi de forma

constand din trei patrate unitare.


Modelarea problemei
Memoram suprafata patrata ntr-o matrice S = (sij )i,j=1,n , fiecare patrat
unitar fiind deci reprezentat de un element al acestei matrice.

TEMA 4. METODA DIVIDE ET IMPERA

161

Evident, o acoperire cu piese de forma data utilizeaza un numar de


4k 1
n2 1
=
3
3
piese.

n2 1
Consideram ca piesele sunt numerotate cu 1, 2, . . . ,
si ca asezarea
3
piesei numarul i consta n completarea elementelor corespunz
ma
 atoare din
n2 1
.
tricea S cu numarul i al piesei, pentru fiecare valoare i 1, 2, . . . ,
3
Pentru rezolvarea problemei utilizam urmatoarea strategie Divide et Impera:
Se mparte suprafata patrata n patru patrate egale, formandu-se patru
suprafete patrate cu lungimea laturii 2k1 .
Una dintre cele patru suprafete are deja un patrat unitar acoperit.
Acoperim cu o placa trei patrate unitare din centrul suprafetei mari astfel ncat sa acoperim cate un patrat unitar si din celelalte trei suprafete.
Un exemplu n acest sens este redat n Figura 4.6.1.

Figura 4.6.1:

Fiecare dintre cele patru suprafete este acum n conditiile problemei,


deci pentru fiecare suprafata se repeta procedeul de descompunere descris anterior.
Obtinem urmatorul algoritm Divide et Impera, descris n pseudocod, pentru rezolvarea problemei.

TEMA 4. METODA DIVIDE ET IMPERA

162

Algoritmul 4.6.1.
ACOPERIRE(S, i, j, n, ip, jp) :
// S=matricea ce va fi completat
a cu numerele pl
acilor
// (i, j)=colt
ul st^
anga sus
// n=lungimea laturii
// (ip, jp) = coordonatele p
atratului unitar acoperit
if (n > 1) then
p p + 1;
// num
arul pl
acii
m n/2;
// noua dimensiune a laturii
// Coordonatele st^
anga sus ale celor 4 p
atrate:
i1 i; j1 j;
i2 i; j2 j + m;
i3 i + m; j3 j;
i4 i + m; j4 j + m;
// Coordonatele p
atratelor unitare ce vor fi acoperite
// ^
n cele 4 p
atrate:
ip1 ip; jp1 jp;
ip2 ip; jp2 jp;
ip3 ip; jp3 jp;
ip4 ip; jp4 jp;
if (i3 ip) then
ip1 i1 + m 1; jp1 j1 + m 1;
ip2 i2 + m 1; jp2 j2;
S[ip1][jp1] p; S[ip2][jp2] p;
else
ip3 i3; jp3 j3 + m 1;
ip4 i4; jp4 j4;
S[ip3][jp3] p; S[ip4][jp4] p;
if (j2 jp) then
ip1 i1 + m 1; jp1 j1 + m 1;
ip3 i3; jp3 j3 + m 1;
S[ip1][jp1] p; S[ip3][jp3] p;
else
ip2 i2 + m 1; jp2 j2;
ip4 i4; jp4 j4;
S[ip2][jp2] p; S[ip4][jp4] p;
ACOPERIRE(S, i1, j1, m, ip1, jp1);
ACOPERIRE(S, i2, j2, m, ip2, jp2);
ACOPERIRE(S, i3, j3, m, ip3, jp3);
ACOPERIRE(S, i4, j4, m, ip4, jp4);

TEMA 4. METODA DIVIDE ET IMPERA

163

Apel: ACOPERIRE(S, 1, 1, n, ip, jp).


Propozitia 4.6.1. Algoritmul 4.6.1 are complexitatea (n2 ).
Demonstratie. Fie T (n) timpul de executie al algoritmului. Vom aplica Teorema Master. Conform descrierii recursive a algoritmului, timpul de executie
T (n) verifica relatia de recurenta
T (n) = 4T (n/2) + O (1), n > 2.
Conform Cazului 1 al Teoremei Master, pentru
a = 4, b = 2, c = 0 < 2 = logb a,
rezulta ca T (n) = (n2 ).
Observatia 4.6.1. Evident, orice algoritm care rezolva problema data necesita
cel putin n2 1 instructiuni de atribuire, pentru completarea elementelor
matricei S, deci conform propozitiei anterioare rezulta ca Algoritmul 4.6.1
este asimptotic-optim.

Tema 5
Metoda program
arii dinamice
5.1

Descrierea metodei. Algoritm general

Ca si metoda Divide et Impera, metoda program


arii dinamice implica
rezolvarea unei probleme prin descompunerea n subprobleme de acelasi tip
de dimensiuni mai mici, dar de aceasta data subproblemele nu sunt disjuncte
(ca la metoda Divide et Impera), ci se pot suprapune, n sensul ca doua
subprobleme pot avea (sub)subprobleme comune.
Solutia problemei se construieste combinand solutiile subproblemelor, numite si subsolutii (solutii partiale).
Metoda se adreseaza problemelor de optimizare care ndeplinesc principiul optimalit
atii al lui Bellman: orice subsolutie a unei solutii optime
este la randul ei o solutie optima pentru subproblema corespondenta.
De regula, subproblemele se rezolva n ordinea crescatoare a dimensiunii lor (strategia bottom-up), iar, pentru a evita repetarea procesului de
calcul necesar rezolvarii aceleiasi subprobleme, solutiile subproblemelor se
memoreaza temporar (de obicei n structuri de date de tip tablouri) pentru
reutilizari la posibile viitoare apeluri ale acestor subprobleme.
Solutiile optime ale problemelor se exprima n functie de solutiile optime
ale subproblemelor lor, de obicei prin intermediul unor relatii de recurent
a,
si astfel determinarea solutiilor optime revine la scrierea si rezolvarea acestor
relatii de recurenta.
Relatiile de recurenta pot fi rezolvate si prin implementari recursive, n
care solutia optima a problemei apeleaza solutiile optime ale subproblemelor
(de dimensiuni mai mici, strategia top-down), dar n acest caz calculul
necesar rezolvarii unei aceleiasi subprobleme poate fi reluat de foarte multe
ori prin apelarea repetata a acesteia, ceea ce conduce frecvent la un timp de
calcul exponential.

164


TEMA 5. METODA PROGRAMARII
DINAMICE

165

Deci este de preferat ca relatiile de recurenta sa fie rezolvate prin implementari nerecursive, utilizand strategia bottom-up, cu memorarea temporara
a solutiilor optime ale subproblemelor.
Prezentam o schema generala de lucru:
Problema data se descompune n subprobleme de acelasi tip, dar de
dimensiuni mai mici.
Se alege o structura de date n care se memoreaza solutiile optime ale
problemei si subproblemelor.
Se determina relatia de recurenta ce caracterizeaza solutia optima.
Se rezolva relatia de recurenta prin strategia bottom-up.
Observatia 5.1.1. Presupunem ca solutiile optime ale subproblemelor sunt
memorate ntr-un tablou
S = (S[i1 , . . . , ir ])(i1 ,...,ir )I1 Ir .
a) Daca relatia de recurenta ce caracterizeaza solutia optima exprima
elementul S[i1 , . . . , ir ] n functie de elemente urmatoare
S[j1 , . . . , jr ], (j1 , . . . , jr ) (i1 , . . . , ir )
(conform ordinii lexicografice), atunci calculul acestor elemente se face n
ordinea inversa, descrescatoare, a indicilor (i1 , . . . , ir ). Aceasta abordare este
denumita si programare dinamica n varianta napoi.
b) Daca relatia de recurenta ce caracterizeaza solutia optima exprima
elementul S[i1 , . . . , ir ] n functie de elemente anterioare
S[j1 , . . . , jr ], (j1 , . . . , jr ) (i1 , . . . , ir )
(conform ordinii lexicografice), atunci calculul acestor elemente se face n
ordinea directa, crescatoare, a indicilor (i1 , . . . , ir ). Aceasta abordare este
denumita si programare dinamica n varianta nainte.

5.2

Problema subsirului cresc


ator de lungime
maxim
a

Problema subsirului cresc


ator de lungime maxim
a este urmatoarea:


TEMA 5. METODA PROGRAMARII
DINAMICE

166

Se considera un sir de numere reale


a1 , a2 , . . . , an , n 1.
Se cere sa se determine un subsir crescator de lungime maxima, adica un
subsir
ai1 ai2 aik
(1 i1 < i2 < < ik n) cu k= maxim.
Exemplul 5.2.1. De exemplu, pentru sirul
10, 16, 2, 8, 4, 10, 3, 4, 9, 8
lungimea maxima a unui subsir crescator este egala cu 4 (nu exista subsiruri
crescatoare de lungime 5), iar un subsir crescator de lungime maxima este,
de exemplu,
2, 3, 4, 8.
Modelarea problemei
Metoda 1) Utilizam programarea dinamica, varianta napoi. Consideram
subproblemele constand n determinarea a cate unui subsir crescator de
lungime maxima care ncepe cu elementul ai , pentru orice i {1, 2, . . . , n}.
Pentru memorarea solutiile subproblemelor utilizam doi vectori
L = (L[1], . . . , L[n]) si P = (P [1], . . . , P [n 1]) avand semnificatia
L[i] = lungimea maxima a unui subsir crescator care ncepe cu elementul ai ,
P [i] = indicele primului element care este succesor al lui ai ntr-un subsir
crescator de lungime maxima care ncepe cu ai , daca exista un astfel
de indice,
P [i] = 1, daca nu exista un astfel de indice,
pentru orice i {1, 2, . . . , n}.
Evident,
L[n] = 1
L[i] = max {1 + L[j] | ai aj }, daca exista un astfel de indice j,
j=i+1,n

L[i] = 1, daca nu exista un astfel de indice j,


P [i] = min {j | L[i] = 1 + L[j]}, daca exista un astfel de indice j,
j=i+1,n


TEMA 5. METODA PROGRAMARII
DINAMICE

167

P [i] = 1, daca nu exista un astfel de indice j,


pentru orice i {1, 2, . . . , n 1}.
Relatia de recurenta de mai sus exprima elementul L[i] n functie de
elementele urmatoare L[i + 1], . . . , L[n].
Rezolvarea relatiei de recurenta a elementelor L[i] si calculul elementelor
P [i] conform strategiei bottom-up revine la calculul acestor elemente n ordinea inversa a indicilor, adica
i = n, n 1, . . . , 2, 1.
O solutie a problemei este subsirul
at1 at2 atk
de lungime
k = max L[i],
i=1,n

construit astfel:
t1 = min {i | L[i] = k},
i=1,n

tj = P [tj1 ], j {2, . . . , k}.


Obtinem urmatorul algoritm de programare dinamica n varianta napoi,
descris n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.2.1.


TEMA 5. METODA PROGRAMARII
DINAMICE

168

SUBSIRMAX1(A, n) :
L[n] 1;
for i = n 1, 1, 1 do
L[i] 1;
P [i] 1;
for j = i + 1, n do
if (aj ai ) and (1 + L[j] > L[i]) then
L[i] 1 + L[j];
P [i] j;
k L[1];
t1 1;
for i = 2, n do
if (L[i] > k) then
k L[i];
t1 i;
for j = 2, k do
tj P [tj1];

for j = 1, k do
afiseaz
a atj ;
Exemplul 5.2.2. La aplicarea algoritmului anterior pentru sirul din Exemplul
5.2.1 avem n = 10,
L[10] = 1;
L[9] = 1,
L[8] = 2,
L[7] = 3,
L[6] = 1,
L[5] = 3,
L[4] = 2,
L[3] = 4,
L[2] = 1,
L[1] = 2,

P [9] = 1;
P [8] = 9;
P [7] = 8;
P [6] = 1;
P [5] = 8;
P [4] = 6;
P [3] = 5;
P [2] = 1;
P [1] = 2,

deci lungimea maxima a unui subsir crescator este


k=4
iar un subsir crescator de lungime maxima este dat de indicii
t1 = 3, t2 = P [t1 ] = 5, t3 = P [t2 ] = 8, t4 = P [t3 ] = 9,


TEMA 5. METODA PROGRAMARII
DINAMICE

169

adica subsirul
2, 4, 4, 9.
Observatia 5.2.1. Instructiunea
if(aj ai ) and (1 + L[j] > L[i])

se executa cate o data pentru fiecare pereche de indici (i, j) cu i {n 1, n


n(n 1)
2, . . . , 1} si j {i + 1, i + 2, . . . , n}, adica de 1 + 2 + + n 1 =
2
ori, deci algoritmul are complexitatea (n2 ).
Observatia 5.2.2. Algoritmul anterior poate fi adaptat pentru determinarea
tuturor subsirurilor crescatoare de lungime maxima. Pentru aceasta, pastrand semnificatia si constructia vectorului L, reconsideram semnificatia si
constructia vectorului P astfel:
P [i] = multimea indicilor tuturor elementelor care sunt succesori directi ai
lui ai ntr-un subsir crescator de lungime maxima care ncepe cu ai
(posibil vida), pentru orice i {1, 2, . . . , n 1}. Evident,
P [i] = {j = i + 1, n | L[i] = 1 + L[j]}, i {1, 2, . . . , n 1}.
Orice solutie a problemei este un subsir de forma
at1 at2 atk
de lungime
k = max L[i],
i=1,n

construit astfel:
t1 {i = 1, n | L[i] = k},
tj P [tj1], j {2, . . . , k}.
Pentru generarea tuturor acestor vectori (t1 , t2 , . . . , tk ) se poate utiliza metoda
Backtracking.


TEMA 5. METODA PROGRAMARII
DINAMICE

170

De exemplu, pentru sirul din Exemplul 5.2.1 avem


L[10] = 1;
L[9] = 1,
L[8] = 2,
L[7] = 3,
L[6] = 1,
L[5] = 3,
L[4] = 2,
L[3] = 4,
L[2] = 1,
L[1] = 2,

P [9] = ;
P [8] = {9, 10};
P [7] = {8};
P [6] = ;
P [5] = {8};
P [4] = {6, 9, 10};
P [3] = {5, 7};
P [2] = ;
P [1] = {2, 6},

deci lungimea maxima a unui subsir crescator este k = 4 iar orice subsir
crescator de lungime maxima este dat de indicii
t1 {3}, t2 P [t1 ], t3 P [t2 ], t4 P [t3 ].
Obtinem ca subsirurile crescatoare de lungime maxima sunt
(a3 = 2, a5 = 4, a8 = 4, a9 = 9), (a3 = 2, a5 = 4, a8 = 4, a10 = 8),
(a3 = 2, a7 = 3, a8 = 4, a9 = 9), (a3 = 2, a7 = 3, a8 = 4, a10 = 8),
deci avem 4 solutii (subsiruri crescatoare de lungime maxima).
Metoda 2) Utilizam programarea dinamica, varianta nainte. Consideram
subproblemele constand n determinarea a cate unui subsir crescator de
lungime maxima care se ncheie cu elementul ai , pentru orice i {1, 2, . . . , n}.
Pentru memorarea solutiile subproblemelor utilizam din nou doi vectori
L = (L[1], . . . , L[n]) si P = (P [2], . . . , P [n]) avand acum semnificatia
L[i] = lungimea maxima a unui subsir crescator care se ncheie cu
elementul ai ,
P [i] = indicele primului element care este predecesor al lui ai ntr-un
subsir crescator de lungime maxima care se ncheie cu ai , daca
exista un astfel de indice,
P [i] = 1, daca nu exista un astfel de indice,
pentru orice i {1, 2, . . . , n}.
Evident,
L[1] = 1,


TEMA 5. METODA PROGRAMARII
DINAMICE

171

L[i] = max {1 + L[j] | aj ai }, daca exista un astfel de indice j,


j=1,i1

L[i] = 1, daca nu exista un astfel de indice j,


P [i] = min {j | L[i] = 1 + L[j]}, daca exista un astfel de indice j,
j=1,i1

P [i] = 1, daca nu exista un astfel de indice j,


pentru orice i {2, 3, . . . , n}.
Relatia de recurenta de mai sus exprima elementul L[i] n functie de
elementele anterioare L[1], . . . , L[i 1].
Rezolvarea relatiei de recurenta a elementelor L[i] si calculul elementelor
P [i] conform strategiei bottom-up revine la calculul acestor elemente n ordinea directa a indicilor, adica
i = 1, 2, . . . , n 1, n.
O solutie a problemei este subsirul
at1 at2 atk
de lungime
k = max L[i],
i=1,n

construit astfel:
tk = min {i | L[i] = k},
i=1,n

tj = P [tj+1], j {k 1, . . . , 1}.
Obtinem urmatorul algoritm de programare dinamica n varianta nainte,
descris n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.2.2.


TEMA 5. METODA PROGRAMARII
DINAMICE

172

SUBSIRMAX2(A, n) :
L[1] 1;
for i = 2, n do
L[i] 1;
P [i] 1;
for j = 1, i 1 do
if (aj ai ) and (1 + L[j] > L[i]) then
L[i] 1 + L[j];
P [i] j;
k L[1];
m 1;
for i = 2, n do
if (L[i] > k) then
k L[i];
m i;

// k = max{i = 1, n | L[i]}
// m = min{i = 1, n | L[i] = k}

tk m;
for j = k 1, 1, 1 do
tj P [tj+1];
for j = 1, k do
afiseaz
a atj ;

Exemplul 5.2.3. La aplicarea algoritmului anterior pentru sirul din Exemplul


5.2.1 avem n = 10,
L[1] = 1;
L[2] = 2,
L[3] = 1,
L[4] = 2,
L[5] = 2,
L[6] = 3,
L[7] = 2,
L[8] = 3,
L[9] = 4,
L[10] = 4,

P [2] = 1;
P [3] = 1;
P [4] = 3;
P [5] = 3;
P [6] = 4;
P [7] = 3;
P [8] = 5;
P [9] = 8;
P [10] = 8,

deci lungimea maxima a unui subsir crescator este


k=4


TEMA 5. METODA PROGRAMARII
DINAMICE

173

iar un subsir crescator de lungime maxima este at1 at2 atk dat de
indicii
t4 = 9, t3 = P [t4 ] = 8, t2 = P [t3 ] = 5, t1 = P [t2 ] = 3,
adica subsirul
2, 4, 4, 9.
Observatia 5.2.3. Analog algoritmului de la Metoda 1, si algoritmul anterior
are complexitatea (n2 ).
Observatia 5.2.4. Printr-un procedeu similar celui descris n Observatia 5.2.2,
si algoritmul anterior poate fi adaptat pentru determinarea tuturor subsirurilor crescatoare de lungime maxima.

5.3

Problema drumurilor de sum


a
maxim
a/minim
a ntr-o matrice

Problema drumului de sum


a maxim
a/minim
a ntr-o matrice este
urmatoarea:
Se considera o matrice de numere reale
A = (aij ) i = 1, m , m, n N .
j = 1, n

Se cere ca dintre toate drumurile care ncep cu un element de pe prima


linie, coboara de fiecare data pe verticala sau pe diagonala la un element
de pe linia urmatoare si se ncheie cu un element de pe ultima linie, sa se
determine un drum pentru care suma elementelor parcurse este:
a) maxima;
b) minima.
Exemplul 5.3.1. De exemplu, pentru matricea

40 30 10 35 20 25

45 30 40 30 40 45

20 25 50 50 20 10

A=

10
15
20
35
15
30

40 50 60 55 65 80

40 20

15

20

10

10

un drum de suma maxima este format din elementele ncadrate n cercuri,


avand suma 240.


TEMA 5. METODA PROGRAMARII
DINAMICE

174

Pentru aceeasi matrice, un drum de suma minima este format din elementele ncadrate n patrate, avand suma 135.
Modelarea problemei
a) Consideram problema drumului de suma maxima.
Metoda 1) Utilizam programarea dinamica, varianta napoi. Consideram
subproblemele constand n determinarea a cate unui drum de suma maxima
care ncepe cu elementul aij (si se ncheie cu un element de pe ultima linie),
pentru orice i {1, 2, . . . , m} si orice j {1, 2, . . . , n}.
Pentru memorarea solutiile subproblemelor utilizam doua matrice S =
(S[i, j]) i = 1, m si P = (P [i, j]) i = 1, m 1 avand semnificatia
j = 1, n

j = 1, n

S[i, j] = suma maxima a unui drum de la aij la ultima linie,

1, daca exista un drum de suma maxima de la aij la ultima

linie avand al doilea element pe ai+1,j1 (adica prima

coborare are forma ),

0,
daca exista un drum de suma maxima de la aij la ultima

linie avand al doilea element pe ai+1,j (adica prima

coborare are forma ) si nu exista un drum de suma

maxima de la aij la ultima linie avand al doilea element


P [i, j] =

pe ai+1,j1,

1, daca exista un drum de suma maxima de la aij la ultima

linie avand al doilea element pe ai+1,j+1 (adica prima

coborare are forma ) si nu exista un drum de suma

maxima de la aij la ultima linie avand al doilea element

pe ai+1,j1 sau pe ai+1,j .


Evident,

S[m, j] = amj , j {1, . . . , n}


si pentru orice i {1, . . . , m 1} avem
S[i, 1] = ai1 + max{S[i + 1, 1], S[i + 1, 2]},
(
0, daca S[i + 1, 1] S[i + 1, 2],
P [i, 1] =
1, daca S[i + 1, 1] < S[i + 1, 2],


TEMA 5. METODA PROGRAMARII
DINAMICE

175

S[i, j] = aij + max{S[i + 1, j 1], S[i + 1, j], S[i + 1, j + 1]},


j {2, . . . , n 1}

1, daca S[i + 1, j 1] S[i + 1, j] si

S[i + 1, j 1] S[i + 1, j + 1],

0, daca S[i + 1, j] > S[i + 1, j 1] si


P [i, j] =

S[i + 1, j] S[i + 1, j + 1],

1, daca S[i + 1, j + 1] > S[i + 1, j 1] si

S[i + 1, j + 1] > S[i + 1, j],


j {2, . . . , n 1}

S[i, n] = ain + max{S[i + 1, n 1], S[i + 1, n]},


(
1, daca S[i + 1, n 1] S[i + 1, n],
P [i, n] =
0, daca S[i + 1, n 1] < S[i + 1, n].
Relatiile de recurenta de mai sus exprima elementul S[i, j] n functie de
elementele de pe linia urmatoare S[i + 1, j 1], S[i + 1, j], S[i + 1, j + 1].
Rezolvarea relatiei de recurenta a elementelor S[i, j] si calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente n ordinea inversa a liniilor, adica
i = m, m 1, . . . , 2, 1.
O solutie a problemei este drumul
a1t1 , a2t2 , . . . , amtm
de suma
M = max S[1, j],
j=1,n

construit astfel:
t1 = min {j | S[1, j] = M},
j=1,n

ti = ti1 + P [i 1, ti1 ], i {2, . . . , m}.


Obtinem urmatorul algoritm de programare dinamica n varianta napoi,
descris n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.3.1.


TEMA 5. METODA PROGRAMARII
DINAMICE

176

DRUMMAX1(A, m, n) :
for j = 1, n do S[m, j] amj ;
for i = m 1, 1, 1 do
P [i, 1] 0;
if S[i + 1, 2] > S[i + 1, 1] then P [i, 1] 1;
S[i, 1] ai1 + S[i + 1, 1 + P [i, 1]];
for j = 2, n 1 do
P [i, j] 1;
if S[i + 1, j] > S[i + 1, j 1] then P [i, j] 0;
if S[i + 1, j + 1] > S[i + 1, j + P [i, j]] then P [i, j] 1;
S[i, j] aij + S[i + 1, j + P [i, j]];
P [i, n] 1;
if S[i + 1, n] > S[i + 1, n 1] then P [i, n] 0;
S[i, n] ain + S[i + 1, n + P [i, n]];
M S[1, 1];
t1 1;
for j = 2, n do
if S[1, j] > M then
M S[1, j];
t1 j;
for i = 2, m do
ti ti1 + P [i 1, ti1 ];
afiseaz
a M;
for i = 1, m do
afiseaz
a aiti ;

// (*)

Exemplul 5.3.2. La aplicarea algoritmului anterior pentru matricea A din


Exemplul 5.3.1 avem

235 235 215 240 225 230


195 195 205 195 205 180

145 150 165 165 135 120

S=
125 105 100 115 105 110 ,

80 90 80 75 85 90
40 20 15 20 10 10

0 1
0 1 0 1
1 1
0 1 1 1

.
0
1
1
0
1
0
P =

1 0 1 1
1
0
0 1 1 0 1 1


TEMA 5. METODA PROGRAMARII
DINAMICE

177

Suma maxima are valoarea


M = max S[1, j] = 240.
j=1,6

Avem
t1 = min {j | S[1, j] = M} = 4,
j=1,6

t2
t3
t4
t5
t6

= t1 + P [1, t1 ] = 4 + P [1, 4] = 4 1 = 3,
= t2 + P [2, t2 ] = 3 + P [2, 3] = 3 + 0 = 3,
= t3 + P [3, t3 ] = 3 + P [3, 3] = 3 + 1 = 4,
= t4 + P [4, t4 ] = 4 + P [4, 4] = 4 + 1 = 5,
= t5 + P [5, t5 ] = 5 + P [5, 5] = 5 1 = 4,

deci drumul de suma maxima produs de algoritm are elementele


a1t1 = a14 = 35, a2t2 = a23 = 40, a3t3 = a33 = 50,
a4t4 = a44 = 30, a5t5 = a55 = 65, a6t6 = a64 = 20.
Observatia 5.3.1. Pentru calculul fiecarui element al matricelor S si P sunt
necesare cate o atribuire si cel mult doua comparatii, deci algoritmul are
complexitatea (mn).
Observatia 5.3.2. Problema poate fi rezolvata si fara utilizarea matricei P .
In acest caz, pentru determinarea unui drum de suma maxima nlocuim
instructiunea () cu urmatoarea secventa de instructiuni:
for i = 1, m 1 do
if (ti > 1) and (S[i + 1, ti 1] = S[i, ti ] aiti ) then
ti+1 ti 1;
// cobor^
are de forma
else
if S[i + 1, ti ] = S[i, ti ] aiti then
ti+1 ti ;
// cobor^
are de forma
else
ti+1 ti + 1;
// cobor^
are de forma
Observatia 5.3.3. Algoritmul 5.3.1 poate fi adaptat pentru determinarea tuturor drumurilor de suma maxima. Pentru aceasta, pastrand semnificatia si
constructia matricei S, reconsideram semnificatia si constructia matricei P
astfel:
n
P [i, j] = k {1, 0, 1} | exista un drum de suma maxima de la aij
o
la ultima linie avand al doilea element pe ai+1,j+k ,


TEMA 5. METODA PROGRAMARII
DINAMICE

178

pentru orice i {1, 2, . . . , m 1} si orice j {1, 2, . . . , n} .


Evident, pentru orice i {1, 2, . . . , m 1} avem
n
o
P [i, 1] = k {0, 1} | ai+1,1+k = max{ai+1,1 , ai+1,2 } ,
n
o
P [i, j] = k {1, 0, 1} | ai+1,j+k = max{ai+1,j1 , ai+1,j , ai+1,j+1} ,
j {2, . . . , n 1},
n
o
P [i, n] = k {1, 0} | ai+1,n+k = max{ai+1,n1 , ai+1,n } .

Orice solutie a problemei este un drum de forma


a1t1 , a2t2 , . . . , amtm
de suma
M = max S[1, j],
j=1,n

construit astfel:
t1 {j = 1, n | S[1, j] = M},
ti {ti1 + k | k P [i 1, ti1 ]}, i {2, . . . , m}.
Pentru generarea tuturor acestor vectori (t1 , t2 , . . . , tm ) se poate utiliza metoda
Backtracking.
De exemplu, pentru matricea A din Exemplul 5.3.1 avem

235 235 215 240 225 230


195 195 205 195 205 180

145 150 165 165 135 120

S=
125 105 100 115 105 110 ,

80 90 80 75 85 90
40 20 15 20 10 10

{0, 1} {1}
{0}
{1, 1} {0}
{1}
{1}
{1}
{0, 1} {1, 0} {1} {1}

.
{0}
{1}
{1}
{0}
{1}
{0}
P =

{1}
{0}
{1}
{1}
{1}
{0}
{0} {1} {1, 1}
{0}
{1} {1, 0}


TEMA 5. METODA PROGRAMARII
DINAMICE

179

Suma maxima are valoarea M = max S[1, j] = 240. Avem


j=1,6

t1 {j = 1, 6 | S[1, j] = M} = {4},
t2 {4 + k | k P [1, 4]} = {3, 5},
pentru t2 = 3 : t3 {3 + k | k P [2, 3]} = {3, 4},
pentru t2 = 5 : t3 {5 + k | k P [2, 5]} = {4},
pentru t3 = 3 : t4 {3 + k | k P [3, 3]} = {4},
pentru t3 = 4 : t4 {4 + k | k P [3, 4]} = {4},
t5 {4 + k | k P [4, 4]} = {5},
t6 {5 + k | k P [5, 5]} = {4},
deci drumurile de suma maxima sunt
(a14 = 35, a23 = 40, a33 = 50, a44 = 30, a55 = 65, a64 = 20),
(a14 = 35, a23 = 40, a34 = 50, a44 = 30, a55 = 65, a64 = 20),
(a14 = 35, a25 = 40, a34 = 50, a44 = 30, a55 = 65, a64 = 20),
deci avem 3 solutii (drumuri de suma maxima).
Metoda 2) Utilizam programarea dinamica, varianta nainte. Consideram
subproblemele constand n determinarea a cate unui drum de suma maxima
care se ncheie cu elementul aij (si se ncepe cu un element de pe prima linie),
pentru orice i {1, 2, . . . , m} si orice j {1, 2, . . . , n}.
Pentru memorarea solutiile subproblemelor utilizam din nou doua matrice
S = (S[i, j]) i = 1, m si P = (P [i, j]) i = 1, m 1 avand acum semnificatia
j = 1, n

j = 1, n

S[i, j] = suma maxima a unui drum de la prima linie la aij ,

1, daca exista un drum de suma maxima de la prima

linie la aij avand penultimul element pe ai1,j1

(adica ultima coborare are forma ),

0, daca exista un drum de suma maxima de la prima

linie la aij avand penultimul element pe ai1,j

(adica ultima coborare are forma ) si nu exista un

drum de suma maxima de la prima linie la aij avand


P [i 1, j] =

penultimul element pe ai1,j1 ,

1, daca exista un drum de suma maxima de la prima

linie la aij avand penultimul element pe ai1,j+1

(adica ultima coborare are forma ) si nu exista un

drum de suma maxima de la prima linie la aij avand

penultimul element pe ai1,j1 sau pe ai1,j .


TEMA 5. METODA PROGRAMARII
DINAMICE

180

Evident,
S[1, j] = a1j , j {1, . . . , n}
si pentru orice i {2, . . . , m} avem
S[i, 1] = ai1 + max{S[i 1, 1], S[i 1, 2]},
(
0, daca S[i 1, 1] S[i 1, 2],
P [i 1, 1] =
1, daca S[i 1, 1] < S[i 1, 2],
S[i, j] = aij + max{S[i 1, j 1], S[i 1, j], S[i 1, j + 1]},
j {2, . . . , n 1}

1, daca S[i 1, j 1] S[i 1, j] si

S[i 1, j 1] S[i 1, j + 1],

0, daca S[i 1, j] > S[i 1, j 1] si


P [i 1, j] =

S[i 1, j] S[i 1, j + 1],

1, daca S[i 1, j + 1] > S[i 1, j 1] si

S[i 1, j + 1] > S[i 1, j],


j {2, . . . , n 1}

S[i, n] = ain + max{S[i 1, n 1], S[i 1, n]},


(
1, daca S[i 1, n 1] S[i 1, n],
P [i 1, n] =
0, daca S[i 1, n 1] < S[i 1, n].
Relatiile de recurenta de mai sus exprima elementul S[i, j] n functie de
elementele de pe linia anterioara S[i 1, j 1], S[i 1, j], S[i 1, j + 1].
Rezolvarea relatiei de recurenta a elementelor S[i, j] si calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente n ordinea directa a liniilor, adica
i = 1, 2, . . . , m 1, m.
O solutie a problemei este drumul
a1t1 , a2t2 , . . . , amtm
de suma
M = max S[m, j],
j=1,n


TEMA 5. METODA PROGRAMARII
DINAMICE

181

construit astfel:
tm = min {j | S[m, j] = M},
j=1,n

ti = ti+1 P [i, ti+1 ], i {1, . . . , m 1}.


Obtinem urmatorul algoritm de programare dinamica n varianta nainte,
descris n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.3.2.
DRUMMAX2(A, m, n) :
for j = 1, n do S[1, j] a1j ;
for i = 1, m 1 do
P [i, 1] 0;
if S[i, 2] > S[i, 1] then P [i, 1] 1;
S[i + 1, 1] ai+1,1 + S[i, 1 P [i, 1]];
for j = 2, n 1 do
P [i, j] 1;
if S[i, j] > S[i, j 1] then P [i, j] 0;
if S[i, j + 1] > S[i, j P [i, j]] then P [i, j] 1;
S[i + 1, j] ai+1,j + S[i, j P [i, j]];
P [i, n] 1;
if S[i, n] > S[i, n 1] then P [i, n] 0;
S[i + 1, n] ai+1,n + S[i, n P [i, n]];
M S[m, 1];
tm 1;
for j = 2, n do
if S[m, j] > M then
M S[m, j];
tm j;
for i = m 1, 1, 1 do
ti ti+1 P [i, ti+1 ];
afiseaz
a M;
for i = 1, m do
afiseaz
a aiti ;

// (*)

Exemplul 5.3.3. La aplicarea algoritmului anterior pentru matricea A din


TEMA 5. METODA PROGRAMARII
DINAMICE

182

Exemplul 5.3.1 avem

S=

P =

40
85
105
145
185
235

30
70
110
140
195
235

10
75
125
135
215
230

35 20 25
65 75 70
125 95 85
155 140 115
210 220 220
240 230 230

0
1 1 0 1 0
0
1
0
1 0 1

1 1 0
1 1 1
.
0
1 1 0 1 1
1 1 0 1 0 1

Suma maxima are valoarea

M = max S[6, j] = 240.


j=1,6

Avem
t6 = min {j | S[6, j] = M} = 4,
j=1,6

t5
t4
t3
t2
t1

= t6 P [5, t6 ] = 4 P [5, 4] = 4 + 1 = 5,
= t5 P [4, t5 ] = 5 P [4, 5] = 5 1 = 4,
= t4 P [3, t4 ] = 4 P [3, 4] = 4 1 = 3,
= t3 P [2, t3 ] = 3 P [2, 3] = 3 0 = 3,
= t2 P [1, t2 ] = 3 P [1, 3] = 3 + 1 = 4,

deci drumul de suma maxima produs de algoritm are elementele


a1t1 = a14 = 35, a2t2 = a23 = 40, a3t3 = a33 = 50,
a4t4 = a44 = 30, a5t5 = a55 = 65, a6t6 = a64 = 20.
Observatia 5.3.4. Analog algoritmului de la Metoda 1, si algoritmul anterior
are complexitatea (mn).
Observatia 5.3.5. Problema poate fi rezolvata, din nou, si fara utilizarea
matricei P . In acest caz, pentru determinarea unui drum de suma maxima
nlocuim instructiunea () cu urmatoarea secventa de instructiuni:


TEMA 5. METODA PROGRAMARII
DINAMICE

183

for i = m, 2, 1 do
if (ti > 1) and (S[i 1, ti 1] = S[i, ti ] aiti ) then
ti1 ti 1;
// cobor^
are de forma
else
if S[i 1, ti ] = S[i, ti ] aiti then
ti1 ti ;
// cobor^
are de forma
else
ti1 ti + 1;
// cobor^
are de forma
Observatia 5.3.6. Analog Algoritmului 5.3.1, si Algoritmul 5.3.2 poate fi
adaptat pentru determinarea tuturor drumurilor de suma maxima.

b) Consideram problema drumului de suma minima.


Metoda 1) Utilizam programarea dinamica, varianta napoi. Consideram
subproblemele constand n determinarea a cate unui drum de suma minima
care ncepe cu elementul aij (si se ncheie cu un element de pe ultima linie),
pentru orice i {1, 2, . . . , m} si orice j {1, 2, . . . , n}.
Pentru memorarea solutiile subproblemelor utilizam doua matrice S =
(S[i, j]) i = 1, m si P = (P [i, j]) i = 1, m 1 avand semnificatia
j = 1, n

j = 1, n

S[i, j] = suma minima a unui drum de la aij la ultima linie,

1, daca exista un drum de suma minima de la aij la ultima

linie avand al doilea element pe ai+1,j1 (adica prima

coborare are forma ),

0,
daca exista un drum de suma minima de la aij la ultima

linie avand al doilea element pe ai+1,j (adica prima

coborare are forma ) si nu exista un drum de suma

minima de la aij la ultima linie avand al doilea element


P [i, j] =

pe ai+1,j1 ,

1,
daca exista un drum de suma minima de la aij la ultima

linie avand al doilea element pe ai+1,j+1 (adica prima

coborare are forma ) si nu exista un drum de suma

minima de la aij la ultima linie avand al doilea element

pe ai+1,j1 sau pe ai+1,j .


Evident,

S[m, j] = amj , j {1, . . . , n}


TEMA 5. METODA PROGRAMARII
DINAMICE

184

si pentru orice i {1, . . . , m 1} avem


S[i, 1] = ai1 + min{S[i + 1, 1], S[i + 1, 2]},
(
0, daca S[i + 1, 1] S[i + 1, 2],
P [i, 1] =
1, daca S[i + 1, 1] > S[i + 1, 2],
S[i, j] = aij + min{S[i + 1, j 1], S[i + 1, j], S[i + 1, j + 1]},
j {2, . . . , n 1}

1, daca S[i + 1, j 1] S[i + 1, j] si

S[i + 1, j 1] S[i + 1, j + 1],

0, daca S[i + 1, j] < S[i + 1, j 1] si


P [i, j] =

S[i + 1, j] S[i + 1, j + 1],

1, daca S[i + 1, j + 1] < S[i + 1, j 1] si

S[i + 1, j + 1] < S[i + 1, j],


j {2, . . . , n 1}

S[i, n] = ain + min{S[i + 1, n 1], S[i + 1, n]},


(
1, daca S[i + 1, n 1] S[i + 1, n],
P [i, n] =
0, daca S[i + 1, n 1] > S[i + 1, n].
Relatiile de recurenta de mai sus exprima elementul S[i, j] n functie de
elementele de pe linia urmatoare S[i + 1, j 1], S[i + 1, j], S[i + 1, j + 1].
Rezolvarea relatiei de recurenta a elementelor S[i, j] si calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente n ordinea inversa a liniilor, adica
i = m, m 1, . . . , 2, 1.
O solutie a problemei este drumul
a1t1 , a2t2 , . . . , amtm
de suma
M = min S[1, j],
j=1,n

construit astfel:
t1 = min {j | S[1, j] = M},
j=1,n


TEMA 5. METODA PROGRAMARII
DINAMICE

185

ti = ti1 + P [i 1, ti1 ], i {2, . . . , m}.


Obtinem urmatorul algoritm de programare dinamica n varianta napoi,
descris n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.3.3.
DRUMMIN1(A, m, n) :
for j = 1, n do S[m, j] amj ;
for i = m 1, 1, 1 do
P [i, 1] 0;
if S[i + 1, 2] < S[i + 1, 1] then P [i, 1] 1;
S[i, 1] ai1 + S[i + 1, 1 + P [i, 1]];
for j = 2, n 1 do
P [i, j] 1;
if S[i + 1, j] < S[i + 1, j 1] then P [i, j] 0;
if S[i + 1, j + 1] < S[i + 1, j + P [i, j]] then P [i, j] 1;
S[i, j] aij + S[i + 1, j + P [i, j]];
P [i, n] 1;
if S[i + 1, n] < S[i + 1, n 1] then P [i, n] 0;
S[i, n] ain + S[i + 1, n + P [i, n]];
M S[1, 1];
t1 1;
for j = 2, n do
if S[1, j] < M then
M S[1, j];
t1 j;
for i = 2, m do
ti ti1 + P [i 1, ti1 ];
afiseaz
a M;
for i = 1, m do
afiseaz
a aiti ;

// (*)

Exemplul 5.3.4. La aplicarea algoritmului anterior pentru matricea A din


Exemplul 5.3.1 avem

165 155 135 165 150 155


140 125 140 130 130 135

95 100 125 125 100 90

S=
95 75 75 95 80 95 ,

60 65 75 65 75 90
40 20 15 20 10 10


TEMA 5. METODA PROGRAMARII
DINAMICE

P =

Suma minima are valoarea

1 0 1 0 1 1
0 1 1 1
1
0
1 0 1 1 0 1
0 1 1 0 1 1
1 1
0
1
0 1

186

M = min S[1, j] = 135.


j=1,6

Avem
t1 = min {j | S[1, j] = M} = 3,
j=1,6

t2
t3
t4
t5
t6

= t1 + P [1, t1 ] = 3 + P [1, 3] = 3 1 = 2,
= t2 + P [2, t2 ] = 2 + P [2, 2] = 2 1 = 1,
= t3 + P [3, t3 ] = 1 + P [3, 1] = 1 + 1 = 2,
= t4 + P [4, t4 ] = 2 + P [4, 2] = 2 1 = 1,
= t5 + P [5, t5 ] = 1 + P [5, 1] = 1 + 1 = 2,

deci drumul de suma minima produs de algoritm are elementele


a1t1 = a13 = 10, a2t2 = a22 = 30, a3t3 = a31 = 20,
a4t4 = a42 = 15, a5t5 = a51 = 40, a6t6 = a62 = 20.
Observatia 5.3.7. Problema poate fi rezolvata si fara utilizarea matricei P .
In acest caz, pentru determinarea unui drum de suma minima nlocuim
instructiunea () cu secventa de instructiuni din Observatia 5.3.2.
Metoda 2) Utilizam programarea dinamica, varianta nainte. Consideram
subproblemele constand n determinarea a cate unui drum de suma minima
care se ncheie cu elementul aij (si se ncepe cu un element de pe prima linie),
pentru orice i {1, 2, . . . , m} si orice j {1, 2, . . . , n}.
Pentru memorarea solutiile subproblemelor utilizam din nou doua matrice


TEMA 5. METODA PROGRAMARII
DINAMICE

187

S = (S[i, j]) i = 1, m si P = (P [i, j]) i = 1, m 1 avand acum semnificatia


j = 1, n

j = 1, n

S[i, j] = suma minima a unui drum de la prima linie la aij ,

1, daca exista un drum de suma minima de la prima

linie la aij avand penultimul element pe ai1,j1

(adica ultima coborare are forma ),

0,
daca exista un drum de suma minima de la prima

linie la aij avand penultimul element pe ai1,j

(adica ultima coborare are forma ) si nu exista un

drum de suma minima de la prima linie la aij avand


P [i 1, j] =

penultimul element pe ai1,j1,

1,
daca exista un drum de suma minima de la prima

linie la aij avand penultimul element pe ai1,j+1

(adica ultima coborare are forma ) si nu exista un

drum de suma minima de la prima linie la aij avand

penultimul element pe ai1,j1 sau pe ai1,j .


Evident,

S[1, j] = a1j , j {1, . . . , n}

si pentru orice i {2, . . . , m} avem

S[i, 1] = ai1 + min{S[i 1, 1], S[i 1, 2]},


(
0, daca S[i 1, 1] S[i 1, 2],
P [i 1, 1] =
1, daca S[i 1, 1] > S[i 1, 2],

S[i, j] = aij + min{S[i 1, j 1], S[i 1, j], S[i 1, j + 1]},


j {2, . . . , n 1}

1, daca S[i 1, j 1] S[i 1, j] si

S[i 1, j 1] S[i 1, j + 1],

0, daca S[i 1, j] < S[i 1, j 1] si


P [i 1, j] =

S[i 1, j] S[i 1, j + 1],

1, daca S[i 1, j + 1] < S[i 1, j 1] si

S[i 1, j + 1] < S[i 1, j],


j {2, . . . , n 1}

S[i, n] = ain + min{S[i 1, n 1], S[i 1, n]},


(
1, daca S[i 1, n 1] S[i 1, n],
P [i 1, n] =
0, daca S[i 1, n 1] > S[i 1, n].


TEMA 5. METODA PROGRAMARII
DINAMICE

188

Relatiile de recurenta de mai sus exprima elementul S[i, j] n functie de


elementele de pe linia anterioara S[i 1, j 1], S[i 1, j], S[i 1, j + 1].
Rezolvarea relatiei de recurenta a elementelor S[i, j] si calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente n ordinea directa a liniilor, adica
i = 1, 2, . . . , m 1, m.
O solutie a problemei este drumul
a1t1 , a2t2 , . . . , amtm
de suma
M = min S[m, j],
j=1,n

construit astfel:
tm = min {j | S[m, j] = M},
j=1,n

ti = ti+1 P [i, ti+1 ], i {1, . . . , m 1}.


Obtinem urmatorul algoritm de programare dinamica n varianta nainte,
descris n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.3.4.


TEMA 5. METODA PROGRAMARII
DINAMICE

189

DRUMMIN2(A, m, n) :
for j = 1, n do S[1, j] a1j ;
for i = 1, m 1 do
P [i, 1] 0;
if S[i, 2] < S[i, 1] then P [i, 1] 1;
S[i + 1, 1] ai+1,1 + S[i, 1 P [i, 1]];
for j = 2, n 1 do
P [i, j] 1;
if S[i, j] < S[i, j 1] then P [i, j] 0;
if S[i, j + 1] < S[i, j P [i, j]] then P [i, j] 1;
S[i + 1, j] ai+1,j + S[i, j P [i, j]];
P [i, n] 1;
if S[i, n] < S[i, n 1] then P [i, n] 0;
S[i + 1, n] ai+1,n + S[i, n P [i, n]];
M S[m, 1];
tm 1;
for j = 2, n do
if S[m, j] < M then
M S[m, j];
tm j;
for i = m 1, 1, 1 do
ti ti+1 P [i, ti+1 ];
afiseaz
a M;
for i = 1, m do
afiseaz
a aiti ;

// (*)

Exemplul 5.3.5. La aplicarea algoritmului anterior pentru matricea A din


Exemplul 5.3.1 avem

40 30 10 35 20 25
75 40 50 40 60 65

60 65 90 90 60 70

S=
95 75 75 90 75 80 ,

115 125 135 130 140 155


155 135 140 150 140 150

1 1 0 1 0 1
1 0 1 0 1 1

.
0
1
1
1
0
1
P =

1 0 1 1 0 1
0 1 1 0 1 1


TEMA 5. METODA PROGRAMARII
DINAMICE

190

Suma minima are valoarea


M = min S[6, j] = 135.
j=1,6

Avem
t6 = min {j | S[6, j] = M} = 2,
j=1,6

t5
t4
t3
t2
t1

= t6 P [5, t6 ] = 2 P [5, 2] = 2 1 = 1,
= t5 P [4, t5 ] = 1 P [4, 1] = 1 + 1 = 2,
= t4 P [3, t4 ] = 2 P [3, 2] = 2 1 = 1,
= t3 P [2, t3 ] = 1 P [2, 1] = 1 + 1 = 2,
= t2 P [1, t2 ] = 2 P [1, 2] = 2 + 1 = 3,

deci drumul de suma minima produs de algoritm are elementele


a1t1 = a13 = 10, a2t2 = a22 = 30, a3t3 = a31 = 20,
a4t4 = a42 = 15, a5t5 = a51 = 40, a6t6 = a62 = 20.
Observatia 5.3.8. Problema poate fi rezolvata, din nou, si fara utilizarea
matricei P . In acest caz, pentru determinarea unui drum de suma minima
nlocuim instructiunea () cu secventa de instructiuni din Observatia 5.3.5.
Observatia 5.3.9. Analog Algoritmului 5.3.1, si Algoritmii 5.3.3 si 5.3.4 au
complexitatea (mn).
De asemenea, ei pot fi adaptati pentru determinarea tuturor drumurilor
de suma minima.

S-ar putea să vă placă și