Sunteți pe pagina 1din 8

Universitatea Tehnică a Moldovei

RAPORT
Lucrare de laborator Nr.1
Tema  :Analiza algoritmilor

Efectuat de st.gr FI-141 Sapojnic Alexandra

Verificat de : Lector Superior,


Mariana Catruc

Chișinău 2015
Scopul lucrării:
1. Analiza teoretică a algoritmilor.

2. Analiza empirică a algoritmilor.

3. Determinarea complexităţii temporale şi asimptotice a algoritmilor

Șirul lui Fibonacci este definit prin recurența următoare:

Termenul n al șirului poate fi obținut direct prin definiție:


function fib1(n)
     if n < 2   then   return n
                           else   return fib1(n-1) + fib1(n-2)
Această metodă nu este atît de reușită deoarece recalculează de mai multe
ori aceleași valori.O altă metodă mai eficace care permite rezolvarea
problemei este:
function fib2(n)
     i  1; j  0
     for k  1 to n do j  i + j
ij-i
      return j
Mai exista un alt agoritm :
function fib3(n)
     i  1; j  0; k  0; h  1
     while n > 0 do
          if n este impar then   t  jh
                                                               j  ih+jk+t
                                                               i  ik+t
          t   h2
          h  2kh+t
          k  k2+t
          n  n div 2
     return j

Determinăm complexitatea asimptotică a acestor metode:


Recurența care definește șirul lui Fibonacci este:
tn = tn-1 + tn-2 n2
și t0 = 0, t1 = 1.
Putem să rescriem aceasta recurență în altă formă:
tn - tn-1 - tn-2 = 0, care are ecuația caracteristică:
x2 - x - 1 = 0, cu radacinile r1,2 = (15 )/2.
Soluția generală are forma:

t n=c1 r n1 +c 2 r 2n
Concluzionăm că timpul algoritmului care determină șirul lui Fibonacci prin
metoda 1,crește în mod exponențial în funcție de n .
O altă metodă propusă a acestei probleme:
function fib2(n)
     i  1; j  0
     for k  1 to n do j  i + j
ij-i
      return j

Costul Numarul de
iteratii

C1 1
C2 1
C3 N
C4 N
C5 N

T(n)=c1+c2+(c3+c4+c5)n, scriem c1+c2 prin k1 si (c3+c4+c5) prin k2 =>


t(n)=k1+k2n si mai departe ca t(n)=O(n).In aceasta metoda,timpul de
executie depinde liniar de n.
Metoda a 3 este o functie logaritmică: tn=O(log2n).,deoarece avem oarecare
costanta n ce se îmulțeste cu log2n și avem ciclul while se execută atîta timp
cît n>0 dar n mereu se împarte la 2.
Efectuam o analiza empirica a algoritmilor.
Rezultatele executiei programului :
Pentru primul algoritm:
n=4
Numarul de iterației: 9
Timpul de executie : 0.02 s.

Pentru al II-lea algoritm :


n=4
Numarul de iterației: 4
Timpul de executie : 0.04 s.

Pentru al III-lea algoritm :


n=4
Numarul de iterației: 3
Timpul de executie : 0.04 s.

Numarul de interatii pentru fiecare algoritm :


Algoritmii Valorile introduse:

4 8 15 26 34
I algoritm 9 67 1973 392835 18454929 

II algoritm 4 8 15 26 34

III algoritm 3 4 4 5 6
Comparăm cei 3 algoritmi printr-o diagrama
După numarul de iterații:

14

12

10

8 Alg I
Alg II
6 Alg III

Codul Sursa:
#include <iostream>

#include <stdlib.h>

#include <time.h>

using namespace std;

long int c = 0,d=0,e=0;

long double fib1(int n);

long int fib2(int n);

long int fib3(int n);

int main()

clock_t start, finish;

int n;

cout << "Dati n:";

cin >> n; cout << "\n";


start = clock();

cout << "fib1 Rezultat:" << fib1(n) << "\n";

finish = clock();

cout << "Numarul de iteratii:" << c << endl;

cout << "Timpul de executie pentru fib1 =" << ((double)finish - start) / CLOCKS_PER_SEC << endl;

cout << "--------------------------------" << endl;

start = clock();

cout << "fib2 Rezultat:" << fib2(n) << "\n";

finish = clock();

cout << "Numarul de iteratii:" << d << endl;

cout << "Timpul de executie pentru fib2 =" << ((double)finish - start) / CLOCKS_PER_SEC << endl;

cout << "--------------------------------" << endl;

start = clock();

cout << "fib3 Rezultat:" << fib3(n) << "\n";

finish = clock();

cout << "Numarul de iteratii:" << e << endl;

cout << "Timpul de executie pentru fib3 =" << ((double)finish - start) / CLOCKS_PER_SEC << endl;

system("pause");

long double fib1(int n)

c++;

if (n < 2)

return n;

else

return fib1((n - 1)) + fib1(n - 2);

long int fib2(int n)

long int i, j, k;
i = 1;

j = 0;

for (k = 0; k<n; k++)

j = i + j;

i = j - i;

d++;

return j;

long int fib3(int n)

long int i, j, k, h, t;

i = 1; k = 0;

j = 0; h = 1;

while (n>0)

e++;

if (n % 2 != 0)

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;

return j;

}
Concluzie:
În această lucrare am înțeles că toate cele 3 metode sunt eficace și au
rezultat bun. Pentru numerele mici prima metodă este cea mai bună,dar
pentru un număr mare nu este rentabil pentru că numarul de iteratii crește în
mod exponențial. Pentru numerele în intervalul [20 .. n] metoda a 3-a este cea
mai eficace avînd un număr de iteratii mic,de aceea această metodă o consider
ca fiind cea mai rezonabilă.
Consider că cînd se compară 3 algoritmi, cel având ordinul de creștere mai
mic este considerat a fi mai eficient. Am observat că analiza timpilor de
execuție pentru valori mici ale dimensiunii problemei nu permite diferențierea
dintre algoritmii eficienți și cei ineficienți . Diferențele dintre ordinele de
creștere devin din ce în ce mai semnificative pe măsura ce crește dimensiunea
problemei.
Efectuînd această lucrare de laborator am înțeles cît de eficiente sunt
pentru noi cunostințele căpătate în urma analizei algoritmelor. Aceasta ne
dezvoltă capacitățile noastre logice,matematice și de analiza. Aceste
cunoștințe ușor pot fi folosite pe viitor la elaborarea unui program mai dificil și
sigur la rezolvarea exemplelor matematice de un nivel mai înalt.

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