Documente Academic
Documente Profesional
Documente Cultură
Recursivitate
Complexitate
def factorial(n):
"""
compute the factorial
n is a positive integer
return n!
"""
if n== 0:
return 1
return factorial(n-1)*n
Obs recursiveSum(l[1:]):
l[1:] - creaz o copie a listei l
exerciiu: modificai funcia recursiveSum pentru a evita l[1:]
Recursivitate n Python:
la fiecare apel de metod se creeaz o noua tabel de simboluri (un nou
namespace). Aceast tabel conine valorile pentru parametrii i pentru variabilele
locale
tabela de simboluri este salvat pe stack, cnd apelul se termin tabela se elimin
din stiv
def isPalindrome(str):
"""
verify if a string is a palindrome
str - string
return True if the string is a palindrome False otherwise
"""
dict = locals()
print (id(dict),dict)
if len(str)==0 or len(str)==1:
return True
Dezavantaje:
consum de memorie mai mare
pentru fiecare recursie se creeaz o nou tabel de simboluri
Analiza complexitii
Analiza complexiti studiul eficienei algoritmilor.
sw = StopWatch()
print "fibonacci(", nr, ") =", fibonacci(nr)
print "fibonacci take " +str(sw.stop())+" seconds"
measureFibo(32)
fibonacci2( 32 ) = 3524578
fibonacci2 take 0.0 seconds
fibonacci( 32 ) = 3524578
fibonacci take 1.7610001564 seconds
Eficiena algoritmilor
Eficiena algoritmilor poate fi definit ca fiind cantitatea de resurse utilizate de algoritm (timp,
memorie).
Msurarea eficienei:
analiz matematic a algoritmului - analiz asimptotic
Descrie eficiena sub forma unei funcii matematice.
Estimeaz timpul de execuie pentru toate intrrile posibile.
o analiz empiric a algoritmului
determinarea timpului exact de execuie pentru date specifice
nu putem prezice timpul pentru toate datele de intrare.
Timpul de execuie pentru un algoritm este studiat n relaie cu dimensiunea datelor de intrare.
Estimm timpul de execuie n funcie de dimensiunea datelor.
Realizm o analiz asymptotic. Determinm ordinul de mrime pentru resursa utilizat (timp,
memorie), ne intereseaz n special pentru cazurile n care datele de intrare sunt mari
Complexitate
caz favorabil - datele de intrare care conduc la timp de execuie minim
BC ( A) min E ( I )
best-case complexity (BC): ID
caz defavorabil date de intrare unde avem cel mai mare timp de execuie.
WC ( A) max E ( I )
worst-case complexity (WC): ID
Obs. Dimensiunea datelor (n) este fixat (un numr mare) caz favorabil/caz defavorabil se refer la un
anumit aranjament al datelor de intrare care produc timp minim/maxim
Complexitate timp de execuie
numrm pai (operaii elementare) efectuai (de exemplu numrul de instruciuni, numr de
comparaii, numr de adunri).
numrul de pai nu este un numr fixat, este o funcie, notat T(n), este in funcie de dimensiunea
datelor (n), nu rezult timpul exact de execuie
Se surprinde doar esenialul: cum crete timpul de execuie n funcie de dimensiunea datelor.
Ne ofer ordinea de mrime pentru timpul de execuie (dac n , then 3 n n ).
2 2
putem ignora constante mici dac n aceste constante nu afecteaz ordinea de mrime.
Ex : T (n) 13 n 42 n 2 n log 2 n 3 n
3 2
Definiia 1 (Notaia O , Big-oh). Spunem c T (n) O( f (n)) dac exist c i n0 constante pozitive
Observaii.
T ( n)
lim 13
Dac T (n) 13 n 42 n 2 n log 2 n 3 n , atunci
3 2
1. n n3 . Deci, putem spune c
T ( n) O ( n 3 ) .
2. Notaia O este bun pentru a da o limit superioar unei funcii. Observm, totui, c dac
T (n) O(n3 ) , atunci este i O(n 4 ) , O(n5 ) , etc atta timp ct limita este 0. Din aceast cauz avem
T ( n)
lim
Definiia alternativ: Spunem c T (n) ( f (n)) dac
n f (n) este o constant sau , dar nu 0.
Definiia 3 (Notaia , Big-theta). Spunem c T (n) ( f (n)) dac T (n) O( f (n)) i dac
T (n) ( f (n)) , altfel spus dac exist c1, c2 i n0 constante pozitive (care nu depind de n) astfel nct
Observaii.
1. Timpul de execuie al unui algoritm este ( f (n)) dac i numai dac timpul su de execuie n
cazul cel mai defavorabil este O( f (n)) i timpul su de execuie n cazul cel mai favorabil este
( f (n)) .
2. Notaia O( f (n)) este de cele mai multe ori folosit n locul notaiei ( f (n)) .
T ( n)
lim 13
Dac T (n) 13 n 42 n 2 n log 2 n 3 n , atunci n n . Deci, T (n) (n ) . Acest lucru
3 2 3 3
3.
poate fi dedus i din faptul c T (n) O(n ) i T (n) (n ) .
3 3
Sume
presupunnd c ceea ce este n corpul structurii repetitive (*) se execut n f(i) pai timpul de
execuie al ntregii structuri repetitive poate fi estimat astfel
n
T (n) f (i )
i 1
Se poate observa c, n cazul n care se folosesc bucle imbricate, vor rezulta sume imbricate. n
continuare, vom prezenta cteva dintre sumele uzuale:
Calculul se efectueaz astfel:
se simplific sumele eliminm constantele, separm termenii in sume individuale
facem calculul pentru sumele simplificate.
Exemple cu sume
Analizai complexitatea ca timp de execuie pentru urmtoarele funcii
def f1(n):
s = 0 () = 1 = () ()
for i in range(1,n+1): (=1)
s=s+i Complexitate (Overall complexity) ()
return s
Cazurile Favorabil/Mediu/Defavorabil sunt identice
def f2(n):
i = 0 () = 1 = () ()
while i<=n: (=1)
#atomic operation
i = i + 1 Overall complexity ()
Cazurile Favorabil/Mediu/Defavorabil sunt identice
def f3(l): Caz favorabil:
"""
l list of numbers primul element e numr par: () = 1 (1)
return True if the list contains Caz defavorabil:
an even nr
""" Nu avem numere pare n list: () = ()
poz = 0 Caz mediu:
while poz<len(l) and l[poz]%2 !=0:
poz = poz+1
While poate fi executat 1,2,..n ori (acelai probabilitate).
return poz<len(l) Numrul de pai = numrul mediu de iteraii
() = (1 + 2+. . . +) = ( + 1)2 () ()
Complexitate ()
Exemple cu sume
def f4(n): (2n2) 2n (2n2)
for i in range(1,2*n-2): () = 1= (2n 1)
for j in range(i+2,2*n): (=1) (=+2) (=1)
#some computation
pass (2n2) (2n2) (2n2)
() = 2n 1
(=1) (=1) (=1)
(2n2)
() = 2n 1 (2n 2) (2n 1)2 (2n 2)
(=1)
() = 2n2 3n + 1 (2 ) Overall complexity (2 )
def f5():
for i in range(1,2*n-2):
Caz favorabil: While se execut odat () = (2n2)
(=1) 1=
j = i+1 2n 2 ()
cond = True Caz defavorabil: While executat 2n ( + 1)ori
while j<2*n and cond: (2n2)
#elementary operation () = (2n 1) =. . . = 2n2 3n + 1 (2 )
if someCond: (=1)
cond = False
Caz mediu:Pentru un i fixat While poate fi executat 1,2..2n-i-
1 ori numr mediu de pai: = (1 + 2+. . . +2n 1)2n
1 =. . . = (2n )2
(2n2) (2n2)
() = = (2n )2 =. . . (2 )
(=1) (=1)
Overall complexity (2 )
Formule cu sume:
1 n
i 1 suma constant.
n
n(n 1)
i 2
i 1 suma liniar (progresia aritmetic)
n
n(n 1)(2n 1)
i
i 1
2
6
suma ptratic
n
1
i ln(n) O(1)
i 1 suma armonic
n
c n 1 1
ci c 1
, c 1
i 1 progresia geometric (crete exponenial)
Complexiti uzuale
T (n) O(1) - timp constant. It is a great complexity. This means that the
algorithm takes only constant time.
T (n) O(log 2 log 2 n) - timp foarte rapid (aproape la fel de rapid ca un timp constant)
T ( n) O ( n) - complexitate liniar;
T (n) O(n log 2 n) - este o complexitate faimoas, ntlnit mai ales la sortri
(MergeSort, QuickSort);
T (n) O(2n ), O(n3 ), O(n!) - complexitate exponenial (algoritmii cu astfel de complexiti sunt
practici doar pentru valori mici ale lui n: n 10, n 20 ).
Recurene
O recuren este o formul matematic definit recursiv.
Ex. numrul de noduri (notat N(h)) dintr-un arbore ternar complet de nlime h ar putea fi descris sub
forma urmtoarei formule de recuren:
N (0) 1
N (h) 3 N (h 1) 1, h 1
Explicaia ar fi urmtoarea:
Numrul de noduri dintr-un arbore ternar complet de nlime 0 este 1.
Numrul de noduri dintr-un arbore ternar complet de nlime h se obine ca fiind de 3 ori
numrul de noduri din subarborele de nlime h-1, la care se mai adaug un nod (rdcina
arborelui).
Dac ar fi s rezolvm recurena, am obine c numrul de noduri din arborele ternar complet de
h
N (h) 3h N (0) (1 31 32 ... 3h 1 ) 3i
nlime h este i 0
Exemple
def recursiveSum(l): 1 = 0
"""Compute the sum of numbers Recurrence: () = {( 1) + 1
l - list of number
return the sum of numbers """ () = ( 1) + 1
#base case ( 1) =( 2) + 1
if l==[]: ( 2) =( 3) + 1=>() = + 1 ()
return 0
...= ...
#inductive step
return l[0]+recursiveSum(l[1:]) (1) = (0) + 1
() = 2(1) + 1 + 2 + 22 + 23 +. . . +2(2)
() = 2 1 (2 )
Complexitatea spaiu de memorare
Complexitatea unui algoritm din punct de vedere al spaiului de memorare estimeaz cantitatea
de memorie necesar algoritmului pentru stocarea datelor de intrare, a rezultatelor finale i a
rezultatelor intermediare. Se estimeaz, ca i timpul de execuie al unui algoritm, n notaiile , , .
Toate observaiile referitoare la notaia asimptotic a complexitii ca timp de execuie sunt valabile i
pentru complexitatea ca spaiu de memorare.
Exemplu
Analizai complexitatea ca spaiu de memorare pentru urmtoarele funcii
Calculeaz complexitatea:
dac avem recuren
calculeaz folosind egaliti
altfel
calculeaz folosind sume
Curs 9 Complexitatea algoritmilor
Recursivitate
Complexitate