You are on page 1of 52

1

RECURENTA VERSUS ITERATIE


Facultatea de Matematica si Informatica,
Universitatea din Bucuresti
7 aprilie 2012
2
Noiunea de algoritm = notiune primar.
Exist descrieri i proprieti:
Un algoritm const dintr-o mulime finit de pai, fiecare necesitnd
una sau mai multe operaii.
Pentru a fi implementate pe un calculator, ntr-un anumit limbaj de
programare, aceste operaii trebuie s fie:
definite;
efective.
Caracteristicile algoritmilor
corectitudinea;
finititudinea:;
generalitatea;
completitudinea;
claritatea.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
3
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Studiul algoritmilor cuprinde mai multe aspecte (1):
Elaborarea algoritmilor.
Tehnici de elaborare (reguli) + creativitate (intuiie) = soluie
Exprimarea algoritmilor
- scheme logice, limbaje de tip pseudocod, programe in diferite
limbaje de programare.
- se impune utilizarea unui anumit stil de programare (legat nu de un
anumit limbaj de programare, ci de tipul limbajului i de modul de
abordare)
4
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Studiul algoritmilor cuprinde mai multe
aspecte (2):
Validarea algoritmilor (demonstrarea
matematica a corectitudinii, independent de
implementare).
Analiza algoritmilor. (in general: timpul de
calcul i/sau la memoria necesar)
Testarea programelor :
(i) depanarea (debugging) Cf. E.W.
Djikstra, prin depanare putem evidentia
prezenta erorilor dar nu si absenta lor!
(ii) verificare (profiling)
5
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Incercarea de definire (decada 1930-1940):
Sunt propuse diverse formalisme pentru
notiunea de algoritm:
Functiile -calculabile (Alonzo CHURCH i
Stephen Cole KLEENE);
Masinile Turing (Alan TURING);
Functiile general recursive (Kurt GDEL);
Sistemele Post, inclusiv masina Post-Turing
(Emil Leon POST);
Algoritmii normali Markov (N.N. MARKOV)
Toate teoriile: echivalente
Teza Church-Turing (cele 2 variante)
6
Lambda calculul
O -functie este definit de o lambda-expresie care
exprim aciunea funciei n argumentele ei.
Exemple: funcia f(x)=x+2: x. x + 2 .
numrul f(3): ( x. x+ 2) 3
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
7
Masina Turing
a b a b
unitate de
control
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
8
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
9
Maina Turing
Un sistem( E, I, Q, q
0
, F, o) unde:
E este o mulime finit, nevida numit alfabet de intrare;
I este o mulime finit, nevida numit alfabetul benzii;
E _ I, e I i e E ;
Q este o mulime finit, nevida numit mulimea strilor
masinii;
q
0
e Q este starea iniial;
F _ Q este mulimea strilor finale (de acceptare sau de
respingere);
o: Q x I Q x I x { L , R } este funcia de tranziie, unde L
denota deplasarea la stnga iar R denota deplasarea la
dreapta a cursorului masinii.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
10
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Stephan Cole KLEENE: "The Theory of Recursive
Functions, Approaching its Centennial", Bulletin (New
Series) of the American Mathematical Society, Vol. 5,
No. 1, July 1981:
"prini" teoriei funciilor recursive (inafara lui Kurt Gdel i
Kleene nsui) sunt considerai a fi:
Leopold Kronecker, prin conferina inut pe 21
sept. 1886 n faa Der Deutschen
Naturforscherversammlung zu Berlin (Asociaia
pentru Cercetarea Naturii), cf. H. Weber, Leopold
Kronecker, Math. Ann. 43 (1893), 1-25
Julius Wilhelm Richard Dedekind (18311916),
prin Teorema 126 ("Satz der Definition durch
Induktion") din articolul "Was sind und was sollen
die Zahlen? (Ce sunt i ce ar trebui sa fie
numerele)" publicat n 1888 si prin Definitia 71
(care contine defiinitia axiomatica a N i.e.
axiomele Dedekind-Peano)
11
Exemple de functii primitiv recursive:
a+0 = a
a+succ(x) = succ(a+x)
a 0 = 0
a succ(x) = a x+a
a
0
= 1
a
succ(x)
= a
x
a
unde succ(x)=x+1 .
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
12
Recurenta primitiva
Fie funciile : g : N
n
N , h : N
n+2
N ;
se cere s se construiasc funcia
f : N
n+1
N
care s satisfac urmtoarele dou ecuaii :
(1) f(a
1
,a
2
,, a
n
,0) = g(a
1
,a
2
,, a
n
) ,
(2) f(a
1
,a
2
,, a
n
, x+1) = h(a
1
,a
2
,, a
n
, x , f(a
1
,a
2
,, a
n
, x)) .
Spunem c f este definit prin recuren primitiv asupra lui x din
funciile g i h , prin intermediul a n>=0 parametri a
1
,a
2
,, a
n
.
Convenim ca n cazul n=0 s notm prin g o constant numr
natural.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
13
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Compunerea functionala
Fie n , m dou numere naturale.
Se dau m+1 funcii de n argumente:
h : N
m
N , g
i
: N
n
N , 1 i m
Funcia
f : N
n
N
este definit prin compunere funcional din funciile h , g
1
, g
2
,, g
m
dac i numai dac:
f(x
1
,x
2
,, x
n
) = h (g
1
(x
1
,x
2
,, x
n
), g
2
(x
1
,x
2
,,x
n
),,g
m
(x
1
,x
2
,, x
n
))
Un caz particular de compunere functionala:
subtitutia (m=1)
14
f(a
1
,a
2
,, a
n
,0) = g(a
1
,a
2
,, a
n
) ,
f(a
1
,a
2
,, a
n
, x+1) = h(a
1
,a
2
,, a
n
, x , f(a
1
,a
2
,, a
n
, x)) .
f(x
1
,x
2
,, x
n
) =h(g
1
(x
1
,x
2
,, x
n
), g
2
(x
1
,x
2
,,x
n
),,g
m
(x
1
,x
2
,, x
n
))
Exemplul 1:
sum(a,x) = a+x,
=> n=1, a
1
=a
=> sum (a,0) = a+0 = a => g(a) = a = p
1
(1)
(a) ,
sum(a,x+1)=a+(x+1)=(a+x)+1
=>h(a,x,y)=succ(sum(a,x))=succ(p
3
(3)
(a,x,sum(a,x))).
=> sum(a,0)=p
1
(1)
(a) ,
sum(a,x+1)=h(a,x,sum(a,x)) , unde h:N
3
N , h(a,x,y)=(succ
0
p
3
(3)
)(a,x,y).
Exemplul 2:
|x-y| = max(0,x-y)+max(0,y-x),
=> |x-y|= max(0, P(2)1 (x,y)-P(2) 2(x,y)) + max(0, P (2) 2(x,y)-P(2)1(x,y)).
15
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Exemplul 3:
O funcie general recursiv: funcia Ackermann-
Peter:
int ack(int m, int n)
{
if (0==m) return n+1;
if (0==n) return ack(m-1,1);
return ack(m-1,ack(m,n-1));
}


=
= +
=
altfel n m ack m ack
n m ack
m n
n m ack
)), 1 , ( , 1 (
0 ), 1 , 1 (
0 , 1
) , (
16
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Exemplul 4 (Conjectura lui Collatz, 1937)
Se d irul de numere a
0
,a
1
,,a
n
, definit prin
iteraia pur:
Pentru orice numr natural a exist un index n astfel
nct
a
n
=1
Verificata pe calculator pana la 20 258 5.764 1018

+
=
=
+
. , 1 3
, , 2 /
1
0
altfel a
par este a daca a
a
a a
n
n n
n
17
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Functia lui COLLATZ :
este definita prin:
f(n)= n/2, daca n este par,
f(n)= 3*n+1, daca n este impar
i are urmatoarele propretati:
lungimea secventei de numere generata in vederea atingerii valorii 1 un
se poate calcula pintr-o formula bazata pe datele de intrare
tinde catre 1.
Se cere sa se scrie un program care sa citeasca o pereche de valori naturale nenule,
reprezentand primul si ultimul numar intr-o secventa inchisa de numere naturale.
Pentru fiecare astfel de secventa inchisa, se cere sa se deteremine valoarea care
genereaza cea mai lunga serie cu functia de mai sus, inainte de a ajunge la 1.
Cea mai mare valoare din secventa si din sirul transformarilor nu va depasi tipul long.
http://gfredericks.com/math/Arith/collatzPage.html
18
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
#include <iostream.h>
long int length (long int n)
{
long int aux=1;
if (n%2) n=n*3+1; else n/=2;
while(n-1){
if (n%2) n=n*3+1; else n/=2;
aux++;
}
return aux;
}
void main ()
{
long int n,m,max,l,i;
cin>>n>>m; max=0; l=-1;
for (i=n; i<=m; i++)
if (length(i)>l) {
max=i; l=length(i);
}
cout<<"intre "<<n<<" si "<<m<<" ,"<<max<<" are lungimea maxima"<<l<<endl;
}
Intre 1 si 20 , numarul 18 are ofera lungimea maxima: 20
19
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Mulimea funciilor de baz
este format din:
funcia succesor succ : N N , succ(x)=x+1
funciile constante c
a
(n)
: N
n
N , c
a
(n)
(x
1
,x
2
,, x
n
)=a
funciile proiecie p
i
(n)
: N
n
N , p
i
(n)
(x
1
,x
2
,, x
i
,, x
n
)= x
i
,
unde a , n , m e N , 1 s i s n, 1sjsn.
20
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Clasa funciilor primitiv recursive
este cea mai mic familie de funcii f : N
n
N , n>=1,
care
conine mulimea funciilor de baz i
este nchis fa de operaiile de
compunere funcional i
recuren primitiv.
Dedekind (1888) i Peano (1889),
Skolem: (1923),
Gdel (1931),
Peter (1934).
21
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Urmtoarele funcii si predicate sunt primitiv recursive:
a) f:N
2
N , f(x,y)=x+y
b) f:N
2
N , f(x,y)=x*y
c) f:N
2
N , f(x,y)=xy , (x
0
=1)
d) pd:NN , pd(x)=max(0,x-1)
e) f:N
2
N , f(x,y)=max(0,x-y) , (diferena aritmetic)
f) sg:NN , sg(0)=0 , sg(x)=1, x>0 ,
g) f:N
2
N , f(x,y)=|x-y| , (modulul)
h) sqrt:NN ,
i) ls,gr,eq:N
2
{0,1}, ls(x,y)=1, daca x<y, ls(x,y)= 0, altfel
gr(x,y)=1, daca x>y, gr(x,y)=0, altfel
eq(x,y)=1, daca x=y, eq(x,y)=0, altfel
| | x x sqrt = ) (
22
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Scheme de recuren speciale:
recurena ereditar
recurena simultan
23
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Schema de recuren ereditar
Exemplu:
Considerm irul lui Fibonacci:
u
0
=u
1
=1 ,
u
n+2
=u
n+1
+u
n
.
24
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Limbajul Borland Pascal
{fib1.pas : implementarea rec. }
function Fib (n: integer): integer;
{returneaza al n-lea termen din
sirul lui Fibonacci, n>0}
begin
if (n<=1) then Fib := n
else Fib:=Fib(n-1)+Fib(n-2);
end;
Limbajul C/C++
//fib1.cpp : implementarea rec.
long Fib (long n)
// returneaza al n-lea termen al
sirului lui Fibonacci, n>0
{
if (n<=1) return n;
else return Fib (n-1) + Fib (n-2);
}
25
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Limbajul Borland Pascal
{fib2.pas: implementarea iterativa}
function Fib (n: integer): integer;
var crt, old, older : integer;
begin
old : = 1; older : = 0;
while (n > 1) do
begin
crt : = old +older;
older : = old;
dec(n)
end;
end;
Limbajul C/C++
// fib2.cpp : implementarea iterativa
long Fib (long n)
{
if (n<=1) return n;
long crt, old=1, older=0;
while(n-- >1)
{
crt = old +older;
older = old;
}
return crt;
}
26
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Definitie
Fie x
0
, x
1
,, x
k
eN. Numarul natural
se numeste numrul Gdel asociat irului (x
0
, x
1
,,x
k
) i
se noteaz cu <x
0
,x
1
,,x
k
>.
Exemple: <3,1,2> = 2
3
3
1
5
2
= 600,
<1,2,0,5> = 2
1
3
2
5
0
7
5
= 2898918
Definiie:
Funcia f:N
n+1
N se obine prin recuren ereditar din funciile
g : N
n
N i h : N
n+2
N dac:
f(x ,0) = g(x) ,
f(x ,y+1) = h(x ,y ,<f(x ,0) ,, f(x ,y)>) ,
unde xeN
n
iar <> desemneaza numarul Gdel asociat
sirului f(x,0), ,f(x,y).
k
x
k
p
x
p
x
p n = ...
1
1
0
0
27
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Teorem:
Clasa funciilor primitiv recursive este nchis fa de
recurena ereditar.
Corolar:
Funcia f: N N, f(n) = u
n
este primitiv recursiv.
28
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Schema de recuren simultan
Exemplu:
Considerm ecuaia lui Pell:
x
2
-dy
2
=1, unde x,y e N , a>1, d=a
2
-1.
Propoziie:
Perechea (x,y)e N
2
este o soluie pentru ecuaia lui Pell
dac exist un numr n0 astfel nct
x = x
n
, y = y
n
, unde :
x
0
= 1, y
0
= 0 ,
x
n+1
= a
.
x
n
+ d
.
y
n
,
y
n+1
= x
n
+ a
.
y
n
, x> 0 .
29
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
programrec_indirecta;
var a,d,n: integer;
function y (n: integer): integer; forward;
function x (n: integer): integer;
begin
if n=0 then x:=1
else x:=a*x(n-1)+d*y(n-1)
end; {x}
function y (n: integer): integer;
begin
if n=0 then y:=0
else y:=x(n-1)+a*y(n-1)
end; {y}
begin {programul principal}
writeln ('dati constanta a > 1 si ordinul solutie n = '); readln (a,n);
d := a *a - 1;
writeln ('perechea de solutii de ordinul ',n,' este: (',x(n):4,' , ',y(n):4,').');
readln;
end.
30
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Definiie:
Funciile f
i
: N
n+1
N, (i=1,2) sunt definite prin recuren simultan
din funciile g
i
: N
n
N i h
i
: N
n+3
N (i=1,2) dac
f
i
(x,0)=g
i
(x),
f
i
(x,y+1)=h
i
(x, f
1
(x,y), f
2
(x,y)) , (i=1,2).
Teorem:
Clasa funciilor primitiv recursive este nchis fa de recurena
simultan.
Corolar:
Funciile f
1
,f
2
: N N, f
1
(n) = x
n
, f
2
(n)=y
n
sunt primitiv recursive.
31
Conceptul de subprogramde tip funcie cu apel recursiv.
Forma general a unui subprogramde tip funcie recursiv:
function f()
{
calcul initial;
conditie de oprire;
apel recursiv f();
calcul final;
return rezultat;
}
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
32
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Tipuri de subprograme recursive
(1) bazate pe funcii (primitiv) recursive unare, (funcia se apeleaz pe ea nsi n mod
direct, ca n cazul calculrii factorialului);
(2) bazate pe funcii (primitiv) recursive de mai multe argumente (ca n cazul calculrii
cmmdc pentru dou numere naturale);
acestea sunt cunoscute sub numele de recursivitate liniar direct:
int cmmdc1 (int x, int y)
{ if (x==y) return x;
else
if (x>y) return cmmdc1(x-y, y);
else return cmmdc1(x, y-x);
}
int cmmdc2 (int x, int y)
{if (0==y) return x;
else
return cmmdc2(y, x%y);
}
33
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
(3) bazate pe funcii care se apeleaz una pe alta (recursivitatea
simultana, numita si recursivitate indirect), ca in cazul calcularii
solutiilor ecuatiei lui Pell: x
2
-dy
2
=1, unde x,y e N , a>1, d=a
2
-1),
int x(int n)
{
if (n==0) return 1;
return a*x(n-1)+d*y(n-1);
}
int y(int n)
{
if (n==0) r eturn 0;
return x(n-1)+a*y(n-1);
}
34
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
(4) bazate pe funcii care au nevoie de mai multe valori anterioare pentru
a calcula valoarea curent (recursivitatea ereditara, numita si
recursivitatea neliniar sau n cascad), ca n cazul determinrii unui
element al irului lui Fibonacci dup formula:
int fibonacci (int n)
{
if (n<=1) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
35
Un subprogram recursiv trebuie s respecte urmtoarele
reguli:
1. subprogramul trebuie s poat fi executat, cel puin ntr-o
situaie, fr a se autoapela;
2. subprogramul recursiv se va autoapela ntr-un mod n care se
tinde spre ajungerea n situaia de execuie fr autoapel.
Pentru a permite apelarea recursiv a subprogramelor
limbajele de programare dispun de mecanisme speciale
de suspendare a execuiei programului apelant,
de salvare a informaiilor necesare i
de reactivare a programului suspendat.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
3
6
Pentru implementarea recursivitii
se folosete o stiv.
La fiecare apel recursiv al unui
subprogram se salveaz n stiv starea
curent a execuiei sale (adresa de
revenire i contextul programului).

Stiva implicita = zona de memorie
n care se poate face salvarea
temporar a unor valori, organizat
dup principiul LIFO
Adresa de revenire = adresa
instruciunii cu care va continua
programul ntrerupt la reluarea
execuiei sale
Context = valorile variabilelor locale
subprogramului, valorile parametrilor
de tip valoare i adresele parametrilor
de tip referin
37
Dei variabilele locale ale subprogramului apelat au aceiai
identificatori cu cei ai subprogramului apelant, orice referire la
aceti identificatori se asociaz ultimului set de variabile alocate
n stiv.
Zona din stiv rmne alocat pe tot parcursul execuiei
subprogramului apelat i se dealoc n momentul revenirii n
programul apelant.
Stiva nu este gestionat explicit de programator ci de ctre
limbaj.
La terminarea execuiei subprogramului apelat recursiv se
reface contextul programului din care s-a fcut apelul.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
38
Datorit faptului c la fiecare autoapel se ocup o zon de
stiv, recursivitatea este eficient numai dac numrul de
autoapeluri nu este mare, astfel nct s nu se ajung n situaia
umplerii stivei.
Recursivitatea ofer avantajul unor soluii mai clare pentru
probleme i unei lungimi mai mici a programelor.
Ea prezint ns dezavantajul unui timp mai mare de execuie
i a unui spaiu de memorie ocupat mai mare.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
39
Ce se ntmpl la autoapelul funciei/procedurii?
Prin autoapelul funciei/ procedurii instruciunile
rmn neschimbate.
Procedura/funcia va prelucra datele transmise n stiv.
In cazul unui nou autoapel, se creeaz un nou nivel
pentru stiv, n care se depun noile valori.
Procedura/funcia care s-a autoapelat se reia de la
instruciunea care urmeaz autoapelului i va lucra cu
variabilele (valorile) reinute n stiv n momentul
autoapelului, la care se adaug valorile returnate.
La atingerea unuia dintre cazurile de baz (condiia de
oprire), urmeaz s se revin din autoapelri.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
40
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Demonstrarea corectitudinii algoritmilor recursivi:
se face intr-un mod similar demonstrarii corectitudinii
algoritmilor nerecursivi;
este mult simplificat de forma algoritmului (care permite
utilizarea comod a metodei induciei matematice
complete):
se verific mai nti dac toate cazurile particulare (de
terminare a apelului recursiv) funcioneaz corect;
se trece apoi la o verificare formal, prin inducie, a
funciei recursive corespunztoare, pentru restul cazurilor.
41
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Exemplificare: calculul factorialului unui numr
int factorial (int n)
{
if (0==n) return 1;
return n*factorial(n-1);
}
Demonstrarea corectitudinii: doi pasi:
pentru n = 0, valoarea 1 returnat de program este corect;
dac n>1 atunci, presupunnd corect valoarea returnat
pentru (n-1), prin nmulirea acesteia cu n se obine valoarea
corect a factorialului numrului natural n, valoare returnat de
subprogram.
n ambele situaii este satisfcut condiia de oprire.
42
Algoritmul cutrii binare: un exemplu algoritmproiectat prin
aplicarea tehnicii recursivitatii si a metodei divide-et-impera:
Fie a
1
, a
2
, , a
n
un ir ordonat de n numere naturale (neN,
n2) si fie x un numar natural, dat . Se cere sa se
verifice daca numarul x se afla printre elementele sirului.
Metoda:
se injumatateste intervalul [[a
1
, a
n
]] si se caut x n jumtatea
cea mai apropiat de valoarea acestuia;
urmeaza divizarea recursiv a acestei jumtii n alte dou jumti
mai mici i reluarea procedeului pana la gasirea elementului sau
pana cand domeniul cautarii devine vid.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
43
LIMBAJ UL C++
// bs.cpp: algoritmul recursiv de cautare
binara
intBinarySearch (float *arr, int n, floatx,
int btm, int top)
{
if ( top>=btm )
{ int mid=(top+btm)/2;
if (arr[mid]==x)
returnmid; //cautare cu succes
if (arr[mid]<x)
btm=mid+1;
else top=mid-1;
returnBinarySearch(arr, n, x, btm, top) ;
}
else return -1; //nu s-a gasit valoarea
cautata
}
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Cu ajutorul acestor cazuri se va ti dac valoarea cutat n
ir s-a gsit sau nu i se poate returna rezultatul imediat.
Observam respectarea regulilor descrise mai sus:
1. Cazul de baz.
Undeva n funcia recursiv, exist unul sau mai multe
teste prin care se verific conditiile de ieire din autoapelul
recusiv. Aceste teste de ieire se numesc cazuri de baz..
Variabilele top i btm sunt prelucrate astfel
nct cutarea s se realizeze ntr-o poriune din
ce n ce mai mic a irului, pn cnd unul dintre
cazurile de baz este gsit.
2. Prelucrarea progresiv.
Esena definiiei recursive const n faptul c
pentru rezolvarea cazului n+1 se recurge la cazul
n. In acest fel, celelalte cazuri ale recursivitii,
diferite de cazurile de baz, trebuie rezolvate prin
tratarea lor astfel nct procesul apelului recursiv
s le orienteze ctre unul dintre cazurile de baz.
44
LIMBAJ UL BORLAND PASCAL
{ bs.pas: algoritmul recursiv de cautare binara }
functionBinarySearch (arr:real; n: integer; x:real;
btm, top:integer) : integer;
var mid : integer;
begin
if (( top>=btm ) then
begin
mid : = (top+btm) div 2;
if (arr[mid] = x) thenBinarySearch : = mid;
if (arr[mid]<x) then btm : = mid+1
else top : = mid-1;
BinarySearch:=BinarySearch(arr,n,x,btm, top)
end;
else BinarySearch : = -1;
end;
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
45
Ridicarea unui numr real x la o putere n natural, x
n
binare: un
alt exemplu algoritm proiectat prin aplicarea tehnicii
recursivitatii si a metodei divide-et-impera:
Metoda clasic de ridicare la putere este multiplicarea sa cu el nsuI
de n-1 ori, iar algoritmul este de complexitate O(n).
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
46
Tehnica divide-et-impera: se poate obine un algoritm cu complexitate:
O(log(n)).
Strategia se bazeaz pe urmtoarele proprieti ale puterilor ntregi:

Se observ cum valorile lui n scad, pn cnd atinge unul dintre


cazurile de baz.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
( ) impar este n daca , x x 4) par este n daca , x x 3) x x 2) 1 x 1)
1 - n n
2
2 n 1 0
x
n
= = = =
Cazurile care reprezint
cazurile de baz ale recursivitii.
Cnd n este par se
calculeaz mai nti x
n-1
i apoi se multiplic
rezultatul cu x.
Cnd n este impar se
multiplic x cu el nsui (x
2
)
i apoi rezultatul se ridic
recursiv la puterea n/2.
47
LIMBAJ UL BORLAND PASCAL
{pow1.pas functia putere recursiva }
function Power(x:real; n :integer): real;
begin
if (n=0) then power:=1;
if (n=1) then power:=x;
if odd ( n) then
Power:=Power(x,n-1)*x; {n impar}
Else Power:=Power(x*x, n/2); {n par}
end;
LIMBAJ UL C++
//pow1.cpp functia putere recursiva
float Power(float x, int x)
{
if (n==0) return 1;
if (n==1) return x;
if (n&1)
return Power(x,n-1)*x; //n impar
else return Power(x*x, n/2); //n par
}
( ) impar este n daca , x x 4) par este n daca , x x 3) x x 2) 1 x 1)
1 - n n
2
2 n 1 0
x
n
= = = =
48
1. se definete o stiv i se initializeaz cu
mulimea vid;
2. ct timp este ndeplinit condiia de
continuare a recursivitii:
3. se execut instruciunile dinainte de
apel;
4. se salveaza pe stiv valorile actuale ce
reprezint argumentele funciei
recursive;
5. se execut instruciunile funciei
recursive;
6. se modific argumentele funciei
recursive;
7. cnd condiia nu mai este indeplinit i
dac stiva este nevid atunci
8. se aduce de pe stiva un set de variabile,
9. se executa o serie de calcule (cele de
dup apelul recursiv) i
10. se trece la pasul 3.
11. dac stiva este vid algoritmul se oprete.
void print_rec()
{
int c = getch ();
if (c!=\n) { print_rec(); printf(%c,c);
}
}
void print_it ()
{
Stack S;
empty (S);
int c = getch ();
while (c!=\n) { push(c); c = getch();
}
while (nevida(S)) {c=pop (S);
printf (%c,c);}
}
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Pentru a tranforma o funcie recursiv ntr-o funcie iterativ:
49
Exista o legatura stransa intre
recursivitate si structurile de date
de tip stiva, arbore, etc folosite in
limbajele Borland Pascal si C++
pentru reprezentarea functiilor /
procedurilor recursive (insasi
definitia stivelor, arborilor, listelor
realizandu-se recursiv).
Deseori, variantele iterative
necesita folosirea explicita a
structurii de tip stiva, generand
astfel un cod extrem de laborios.
In aceste situatii se considera
solutia recursiva mai eleganta,
datorita simplitatii sale.
Recursivitatea trebuie inlocuita
prin iteratie atunci cand
recursivitatea este prea adanca
sau cand limbajul de programare
nu permite implementarea de
apeluri recursive.
Din punctul de vedere al memoriei
solicitate, o varianta recursiva
necesita un spatiu de stiva
suplimentar pentru fiecare apel
fata de varianta iterativa.
Dimensiunea stivei trebuie aleasa
astfel incat sa poata permite
memorarea elementelor pentru
toate iteratiile.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
Avantajele si dezavantajele utilizarii subprogramelor recursive
50
Greseli tipice in realizarea subprogramelor recursive (1):
1. Declararea ca variabile globale a unor variabile care
controleaza adresa de revenire (cazul cand apelurile se
fac din interiorul unei structuri repetitive).
2. Declararea ca parametri transmisi prin valoare sau ca
variabile locale a unor date structurate (de exemplu de tip
tablou) micsoreaza semnificativ adancimea acceptata a
recursivitatii, deoarece memorarea lor necesita un spatiu
mare de memorie.
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
51
Greseli tipice in realizarea subprogramelor recursive (2):
4. Absenta unei conditii de oprire.
5. Exprimarea unei conditii de oprire in care nu intervin nici
variabile locale si nici parametrii transmisi prin valoare sau
prin referinta ai subprogramului.
6. Marirea dimensiunii problemei prin transmiterea in cadrul
autoapelurilor a unor parametri actuali care nu tind sa se
aproprie de valorile impuse prin conditia de oprire.
7. Neutilizarea directivei forward (limbajul Borland Pascal) in
cazul declararii unor subprograme indirect recursive
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
52
1. Algoritmi: generalitati
2. Algoritmi: modele de calculabilitate
3. Teoria functiilor recursive
4. Scheme de recurenta; reduceri
5. Recuren i iteraie in programare
BIBLIOGRAFIE
1. Rzvan ANDONIE, Ilie GARBACEA: Algoritmi
fundamentali. O perspectiv C++, Editura Libris, Cluj-
Napoca, 1995.
2. Cristian Sorin CALUDE: Theories of Computational
Complexity, Elsevier Science Publ., Amsterdam, 1988.
3. Richard JOHNSONBAUGH, Marcus SCHAEFER:
Algorithms, Pearson Prentice Hall, Upper Saddle River, NJ.,
2004.
4. D. JOYCE: The Dedekind/Peano Axioms, Clark University,
posted on January 2005,
http://aleph0.clarku.edu/~djoyce/numbers/peano.pdf
5. Dexter C. KOZEN: Theory of Computation, Springer-Verlag,
Berlin Heidelberg, 2006.