Sunteți pe pagina 1din 0

Analiza complexitii

Timpul de execuie
Cazul cel mai defavorabil i cazul mediu
Ordinul de complexitate
Capitolul
2




n cadrul acestui capitol vom prezenta cteva detalii referitoare la complexitatea algo-
ritmilor. Vom arta c ordinul de complexitate al unui algoritm depinde de dimensiu-
nea datelor de intrare, vom prezenta noiunile de caz mediu i caz cel mai defavorabil
i vom introduce noiunea de ordin de complexitate.

2.1. Timpul de execuie
Este evident faptul c durata execuiei unui program depinde de dimensiunea i de
particularitile datelor de intrare. De exemplu, putem spune cu certitudine c sortarea
unui ir care conine o mie de numere va dura mai mult dect sortarea unui ir care
conine o sut de numere.
n general, timpul de execuie al unui algoritm crete pe msur ce crete dimensi-
unea datelor de intrare. Din acest motiv, este natural s descriem timpul de execuie al
unui program ca o funcie care depinde de aceast dimensiune.
Totui, conceptele de timp de execuie i dimensiune a datelor de intrare sunt rela-
tiv vagi. n continuare vom defini aceste noiuni din punctul de vedere al analizei
complexitii algoritmilor.

2.1.1. Datele de intrare
Definiia dimensiunii datelor de intrare depinde de problema care trebuie rezolvat. De
exemplu, pentru problema sortrii unui ir de N numere, dimensiunea intrrii este N.
Cea mai des utilizat "msur" a dimensiunii datelor este numrul "obiectelor" care
constituie intrarea. Totui, nu n toate cazurile este utilizat o astfel de msur. De
30


exemplu, pentru adunarea a dou numere, o msur ar putea fi numrul biilor folosii
pentru a reprezenta cele dou numere.
Aadar dimensiunea datelor de intrare este o funcie care depinde de anumite vari-
abile. n foarte multe cazuri avem o singur astfel de variabil, dar exist i situaii n
care sunt necesare mai multe. De exemplu, dac intrarea const n descrierea unui graf
neorientat, putem descrie dimensiunea datelor de intrare n funcie de dou variabile:
numrul nodurilor i numrul muchiilor.

2.1.2. "Msurarea" timpului
n principiu, timpul de execuie al unui program este durata (exprimat n secunde,
milisecunde, nanosecunde etc.) necesar pentru ca programul s preia datele de intra-
re, s efectueze anumite operaii asupra lor i s furnizeze datele de ieire. Evident,
acest timp depinde ntotdeauna de calculatorul pe care este executat programul. Nu ne
putem atepta ca un program care sorteaz un milion de numere s necesite acelai
timp de execuie pe un calculator dotat cu un procesor Pentium II i pe un calculator
dotat cu un procesor Pentium 4.
Chiar i pentru calculatoarele de ultim generaie vom avea timpi de execuie dife-
rii care vor depinde, n primul rnd, de arhitectura i frecvena procesorului. Conside-
rnd din nou exemplul programului care sorteaz un milion de numere, vom obine
timpi de execuie diferii pe calculatoare din familii diferite. Programul nu va rula n
acelai timp pe calculatoare cu procesoare Celeron, Pentium 4, Itanium, Athlon XP,
Athlon 64 sau Opteron.
Chiar dac avem procesoare din aceeai familie, vom observa diferene vizibile
ntre un procesor cu frecvena de 2 GHz i un procesor cu frecvena de 3 GHz.
Chiar dac avem aceeai frecven, vom observa, din nou, diferene ntre un Pen-
tium 4 i un Athlon XP.
De fapt, chiar dac avem acelai tip de procesor i aceeai frecven, pot aprea
unele diferene de timp datorate altor factori cum ar fi: sistemul de operare, cantitatea
de memorie, rata de transfer a discului etc.
n concluzie, msurarea exact a timpului de execuie nu este un criteriu valid pen-
tru a descrie timpul de execuie al unui algoritm.
S-ar putea crede c un algoritm care are nevoie de t secunde pentru a rula pe un
calculator al crui procesor are frecvena de 1 GHz va avea nevoie de t / 2 secunde
pentru a rula pe un calculator al crui procesor are frecvena de 2 GHz. Din nefericire
nici o astfel de presupunere nu este valid, deoarece dublarea frecvenei nu nseamn
dublarea performanelor.
O msur mult mai util a timpului de execuie este dat de numrul pailor ele-
mentari necesari execuiei unui algoritm. Noiunea de pas trebuie definit astfel nct
s nu depind de tipul calculatorului pe care este executat programul.
Cu o oarecare aproximare, putem consider c o linie descris n pseudocod se
execut ntotdeauna n acelai interval de timp. Evident, pentru linii diferite vom avea
2. Analiza complexitii 31


intervale diferite, dar o aceeai linie se va executa ntotdeauna n acelai timp. Exist
cteva argumente mpotriva unei astfel de alegeri. De exemplu, este posibil ca anumite
linii s nu se execute n timp constant. Dac avem o linie n care se precizeaz c se
sorteaz un ir, atunci timpul de execuie al acestei linii va depinde de dimensiunea
irului. Totui, o astfel de linie "ascunde" de fapt o mulime de pai care nu au mai fost
prezentai pentru a simplifica descrierea. De aceea, va trebui s lum n considerare
astfel de cazuri n momentul n care analizm timpii de execuie ai algoritmilor.
Aadar, dac dimensiunea intrrii este n, putem exprima numrul de pai sub forma
unei funcii T(n). Dac algoritmul const ntr-un numr de pai egal cu ptratul valorii
lui n vom avea T(n) = n
2
. Dac, din diverse motive, mai avem nevoie de nc n pai,
vom avea T(n) = n
2
+ n.
De obicei, timpul de execuie al unui algoritm este ntotdeauna acelai pentru date
de intrare identice. Exist i situaii n care intervine nedeterminismul (de exemplu
dac utilizm numere generate aleator), caz n care timpul de execuie poate varia chi-
ar i pentru date de intrare identice.

2.2. Cazul cel mai defavorabil i cazul mediu
Timpul de execuie al unui algoritm nu depinde doar de dimensiunea datelor de intra-
re, ci i de configuraia acestora. De exemplu, pentru a sorta un ir de numere "aproape
sortat" vom avea nevoie, n principiu, de mai puin timp dect pentru un ir "sortat n
ordine invers".
Din acest motiv au fost introduse noiunile de caz mediu i caz cel mai defavorabil.
Timpul de execuie n cazul mediu reprezint o medie a timpilor de execuie pentru
toate configuraiile posibile ale unei intrri de dimensiune dat. Timpul de execuie n
cazul cel mai defavorabil reprezint cel mai mare dintre timpii de execuie corespun-
ztori configuraiilor posibile ale unei intrri de dimensiune dat.
De obicei, n analiza algoritmilor se utilizeaz cazul cel mai defavorabil. Exist trei
motive pentru aceast alegere.
n primul rnd, timpul de execuie n cel mai defavorabil caz reprezint o limit
superioar pentru timpul de execuie corespunztor oricrei configuraii de dimensiune
dat. Este garantat faptul, c pentru nici o configuraie, nu vom avea un timp de execu-
ie mai mare.
n al doilea rnd, n cazul multor algoritmi cazul cel mai defavorabil apare relativ
frecvent. De exemplu, pentru cutarea unei valori ntr-un vector, cazul cel mai defavo-
rabil apare atunci cnd valoarea nu exist, iar o astfel de situaie este destul de frec-
vent.
n al treilea rnd, n marea majoritate a cazurilor, cazul mediu este "aproape la fel
de nefavorabil" ca i cel mai nefavorabil caz. De exemplu, pentru a determina maxi-
mul unui ir, indiferent ce metod aplicm, va trebui ntotdeauna s parcurgem toate
elementele irului.
32


Totui, n anumite situaii, timpul de execuie pentru cazul mediu se poate dovedi
util. Cea mai mare dificultate ntmpinat n momentul n care se ncearc determina-
rea acestui timp este dat de faptul c, n marea majoritate a cazurilor, nu vom putea
determina timpii de execuie pentru toate cazurile pentru ca apoi s calculm o medie.
De aceea, va trebui s estimm o astfel de medie fr a fi siguri c obinem media
exact. n principiu, n acest scop putem considera c orice configuraie a datelor de
intrare are aceleai anse s apar ca i oricare alta. Din nefericire, n practic, aceast
presupunere se dovedete deseori fals.

2.3. Ordinul de complexitate
Funciile obinute pentru timpii de execuie pot fi uneori foarte complicate i, din acest
motiv, devin inutile. Tocmai de aceea a fost introdus ordinul de complexitate al unui
algoritm. Acesta reprezint o caracterizare a funciei respective, o descriere a ordinului
de mrime.
Ordinul de complexitate va indica doar ordinul de mrime al funciei, eliminndu-
se toi termenii care nu sunt importani.
De exemplu, dac avem T(n) = 2 n
2
+ 5 n + 3, ordinul de complexitate va fi
O(n
2
). Din acest exemplu "deducem", n primul rnd, c ordinul de complexitate se
noteaz prin O i se obine prin eliminarea tuturor coeficienilor i a termenilor "neim-
portani".
Noiunea de termen "neimportant" este foarte vag, motiv pentru care vom arta
modul n care putem decide care termen este mai important.
n primul rnd, putem compara doi termeni doar dac n cadrul lor apare aceeai
variabil. Termenul mai "important" este numit termen dominant. n tabelul urmtor
vom prezenta modul n care se stabilete termenul dominant (coeficienii au fost eli-
minai).

Termen dominant Termen "dominat" Condiii
n! a
n
ntotdeauna
a
n
b
n
a > b > 1 sau 0 < b < a < 1
a
n
n
b
ntotdeauna
n
a
n
b
a > b > 0 sau b < a < 0
n
a
n a > 1
n log
a
n a > 1
log
a
n 1 a > 1

Ar putea prea c ar trebui s avem i o linie care s indice c log
a
n "domin" pe
log
b
n dac a > b. Oarecum surprinztor, nu este cazul. Cteva calcule matematice
simple ne arat c toi termenii logaritmici sunt la fel de importani. Avem:
2. Analiza complexitii 33


x c x
a a
x
x
b b
b b
b
a
log log
log
1
log
log
log = = = .
Am notat prin c raportul 1 / log
b
a, pentru a sugera faptul c este o constant. Dato-
rit faptului c valorile constante (coeficienii) nu sunt luai n considerare, o funcie
logaritmic nu poate domina o alt funcie logaritmic. Din acest motiv, pentru descri-
erea ordinului de complexitate nici nu mai este prezent baza logaritmului, notaia fi-
ind O(log n).
n foarte multe situaii putem estima mult mai uor timpii de execuie (i ordinele
de complexitate) pentru anumite seciuni ale algoritmilor. n aceast situaie, este mult
mai uor s determinm ordinul de complexitate al ntregului algoritm, deoarece se
reduc semnificativ calculele necesare.
n continuare vom presupune c funcia f(n) domin funcia g(n). n aceast situaie
vom avea ntotdeauna:
O(f(n)) + O(g(n)) = O(f(n));
O(f(n)) O(g(n)) = O(f(g(n)));
min(O(f(n)), O(g(n))) = O(g(n));
max(O(f(n)), O(g(n))) = O(f(n)).

Pe baza acestor relaii ne va fi mult mai uor s stabilim ordinul de complexitate al
unui algoritm.
De exemplu, presupunem c am reuit s stabilim c ordinul de complexitate al
operaiei de citire a datelor de intrare este O(n), ordinul de complexitate al operaiei de
prelucrare al acestora este O(n
2
) i ordinul de complexitate al operaiei de scriere a
datelor de ieire este O(n). n acest caz, ordinul de complexitate al algoritmului va fi
O(n) + O(n
2
) + O(n) = O(n
2
).

S-ar putea să vă placă și