Sunteți pe pagina 1din 8

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Facultatea Calculatoare, Informatic i Microelectronic

Raport
Lucrare de laborator Nr. 1
la Analiza i Proiectarea Algoritmilor
Tema: Analiza algoritmilor (Timpul de execuie al algoritmilor).

Elaborat: st. gr. TI-151


Poseletchi Cristian
Verificat: Lector Universitar
Veronica Bagrin

Chiinu 2016

Notiuni teoretice:
Timpul de execuie
Durata de execuie a unui program depinde de dimensiunea i de caracteristicile datelor de intrare.
Putem spune c un ir de 10000 de numere va fi sortat mai ncet dect unul de 1000 de numere. De
obicei timpul de execuie al unui algoritm crete dac numrul datelor de intrare crete. Deci ar fi
normal s descriem timpul de execuie ca o funcie de aceast variabil.
Dimensiunea datelor de intrare depinde de problema care o rezolvm. De exemplu, dac trebuie s
sortm un ir de n numere atunci dimensiunea datelor de intrare va fi n. Astfel putem s ne gndim
c avem un numr de n obiecte iar acesta va fi dimensiunea datelor de intrare. Totui exist cazuri
cnd numrarea "obiectelor" ca date de intrare nu este o abordare bun. Dac avem un graf,
dimensiunea datelor de intrare se va calcula n funcie de cte vrfuri i cte noduri are graful
respectiv.
Cnd ne gndim la timp ne gndim automat la secunde ( sau ceva asemntor ). Dac algoritmul
nostru este rulat pe calculatoare diferite desigur ca vom avea timpi de rulare diferii. Un algoritm
oarecare pe un Pentium I va rula mai ncet dect pe un Pentium II. Dac avem un computer a crui
procesor are o frecva de 1Ghz i alt computer cu procesor de 2Ghz nu nseamn c pe al doilea
computer va rula de dou ori mai rapid. Chiar i pe sisteme identice pot aprea diferene. Sau poate
difer doar sistemul de operare. Sunt foarte muli factori care modific timpul ( n secunde ) de
rulare a algoritmilor.
Astfel trebuie s regndim strategia i s ncercm s msurm timpul n funcie de numrrul pailor
elementari care sunt executai n algoritm. Putem aproxima c o linie de cod este executat n
acelai timp de fiecare dat. Dar pot aprea i linii n care sunt apelate funcii i proceduri ale cror
timp de execuie poate s fie diferit ( de exemplu,timpul de execuie a unei funcii care verific
existena unui elemen ntr-un ir de numere poate varia n funcie de lungimea irului si de
aranjamentul elementelor din ir ).
Dac presupunem c se fac n pasi pentru a citi din fiier datele de intrare putem considera o funcie
de forma T(n)=n2. Presupunem c algoritmul face n pai iar pentru afiare se vor folosi 2*n pai.
Funcia noastr devine T(n)=n2+3n.

Cazul cel mai defavorabil i cazul mediu

Timpul de execuie al unui algoritm nu depinde doar de dimensiunea datelor de intrare. Acest timp
depinde i de felul n care sunt organizate datele. De exemplu, dac trebuie s sortm un ir de
numere aproape sortat vom avea nevoie de mai putin timp dect pentru un ir sortat n ordine
invers.
Astfel apare cazul mediu i cazul cel mai defavorabil ( desigur , exist i cazul cel mai favorabil dar
nu asta urmrim ). Cazul mediu de execuie este o medie a tuturor timpilor posibili nregistrati n
cazul unor date de intrare de dimensiune dat. Timpul de executie pentru cazul cel mai defavorabil
reprezint timpul cel mai mare nregistrat n cazul unor date de intrare de dimensiune dat.
De obicei se folosete cazul cel mai defavorabil astfel nct s avem un punct de reper bun. Degeaba
zicem c programul nostru ruleaz n minim 3 secunde. El poate s ruleze i un an n anumite cazuri
defavorabile. Ideal ar fi s precizm limita superioar ( de exemplu: programul ruleaz n maxim 6
secunde ). Astfel tim c pentru cazul cel mai defavorabil este nevoie de 6 secunde. Este un lucru
bun s tim timpul de execuie pentru cazul cel mai defavorabil pentru c avem garania c
programul nostru nu va depi niciodat acest timp.

Ordinul de complexitate

Pentru timpii de execuie se pot forma funcii foarte complicate dar noi nu avem nevoie de funcii
complicate. Astfel a fost introdus ordinul de complexitate al unui algoritm. Acesta reprezint o
caracterizare a functiei respective, o descriere a ordinului de mrime. Ordinul de complexitate va
indica doar ordinul de mrime al funciei iar restul termenilor care nu sunt importani vor fi
eliminai.
Dac avem :
1.

T(n)= 2*n2+5*n+3

ordinul de complexitate va fi :
1.

O(n2)

Observm c acum notm ordinul de complexitate cu "O" i am ales termenul cu "puterea cea mai
mare". Dup cum am spus , termenii neimportani vor fi eliminai.A rmas doar termenul cu puterea
cea mai are pentru c este cel mai important.
Dac facem o incursiune n matematic vom observa c atunci cnd n->infinit n2 crete cel mai
repede fa de ceilali termeni.

Scopul lucrrii:
1.
2.

Analiza empiric a algoritmilor.


Analiza teoretic a algoritmilor.
3.Determinarea complexitii temporale i asimptotice a algoritmilor

3. Determinarea complexitii asimtotice a acestor metode:


Recurena care definete irul lui Fibonacci este:
tn = tn-1 + tn-2 , n 2, unde t0=0, t1=1.
De aici putem s rescriem aceast recuren sub alt form, i anume:
tn - tn-1 - tn-2=0.
Aceast ecuaie este caracterizat de ecuaie de gradul II (ax2+bx+c=0).
5
x2 - x - 1=0, =1-4*1*(-1)=5, avnd rdcinile: r1,2 = (1
Soluia generala are forma: tn = c1r1n + c2r2n
Impunnd condiiile iniiale, obinem sistemul:
c1+c2 = 0, n=0
r1c1 + r2c2 = 1, n = 1
unde determinm c1,2 = 1/5 .
1

tn

5 r1n r2n

Rezult c
1 5

t n O

Listingul programului:
#include <iostream>
#include <time.h>
#include <conio.h>
#include <stdio.h>
using namespace std;
int fib1(int n);
int fib2(int n);
int fib3(int n);
int main()
{
int n;
time_t start, end;
cout << "Dati n: "; cin >> n;
start = time(NULL);
cout << endl << fib1(n);

)/2.

end = time(NULL);
printf("\ntimp de %.2f\n", difftime(end, start));
cout << endl;
start = time(NULL);
cout << endl << fib2(n);
end = time(NULL);
printf("\n timp de %.2f\n", difftime(end, start));
cout << endl;
start = time(NULL);
cout << endl << fib3(n);
end = time(NULL);
printf("\n timp de %.2f\n", difftime(end, start));
cout << endl;
system("pause");
return 1;
}
int fib1(int n)
{
if (n < 2) return n;
else return fib1(n - 1) + fib1(n - 2);
}
int fib2(int n)
{
{
int k = 1, m = 0, i;
for (i = 0; i<n; i++) {
m = k + m;
k = m - k;
}
return m;
}
}
return j;
}
int fib3(int n)
{
int i = 1, j = 0, k = 0, h = 1, t;
while (n > 0){
if (n % 2 == 1) {
t = j*h;
j = i*h + j*k + t;
i = i*k + t;
}
t = h*h;
h = 2 * k* h + t;
k = k*k + t;
n = n / 2;

Rezultatele obinute:

Rezultatele obinute
Dup timp:

f1(n)
f2(n)
f3(n)

10

20

30

40

fib1(recursia)
fib2(for)
fib3(while)

0
0
0

0
0
0

0,001
0
0

0,009
0
0

1,121
0
0

Graficul obinut n intervalul [1;20]:


0
0
0
fib3(while)

fib2(for)
fib1(recursia)

0
0
0
1

10

Graficul obinut n intervalul [30;50]:

20

50
135,2
89
0,001
0

160
140
120
100

fib2(for)

80

fib3(while)

60

fib1(recursia)

40
20
0
30

40

50

Rezultatele obinute dup numrul de iteraii:


f1(n)
f2(n)
f3(n)

it

10

20

fib1(recursia)
fib2(for)
fib3(while)

1
1
1

177
4
10

21891
5
20

30
26925
37
5
30

Graficul obinut n intervalul [1;20]:


25000
20000
15000

fib1(recursia)
fib2(for)

10000

fib3(while)

5000
0
1

10

20

Graficul obinut la compararea (for-while) n intervalul [1;40]:


45
40
35
30
25
20
15
10
5
0

fib2(for)
fib3(while)

10

20

30

40

40
331160281
6
40

50

Concluzii:
n urma efecturii acestei lucrari de laborator am fcut cunotin cu Numerele lui
Fibonacci. Pentru afiarea unui numr al acestui ir am folosit 3 metode:
1. recursia
2. for
3.while
Dup obinerea rezultatelor , am fcut comparaii ntre ele cu ajutorul unor grafice.
Dup rezultatele primului tabel care arat timpul msurat n clockuri, am facut grafice pe intervale [1;20] si [30;50] . In primul ca si in al doilea interval algoritmul
fib1(recursia) are nevoie de mai mult timp pentru a afisa rezultatul, iar fib2 si fib 3
sint mai eficiente deoarece afiseaza rezultatul imediat, acesta observam si in graficile
facute. Calcule facute dupa numarul de iteratii arata tot aceleasi rezultate .
Pentru fib1 (recursia) numarul de interatii creste foarte rapid , iar pentru fib2 si fib3
lent . In graficul 4 am comparat fib2(for) si fib3(while) si observam ca fib3 face mai
multe iteratii ca fib2 respectiv fib3 este mai efficient.