Sunteți pe pagina 1din 7

Ministerul Educației al Republicii Moldova

Universitatea Tehnică a Moldovei


Facultatea Calculatoare , Informatică și Microelectronică
Departamentul Inginerie Software și Automatică

Lucrare de laborator nr. 1


Disciplina : Analiza și proiectarea algoritmilor
Tema : Analiza empirică a algoritmilor

Elaborat:
studenta : TI-171 f/r, Trili Diana
Verificat:
prof.univ. : Catruc Mariana

Chișinău 2019

Scopul lucrării:
Să alcătuim un program care calculează un număr fib(n) al lui Fibonacci introdus de la
tastatură prin intermediul diferitor algoritmi.
Să facem o analiză care din algorimii implementați e cei mai simplu de înțeles, care din
aceștia folosește eficace resursele calculatorului, care afișează mai rapid rezultatul
dorit.

Modul de implementare:

Vom rezolva problema prin intermediul a 3 algoritmi:


1. Algoritmul recursiv
2. Algoritmul iterativ
3. Algoritmul divizării

Apoi, pentru fiecare tip de execuție, vom alege random 10 n din f(n) și vom trece
aceste 10 numere prin algoritmii implementați, adaugînd spre afișare nr de iterații, apoi
timpul de execuție.

Vom trece 10 numere prin algoritmi pentru a minimiza coeficientul de eroare.


În mare parte, acest coeficient de eroare va fi prezent la timpul de execuție, așa cum
mașina fizică se comportă diferit în dependență de puterea de procesare, load, baterie
(laptop), și alți factori.

Cod Algoritm 1:

import java.math.BigDecimal;
import java.math.RoundingMode;

import static java.lang.System.out;

public class Lab1 {

static int nriteratii = 0;

public static void main(String[] args) {


int n = FunctiiUtile.citestedinconsola();
BigDecimal div = BigDecimal.valueOf(1000000000);
BigDecimal start = BigDecimal.valueOf(System.nanoTime());
long result;
result = fibo_recursiv(n);
BigDecimal end = BigDecimal.valueOf(System.nanoTime());
BigDecimal time = end.subtract(start).divide(div, 5, RoundingMode.HALF_EVEN);
out.println("Rezultatul este " + result);
out.println("Executat în " + time + " secunde");
out.println("Numărul de iterații este " + nriteratii);

static long fibo_recursiv(int n) {


nriteratii++;
if (n <= 1) return n;
else return fibo_recursiv(n - 1) + fibo_recursiv(n - 2);
}
}

Cod Algoritm 2:

import java.math.BigDecimal;
import java.math.RoundingMode;

import static java.lang.System.out;

public class Lab1alg2 {


static int nriteratii = 0;

public static void main(String[] args) {


int n = FunctiiUtile.citestedinconsola();
BigDecimal div = BigDecimal.valueOf(1000000000);
BigDecimal start = BigDecimal.valueOf(System.nanoTime());
long result;
result = fibo_for(n);
BigDecimal end = BigDecimal.valueOf(System.nanoTime());
BigDecimal time = end.subtract(start).divide(div, 5, RoundingMode.HALF_EVEN);
out.println("Rezultatul este " + result);
out.println("Executat în " + time + " secunde");
out.println("Numărul de iterații este " + nriteratii);

static long fibo_for(int n) {


int i = 1;
int j = 0;
for (int k = 1; k <= n; k++) {
nriteratii ++;
j = i + j;
i = j - i;
}
return j;
}
}
Cod algoritm 3:

import java.math.BigDecimal;
import java.math.RoundingMode;

import static java.lang.System.out;

public class Lab1alg3 {


static int nriteratii = 0;

public static void main(String[] args) {


int n = FunctiiUtile.citestedinconsola();
BigDecimal div = BigDecimal.valueOf(1000000000);
BigDecimal start = BigDecimal.valueOf(System.nanoTime());
long result = fibo_while(n);
BigDecimal end = BigDecimal.valueOf(System.nanoTime());
BigDecimal time = end.subtract(start).divide(div, 5, RoundingMode.HALF_EVEN);
out.println("Rezultatul este " + result);
out.println("Executat în " + time + " secunde");
out.println("Numărul de iterații este " + nriteratii);
}

static long fibo_while(int n) {


int i = 1, j = 0, k = 0, h = 1, t;
while (n > 0) {
nriteratii++;
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;
}
return j;
}
}
Nr./Algoritm Recursiv Iterativ Divizarii

3 t= 0.00004 t= 0.00001 t= 0.00001


i=5 i=3 i=2

5 t= 0.00003 t= 0.00001 t= 0.00001


i = 15 i=5 i=3

7 t= 0.00002 t= 0.00001 t= 0.00001


i = 41 i=7 i=3

10 t= 0.00006 t=0.00001 t=0.00001


i = 177 i = 10 i=4

15 t= 0.00022 t=0.00001 t=0.00001


i = 1973 i = 15 i=4

18 t=0.00051 t=0.00001 t=0.00001


i = 8361 i = 18 i=5

20 t=0.00058 t= 0.00001 t=0.00001


i = 21891 i = 20 i=5

26 t=0.00197 t=0.00001 t=0.00001


i = 392835 i = 26 i=5

35 t=0.05053 t=0.00001 t=0.00001


i = 29860703 i = 35 i=6

40 t=0.49150 t=0.00002 t=0.00001


i = 331160281 i = 40 i=6

t = timp de execuție (sec), i = iterații


Concluzie:
Efectuînd această lucrare de laborator am pus în practică cunoștințele teoretice despre
algoritmi.
Am dedus faptul că metoda Recursivă nu este cea mai potrivită pentru determinarea
unui număr n din șirul lui Fibonacci.
Metoda Iterativă și cea de Divizare au oferit ambele rezultare bune, în materie de timp
și iterații.
Pentru numărul de ordine <50 din șir, metoda Iterativă este după părerea mea cea mai
eficientă, deoarece aceasta satisface principalele criterii de alegere:
- Folosește eficient resursele mașinii fizice, are un timp de execuție redus
- Este simplu de înțeles și de decodificat
Pentru numărul de ordine 50> însă, metoda Divizării oferă cele mai optime rezultate,
dar nu e la fel de ușor de înțeles la o primă vedere a codului.
Astfel, la rezolvarea unei probleme de acest tip, vom determina pentru început scopul,
fie acesta timpul de execuție, numărul de iterații sau claritate în cod.

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