Sunteți pe pagina 1din 18

Ministerul Educaţiei a Republicii Moldova

Universitatea Tehnică a Moldovei


Facultatea Calculatoare, Informatică şi Microelectronică

RAPORT
Lucrarea de laborator nr. 2

Tema: Metoda divide et impera


La disciplina: Analiza şi proiectarea algoritmilor
Varianta: 1

A efectuat:
student a gr. TI-102 Sîli Gheorghe
A verificat:
lect. sup. Mariana Catruc

Chişinău 2011
Scopul lucrării:
1. Studierea metodei divide et impera.
2. Analiza şi implementarea algoritmilor bazaţi pe metoda divide et impera.

SARCINA DE BAZĂ:
1. Studiaţi noţiunile teoretice despre metoda divide et impera.
2. Implementaţi algoritmii Mergesort şi Quicksort descrişi şi analizaţi mai sus.
3. Prezentaţi în pseudo-cod algoritmului lui Strassen.

Consideraţii teoretice

1. Tehnica divide et impera

Divide et impera este o tehnica de elaborare a algoritmilor care constă în:

Descompunerea cazului ce trebuie rezolvat într-un număr de subcazuri mai mici ale aceleiaşi
probleme.
2. Rezolvarea succesivă şi independentă a fiecăruia din aceste subcazuri.

3. Recompunerea subsoluţiilor astfel obţinute pentru a găsi soluţia cazului iniţial.

Să presupunem că avem un algoritm A cu timp pătratic. Fie c o constantă, astfel încât timpul pentru a
rezolva un caz de mărime n este tA(n)  cn2. Să presupunem că este posibil să rezolvăm un astfel de caz prin
descompunerea în trei subcazuri, fiecare de mărime n/2. Fie d o constantă, astfel încât timpul necesar
pentru descompunere şi recompunere este t(n)  dn. Folosind vechiul algoritm şi ideea de descompunere-
recompunere a subcazurilor, obţinem un nou algoritm B, pentru care:

tB(n) = 3tA(n/2)t(n)  3c((n1)/2)2dn = 3/4cn2(3/2d)n3/4c

Termenul 3/4cn2 domină pe ceilalţi când n este suficient de mare, ceea ce înseamnă ca algoritmul B
este în esenţă cu 25% mai rapid decât algoritmul A. Nu am reuşit însă să schimbăm ordinul timpului, care
rămâne pătratic.

Putem să continuăm în mod recursiv acest procedeu, împărţind subcazurile în subsubcazuri etc.
Pentru subcazurile care nu sunt mai mari decât un anumit prag n0, vom folosi tot algoritmul A. Obţinem
astfel algoritmul C, cu timpul

tC(n) este în ordinul lui nlg 3. Deoarece lg 3  1,59, înseamnă că de această dată am reuşit să
îmbunătăţim ordinul timpului.

Algoritmul formal al metodei divide et impera:

funcţion divimp(x)
{returnează o soluţie pentru cazul x}
if x este suficient de mic then return adhoc(x)
{descompune x în subcazurile x1, x2, …, xk}
for i  1 to k do yi  divimp(xi)
{recompune y1, y2, …, yk în scopul obţinerii soluţiei y pentru x}
return y

unde adhoc este subalgoritmul de bază folosit pentru rezolvarea micilor subcazuri ale problemei în cauză (în
exemplul nostru, acest subalgoritm este A).

Un algoritm divide et impera trebuie să evite descompunerea recursivă a subcazurilor “suficient de


mici”, deoarece, pentru acestea, este mai eficientă aplicarea directă a subalgoritmului de bază. Ce înseamnă
însă “suficient de mic”?

In exemplul precedent, cu toate ca valoarea lui n0 nu influenţează ordinul timpului, este influenţata
însă constanta multiplicativa a lui nlg 3, ceea ce poate avea un rol considerabil în eficienţa algoritmului.
Pentru un algoritm divide et impera oarecare, chiar dacă ordinul timpului nu poate fi îmbunătăţit, se doreşte
optimizarea acestui prag în sensul obţinerii unui algoritm cât mai eficient. Nu exista o metodă teoretică
generală pentru aceasta, pragul optim depinzând nu numai de algoritmul în cauză, dar şi de particularitatea
implementării. Considerând o implementare dată, pragul optim poate fi determinat empiric, prin măsurarea
timpului de execuţie pentru diferite valori ale lui n0 şi cazuri de mărimi diferite.

In general, se recomandă o metodă hibridă care consta în ă a) determinarea teoretica a formei


ecuaţiilor recurente; b) găsirea empirica a valorilor constantelor folosite de aceste ecuaţii, în funcţie de
implementare.

Revenind la exemplul nostru, pragul optim poate fi găsit rezolvând ecuaţia

tA(n) = 3tA(n/2)  t(n)

Empiric, găsim n0  67, adică valoarea pentru care nu mai are importanţă dacă aplicăm algoritmul A
în mod direct, sau dacă continuăm descompunerea. Cu alte cuvinte, atâta timp cât subcazurile sunt mai mari
decât n0, este bine să continuăm descompunerea. Dacă continuăm însă descompunerea pentru subcazurile
mai mici decât n0, eficienţa algoritmului scade.

Observăm că metoda divide et impera este prin definiţie recursivă. Uneori este posibil să eliminăm
recursivitatea printr-un ciclu iterativ. Implementată pe o maşina convenţionala, versiunea iterativă poate fi
ceva mai rapidă (in limitele unei constante multiplicative). Un alt avantaj al versiunii iterative ar fi faptul că
economiseşte spaţiul de memorie. Versiunea recursiva foloseşte o stivă necesară memorării apelurilor
recursive. Pentru un caz de mărime n, numărul apelurilor recursive este de multe ori în (log n), uneori
chiar în (n).

1.1. Mergesort (sortarea prin interclasare)


Fie T[1 .. n] un tablou pe care dorim sa-l sortam crescător. Prin tehnica divide et impera putem
proceda astfel: separăm tabloul T în două părţi de mărimi cât mai apropiate, sortăm aceste părţi prin apeluri
recursive, apoi interclasăm soluţiile pentru fiecare parte, fiind atenţi să păstrăm ordonarea crescătoare a
elementelor. Obţinem următorul algoritm:

procedure mergesort(T[1 .. n])


{sortează în ordine crescătoare tabloul T}
if n este mic
then insert(T)
else arrays U[1 .. n div 2], V[1 .. (n1) div 2]
U  T[1 .. n div 2]
V  T[1  (n div 2) .. n]
mergesort(U); mergesort(V)
merge(T, U, V)
unde insert(T) este algoritmul de sortare prin inserţie cunoscut, iar merge(T, U, V) interclasează într-
un singur tablou sortat T cele două tablouri deja sortate U şi V.

Algoritmul mergesort ilustrează perfect principiul divide et impera: pentru n având o valoare mica,
nu este rentabil să apelăm recursiv procedura mergesort, ci este mai bine să efectuăm sortarea prin inserţie.
Algoritmul insert lucrează foarte bine pentru n  16, cu toate că, pentru o valoare mai mare a lui n, devine
neconvenabil. Evident, se poate concepe un algoritm mai puţin eficient, care să meargă pană la
descompunerea totală; în acest caz, mărimea stivei este în (log n).

Spaţiul de memorie necesar pentru tablourile auxiliare U şi V este în (n). Mai precis, pentru a sorta
un tablou de n = 2k elemente, presupunând că descompunerea este totală, acest spaţiu este de

elemente.

In algoritmul mergesort, suma mărimilor subcazurilor este egală cu mărimea cazului iniţial. Aceasta
proprietate nu este în mod necesar valabilă pentru algoritmii divide et impera. Este esenţial ca subcazurile să
fie de mărimi cât mai apropiate (sau, altfel spus, subcazurile să fie cât mai echilibrate).

1.2. Quicksort (sortarea rapida)

Algoritmul de sortare quicksort, inventat de Hoare în 1962, se bazează de asemenea pe principiul


divide et impera. Spre deosebire de mergesort, partea nerecursivă a algoritmului este dedicata construirii
subcazurilor şi nu combinării soluţiilor lor.

Ca prim pas, algoritmul alege un element pivot din tabloul care trebuie sortat. Tabloul este apoi
partiţionat în două subtablouri, alcătuite de-o parte şi de alta a acestui pivot în următorul mod: elementele
mai mari decât pivotul sunt mutate în dreapta pivotului, iar celelalte elemente sunt mutate în stânga
pivotului. Acest mod de partiţionare este numit pivotare. În continuare, cele subtablouri sunt sortate în mod
independent prin apeluri recursive ale algoritmului. Rezultatul este tabloul complet sortat; nu mai este
necesară nici o interclasare. Pentru a echilibra mărimea celor două subtablouri care se obţin la fiecare
partiţionare, ar fi ideal să alegem ca pivot elementul median. Intuitiv, mediana unui tablou T este elementul
m din T, astfel încât numărul elementelor din T mai mici decât m este egal cu numărul celor mai mari decât
m. Din păcate, găsirea medianei necesita mai mult timp decât merită. De aceea, putem pur şi simplu să
folosim ca pivot primul element al tabloului. Iată cum arată acest algoritm:

procedure quicksort(T[i .. j])


{sortează în ordine crescătoare tabloul T[i .. j]}
if ji este mic
then insert(T[i .. j])
else pivot(T[i .. j], l)
{după pivotare, avem:
i  k < l  T[k]  T[l]
l < k  j  T[k] > T[l]}
quicksort(T[i .. l1])
quicksort(T[l1 .. j])

Mai rămâne să concepem un algoritm de pivotare cu timp liniar, care să parcurgă tabloul T o singură
dată. Putem folosi următoarea tehnica de pivotare: parcurgem tabloul T o singură dată, pornind însă din
ambele capete. Încercaţi să înţelegeţi cum funcţionează acest algoritm de pivotare, în care p = T[i] este
elementul pivot:
procedure pivot(T[i .. j], l)
{permută elementele din T[i .. j] astfel încât, în final,
elementele lui T[i .. l1] sunt  p,
T[l] = p,
iar elementele lui T[l1 .. j] sunt > p}
p  T[i]
k  i; l  j1
repeat k  k1 until T[k] > p or k  j
repeat l  l1 until T[l]  p
while k < l do
interschimbă T[k] şi T[l]
repeat k  k1 until T[k] > p
repeat l  l1 until T[l]  p
{pivotul este mutat în poziţia lui finală}
interschimbă T[i] şi T[l]

Intuitiv, ne dăm seama că algoritmul quicksort este ineficient, dacă se întâmpla în mod sistematic ca
subcazurile T[i .. l1] şi T[l1 .. j] să fie puternic neechilibrate. Ne propunem în continuare să analizăm
aceasta situaţie în mod riguros.

Operaţia de pivotare necesită un timp în (n). Fie constanta n0, astfel încât, în cazul cel mai
nefavorabil, timpul pentru a sorta n > n0 elemente prin quicksort să fie

t(n)  (n)  max{t(i)t(ni1) | 0  i  n1}

Folosim metoda inducţiei constructive pentru a demonstra independent că t  O(n2) şi t  (n2).

Putem considera că există o constantă reală pozitivă c, astfel încât t(i)  ci2c/2 pentru 0  i  n0. Prin
ipoteza inducţiei specificate parţial, presupunem că t(i)  ci2c/2 pentru orice 0  i < n. Demonstrăm că
proprietatea este adevărata şi pentru n. Avem

t(n)  dn c c max{i2(ni1)2 | 0  i  n1}

d fiind o altă constantă. Expresia i2(ni1)2 îşi atinge maximul atunci când i este 0 sau n1. Deci,

t(n)  dn c c(n1)2 = cn2c/2 n(d2c) 3c/2

Dacă luăm c  2d, obţinem t(n)  cn2c/2. Am arătat că, dacă c este suficient de mare, atunci
t(n)  cn2c/2 pentru orice n  0, adică, t  O(n2). Analog se arată că t  (n2).

Am arătat, totodată, care este cel mai nefavorabil caz: atunci când, la fiecare nivel de recursivitate,
procedura pivot este apelata o singură dată. Dacă elementele lui T sunt distincte, cazul cel mai nefavorabil
este atunci când iniţial tabloul este ordonat crescător sau descrescător, fiecare partiţionare fiind total
neechilibrată. Pentru acest cel mai nefavorabil caz, am arătat că algoritmul quicksort necesită un timp în
(n2).

1.3. Înmulţirea matricelor

Pentru matricele A şi B de n  n elemente, dorim să obţinem matricea produs C = AB. Algoritmul


clasic provine direct din definiţia înmulţirii a două matrice şi necesita n3 înmulţiri şi (n1)n2 adunări scalare.
Timpul necesar pentru calcularea matricei C este deci în (n3). Problema pe care ne-o punem este să găsim
un algoritm de înmulţire matricială al cărui timp să fie intr-un ordin mai mic decât n3. Pe de alta parte, este
clar ca (n2) este o limita inferioara pentru orice algoritm de înmulţire matriciala, deoarece trebuie în mod
necesar să parcurgem cele n2 elemente ale lui C.

Strategia divide et impera sugerează un alt mod de calcul a matricei C. Vom presupune în continuare
ca n este o putere a lui doi. Partiţionăm pe A şi B în câte patru submatrice de n/2  n/2 elemente fiecare.
Matricea produs C se poate calcula conform formulei pentru produsul matricelor de 2  2 elemente:

unde

Pentru n = 2, înmulţirile şi adunările din relaţiile de mai sus sunt scalare; pentru n > 2, aceste operaţii
sunt intre matrice de n/2  n/2 elemente. Operaţia de adunare matricială este cea clasică. În schimb, pentru
fiecare înmulţire matricială, aplicăm recursiv aceste partiţionări, până când ajungem la submatrici de 2  2
elemente.

Pentru a obţine matricea C, este nevoie de opt înmulţiri şi patru adunări de matrice de n/2  n/2
elemente. Două matrice de n/2  n/2 elemente se pot aduna intr-un timp în (n2). Timpul total pentru
algoritmul divide et impera rezultat este

t(n)  8t(n/2) (n2)

Definim funcţia

Arătaţi că recurenţa de mai sus este în O(n3).

In timp ce înmulţirea matricelor necesită un timp cubic, adunarea matricelor necesită doar un timp
pătratic. Este, deci, de dorit ca în formulele pentru calcularea submatricelor C să folosim mai puţine
înmulţiri, chiar dacă prin aceasta mărim numărul de adunări. În 1969, Strassen a descoperit o metodă de
calculare a submatricelor Cij, care utilizează 7 înmulţiri şi 18 adunări şi scăderi. Pentru început, se calculează
şapte matrice de n/2  n/2 elemente:

Este uşor de verificat ca matricea produs C se obţine astfel:


Timpul total pentru noul algoritm divide et impera este

t(n)  7t(n/2)  (n2)

şi în mod similar deducem ca t  (nlg 7). Deoarece lg 7 < 2,81, rezulta ca t  O(n2,81). Algoritmul
lui Strassen este deci mai eficient decât algoritmul clasic de înmulţire matriciala.

Realizarea sarcinei

Codul sursă a algoritmilor Mergesort şi Quicksort


#include <iostream>
#include <stdlib.h>
#include <conio.h>
using namespace std;

int np;

void copyright()
{
cout << "A efectuat: Antoci Anatoli |" << endl << "---------------------------" << endl;
}

void merge(int *A, int *t, int a, int b, int c)


{
int h, i, j, k;
h = a;
i = a;
j = b + 1;

while((h <= b) && (j <= c))


{
if(A[h] <= A[j])
{
t[i] = A[h];
++h;
}
else
{
t[i] = A[j];
++j;
}
++i;
++np;
}

if(h > b)
{
for(k=j; k < c; k++)
{
t[i] = A[k];
++i;
++np;
}
}
else
{
for(k=h; k<=b; k++)
{
t[i] = A[k];
++i;
++np;
}
}
for(k=a; k<=c; k++) A[k] = t[k];
}

void merge_sort(int *A, int *t, int a, int c)


{
int b;

if(a < c)
{
b = (a + c) / 2;
merge_sort(A, t, a, b);
merge_sort(A, t, b+1, c);
merge(A, t, a, b, c);
}
}

int Partition(int a, int c, int *arr)


{
int i, partea1, partea2, pivot;

pivot = arr[a];

while(c > a)
{
partea2 = arr[c];

while(pivot < partea2)


{
if(c <= a) break;
--c;
partea2 = arr[c];
}

partea1 = arr[a];
arr[a] = partea2;
while(pivot > partea1)
{
if(c <= a) break;
++a;
partea1 = arr[a];
}
arr[c] = partea1;
np += 2;
if(c > a && pivot <= partea1 && pivot >= partea2)
{
++a;
--c;
}
}

arr[a] = pivot;
return a;
}

void Quick_sort(int a, int c, int *arr)


{
int piv;

if(a < c)
{
piv = Partition(a, c, arr);
Quick_sort(a, piv-1, arr);
Quick_sort(piv+1, c, arr);
}
}

main()
{
// Programa data este pentru implementarea algoritmilor de sortare: mergesort, quiqsort

int nr;

copyright();

cout << "Introduceti numarul de elemente a tabloului A: ";


cin >> nr;

if(nr <= 100)


{
cout << endl << "EROARE! Numarul de elemente nu poate fi <= 100";
getch();
main();
exit(1);
}

int *A = new int[nr];


int *B = new int[nr];
int *t = new int[nr];
for(int i=0; i<nr; i++)
{
A[i] = rand()%200;
B[i] = A[i];
t[i] = A[i];
}
cout << endl << "Elementele tabloului a fost inregistrate cu succes!";
cout << endl << "Pentru continuare tastati oarecare tasta!";
getch();
system("cls");
copyright();

cout << "Tabloul aleator este: " << endl;


for(int i=0; i<nr; i++)
cout << A[i] << " ";
cout << endl;

np = 0;
cout << "--------------------------" << endl << endl;
merge_sort(A, t, 0, nr-1);
cout << "METODA MERGESORT:" << endl;
cout << "Numarul de pasi: " << np << endl;
cout << "Tabloul aranjat crescator este: " << endl;
for(int i=0; i<nr; i++)
cout << A[i] << " ";
cout << endl << endl;
delete [] A;
delete [] t;

np = 0;
Quick_sort(0, nr-1, B);
cout << "METODA QUICKSORT:" << endl;
cout << "Numarul de pasi: " << np << endl;
cout << "Tabloul aranjat crescator este: " << endl;
for(int i=0; i<nr; i++)
cout << B[i] << " ";
cout << endl;
delete [] B;
getch();
main();
}

Codul sursă a algoritmului Strassen


#include <iostream>
#include <conio.h>
#include <stdlib.h>
using namespace std;

class Strassen{

float **A, **B, **a, **b, **P;


int n;
int imp;

public:

Strassen(float **A, float **B, int n){


n++;
this->A = new float *[n+1];
for(int i=0; i<n; i++) this->A[i] = new float[n+1];
this->B = new float *[n+1];
for(int i=0; i<n; i++) this->B[i] = new float[n+1];
this->P = new float *[n+1];
for(int i=0; i<n; i++) this->P[i] = new float[n+1];

this->a = new float *[2];


for(int i=0; i<n; i++) this->a[i] = new float[2];
this->b = new float *[2];
for(int i=0; i<n; i++) this->b[i] = new float[2];
--n;

imp = 0;

// Copiem informatia in clasa


this->n = n;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
{
this->A[i][j] = A[i][j];
this->B[i][j] = B[i][j];
this->a[i][j] = 0;
this->b[i][j] = 0;
this->P[i][j] = 0;
}

delete [] A;
delete [] B;

size_m();
inmultirea_matrice();
}

~Strassen()
{
delete [] A;
delete [] B;
delete [] P;
delete [] a;
delete [] b;
}

// Functia controleaza daca matricea are o marime impara atunci se adauga zero pe LINII si pe
COLOANE
int size_m(){
if(n % 2 == 1)
{
++n;
for(int i=0; i<n; i++)
{
A[i][n-1] = 0;
A[n-1][i] = 0;
B[i][n-1] = 0;
B[n-1][i] = 0;
}

imp = 1;

return 1;
}

return 0;
}

// Functie pentru copierea matricei, din ce variabila in ce variabila


void copy_matrice(float **start, float **final, int n)
{
for(int i=0; i < n; i++)
for(int j=0; j < n; j++)
final[i][j] = start[i][j];
}

// Functia efectueaza inmultirea si divizarea in kite 2x2 matrici


void inmultirea_matrice(){
float **c = new float *[2];
for(int i=0; i<n; i++) c[i] = new float[2];

for(int r=0; r<n; r++) // rindul 2


{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
//cout << r << j << " " << r << j+1 << "*" << j << i << " " << j << 1+i << "=" << r << i << "
" << r << i+1 << endl;
//cout << r+1 << j << " " << r+1 << j+1 << "*" << 1+j << i << " " << 1+j << 1+i << "=" <<
1+r << i << " " << 1+r << i+1 << endl;

//cout << "\n************\n";

a[0][0] = A[r][j];
a[0][1] = A[r][j+1];
a[1][0] = A[r+1][j];
a[1][1] = A[r+1][j+1];
b[0][0] = B[j][i];
b[0][1] = B[j][1+i];
b[1][0] = B[1+j][i];
b[1][1] = B[1+j][1+i];

c = inmultire_2matrice(a, b);

P[r][i] += c[0][0];
P[r][1+i] += c[0][1];
P[r+1][i] += c[1][0];
P[r+1][1+i] += c[1][1];

++j;
}

++i;
}

++r;
}

delete [] c;
}

// Inmulteste 2 matrice 2x2 dupa algoritmul lui Strassen


float** inmultire_2matrice(float **a, float **b)
{
float **c = new float *[2], r, s, t, u, *P = new float[7];
for(int i=0; i<n; i++) c[i] = new float[2];
/* Metoda standarta
r = a[0][0]*b[0][0] + a[0][1]*b[1][0];
s = a[0][0]*b[0][1] + a[0][1]*b[1][1];
t = a[1][0]*b[0][0] + a[1][1]*b[1][0];
u = a[1][0]*b[0][1] + a[1][1]*b[1][1];*/

/*a = a[0][0];
b = a[0][1];
c = a[1][0];
d = a[1][1];

e = b[0][0];
g = b[0][1];
f = b[1][0];
h = b[1][1];*/

P[0] = a[0][0]*b[0][1]-a[0][0]*b[1][1];
P[1] = a[0][0]*b[1][1]+a[0][1]*b[1][1];
P[2] = a[1][0]*b[0][0]+a[1][1]*b[0][0];
P[3] = a[1][1]*b[1][0]-a[1][1]*b[0][0];
P[4] = a[0][0]*b[0][0]+a[0][0]*b[1][1]+a[1][1]*b[0][0]+a[1][1]*b[1][1];
P[5] = -a[1][1]*b[1][1]-a[1][1]*b[1][0]+a[0][1]*b[1][1]+a[0][1]*b[1][0];
P[6] = a[0][0]*b[0][0]+a[0][0]*b[0][1]-a[1][0]*b[0][0]-a[1][0]*b[0][1];

s = P[0] + P[1];
t = P[2] + P[3];
r = P[4] + P[3] - P[1] + P[5];
u = P[4] + P[0] - P[2] - P[6];

c[0][0] = r;
c[0][1] = s;
c[1][0] = t;
c[1][1] = u;

return c;
}

void view()
{
cout << "\nInmultirea matricelor este:\n";
if(imp == 1) n--;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
cout << P[i][j] << "\t";
cout << endl;
}
}

};

void copyright()
{
cout << "A efectuat studentul grupei TI-102: Antoci Anatoli |";
cout << "\n---------------------------------------------------\n";
}

main()
{
int n;
copyright();
cout << "Introduceti marimea matricelor pentru inmultire: ";
cin >> n;
if(n < 2)
{
cout << "\nEROARE! Matricea trebuie sa fie >= 2";
getch();
system("cls");
main();
exit(1);
}

// Introducerea matricelor
cout << "Introduceti matricea A(" << n << " x " << n << "):\n";
float **A = new float*[n];
for(int i=0; i<n; i++) A[i] = new float[n];

for(int i=0; i<n; i++)


for(int j=0; j<n; j++)
cin >> A[i][j];

cout << "\n\nIntroduceti matricea B(" << n << " x " << n << "):\n";
float **B = new float*[n];
for(int i=0; i<n; i++) B[i] = new float[n];

for(int i=0; i<n; i++)


for(int j=0; j<n; j++)
cin >> B[i][j];

// Efectuam inmultirea matricelor cu ajutorul metodei lui Stressen


Strassen S(A, B, n);
S.view();

// Eliberam memoria
delete [] A;
delete [] B;
}

Analiza algoritmilor

Merge Sort

Analiza Algoritnului

Sortarea Merge împarte lista de sortare in doua jumătăţi egale, si le pune in matrice diferite. Fiecare matrice
e sortata recursive, mai apoi fiind unite înapoi formînd lista finala sortata. Ca majoritatea listelor recursive,
sortarea merge are un algoritm de complexitate de O(n log n).

Analiza Empirica

Metoda de sortare merge e mai rapida decît unele metode de sortare, dar in comparative cu acele metode,
metoda merge foloseşte dublu memorie ca rezultat al divizării in doua a matricei. Metoda quick este o
alegere mai buna cînd avem de sortat seturi mari de numere.

Quick Sort

Analiza Algoritmului

Metoda quick sort este o metoda divide şi stăpîneşte, care foloseşte funcţii recursive. Este o metoda mult
mai rapida decît sortarea merge, dar metoda de sortare quick e grea de scris in cod.

Algoritmul recursive consta din 4 paşi:

Daca in matrice are unu sau mai puţine elemente de sortat face return.

Alegem un element ca punct pivot. De obicei este utilizat elementul cel mai din stînga

împărţim matricea in doua-o parte cu elementele mai mari ca pivotul si alta mai mici.

Repetam recursive algoritmul pentru ambele jumătăţi.

Eficienta depinde de care element a fost ales ca pivot. In cel mai rău caz, eficienta quick sort este de O(n2),
cînd cel mai din stînga element a fost ales ca pivot. Pentru ca eficienta sa fie mai mare alegem la întâmplare
un număr numai in cazul cand elementele din matrice nu sunt aranjate întîmplător. Cînd pivotul e ales la
întîmplare, metoda quick sort are o complexitate algoritmica de O(n log n).

Analiza Empirica

La momentul actual metoda de sortare quick sort este cea mai rapida.

Cu toate ca aceasta metoda este cea mai rapida, ea foloseşte funcţia recursive si poate duce la epuizarea
memorie alocate pentru un anumit program. Si de asemenea aceasta metoda nu e convinabila pentru
sortarea a unei matrice mici, deoarece efortul depus pentru implementarea programului este prea mare
pentru matricele mici.
Screenshoturile
Algoritmul Strassen

Concluzie
În urma efectuării acestui laborator, noi am efectuat 2 programe în C++ cu algoritmii de sortare
quiqsort şi mergesort, şi algoritmul de înmulţire a 2 matrici. În urma efectuării acestui laborator am
observat că algoritmul quiqsort este mai rapid decît mergesort, dar este mai puţin eficient pentru mulţimi
mai mari de numere.
La algoritmul Strassen de înmulţire a 2 matrici a fost folosită un algoritm ce se diferă de metoda
clasică de înmulţire, ce dă un timp mai rapid de înmulţire a matricelor.

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

  • Laboratorul 1
    Laboratorul 1
    Document11 pagini
    Laboratorul 1
    Дарья Рг
    Încă nu există evaluări
  • Lab 3
    Lab 3
    Document5 pagini
    Lab 3
    Fil Gorea
    Încă nu există evaluări
  • Grafica Laborator Nr.2
    Grafica Laborator Nr.2
    Document8 pagini
    Grafica Laborator Nr.2
    Cebotari Ion
    100% (1)
  • Lab 4 APA
    Lab 4 APA
    Document20 pagini
    Lab 4 APA
    Cristi Poselețchi
    Încă nu există evaluări
  • Lab1 Arhitectura Calculatoarelor
    Lab1 Arhitectura Calculatoarelor
    Document8 pagini
    Lab1 Arhitectura Calculatoarelor
    Valeria Lisenco
    Încă nu există evaluări
  • Raport APA Cucu Eugeniu Lab.1
    Raport APA Cucu Eugeniu Lab.1
    Document7 pagini
    Raport APA Cucu Eugeniu Lab.1
    Cucu Eugen
    Încă nu există evaluări
  • Raspunsuri AMSI
    Raspunsuri AMSI
    Document11 pagini
    Raspunsuri AMSI
    Cristina Florea
    Încă nu există evaluări
  • Prog. C++. Lab Nr. 1
    Prog. C++. Lab Nr. 1
    Document30 pagini
    Prog. C++. Lab Nr. 1
    Unknown Person
    Încă nu există evaluări
  • Laboratorul Nr1 La Grafica Pe Calculator Gc.
    Laboratorul Nr1 La Grafica Pe Calculator Gc.
    Document4 pagini
    Laboratorul Nr1 La Grafica Pe Calculator Gc.
    Ion Damaschin
    Încă nu există evaluări
  • Lab 5
    Lab 5
    Document11 pagini
    Lab 5
    hoia
    Încă nu există evaluări
  • Lab7 POO
    Lab7 POO
    Document10 pagini
    Lab7 POO
    Grosu Elena
    Încă nu există evaluări
  • POO - 004 - Particularități Clase Și Obiecte
    POO - 004 - Particularități Clase Și Obiecte
    Document25 pagini
    POO - 004 - Particularități Clase Și Obiecte
    Dorin Crasnojon
    Încă nu există evaluări
  • Despre UML
    Despre UML
    Document51 pagini
    Despre UML
    Danu Botnari
    Încă nu există evaluări
  • LL3 PS ECiobanu TI192
    LL3 PS ECiobanu TI192
    Document14 pagini
    LL3 PS ECiobanu TI192
    Ecaterina Ciobanu
    Încă nu există evaluări
  • Laborator 1 Cucu Eugeniu
    Laborator 1 Cucu Eugeniu
    Document5 pagini
    Laborator 1 Cucu Eugeniu
    Cucu Eugen
    Încă nu există evaluări
  • Lab1 Apa
    Lab1 Apa
    Document15 pagini
    Lab1 Apa
    SlavicCaldare
    Încă nu există evaluări
  • Raspunsuri AC
    Raspunsuri AC
    Document10 pagini
    Raspunsuri AC
    Anastasia
    Încă nu există evaluări
  • LL4 PS
    LL4 PS
    Document12 pagini
    LL4 PS
    Anya Mr
    100% (1)
  • POO Lab7
    POO Lab7
    Document6 pagini
    POO Lab7
    Dani Ela
    Încă nu există evaluări
  • Grafica Laborator Nr.3
    Grafica Laborator Nr.3
    Document5 pagini
    Grafica Laborator Nr.3
    Cebotari Ion
    100% (2)
  • TW Lab 5
    TW Lab 5
    Document4 pagini
    TW Lab 5
    danielploaia
    Încă nu există evaluări
  • Criptarea Asimetrica
    Criptarea Asimetrica
    Document6 pagini
    Criptarea Asimetrica
    vanikad
    Încă nu există evaluări
  • Lab 1 GC
    Lab 1 GC
    Document4 pagini
    Lab 1 GC
    Ion Popescu
    Încă nu există evaluări
  • AMOO Lab2.Use Case
    AMOO Lab2.Use Case
    Document5 pagini
    AMOO Lab2.Use Case
    Dorin Gribincea
    Încă nu există evaluări
  • Rezolvarea Numerica A Sistemelor de Ecuatii Liniare
    Rezolvarea Numerica A Sistemelor de Ecuatii Liniare
    Document8 pagini
    Rezolvarea Numerica A Sistemelor de Ecuatii Liniare
    Valentin I. Marius
    Încă nu există evaluări
  • Laboratorul Cercetari
    Laboratorul Cercetari
    Document5 pagini
    Laboratorul Cercetari
    Buinovschi Corneliu
    Încă nu există evaluări
  • PS Lab #1 2020 Short
    PS Lab #1 2020 Short
    Document12 pagini
    PS Lab #1 2020 Short
    Nina Cavcaliuc
    Încă nu există evaluări
  • TI-205 Tulbu Gabriela LAB1 IOT
    TI-205 Tulbu Gabriela LAB1 IOT
    Document9 pagini
    TI-205 Tulbu Gabriela LAB1 IOT
    GabrielaTulbu
    Încă nu există evaluări
  • PSLab 4
    PSLab 4
    Document5 pagini
    PSLab 4
    Victor Turculet
    Încă nu există evaluări
  • Examen PW
    Examen PW
    Document71 pagini
    Examen PW
    DorinRotaru
    Încă nu există evaluări
  • Somipp Linux 1 UTM
    Somipp Linux 1 UTM
    Document10 pagini
    Somipp Linux 1 UTM
    Cristi Poselețchi
    Încă nu există evaluări
  • Lab 1
    Lab 1
    Document9 pagini
    Lab 1
    Fil Gorea
    Încă nu există evaluări
  • Laborator Metode Numerice
    Laborator Metode Numerice
    Document4 pagini
    Laborator Metode Numerice
    Florin Gheorghe
    Încă nu există evaluări
  • Lucrare de Curs LFPC
    Lucrare de Curs LFPC
    Document19 pagini
    Lucrare de Curs LFPC
    Cristik95
    100% (1)
  • Co1
    Co1
    Document5 pagini
    Co1
    I LOVE ME
    Încă nu există evaluări
  • Iepuras Daniel LAB 3 TS
    Iepuras Daniel LAB 3 TS
    Document8 pagini
    Iepuras Daniel LAB 3 TS
    DanuIepuras
    Încă nu există evaluări
  • Somipplaba5 (Ru)
    Somipplaba5 (Ru)
    Document99 pagini
    Somipplaba5 (Ru)
    Maria Sevciuc
    0% (1)
  • TW Lab5
    TW Lab5
    Document3 pagini
    TW Lab5
    Dan
    Încă nu există evaluări
  • Lab1 Po
    Lab1 Po
    Document7 pagini
    Lab1 Po
    Alina Axenti
    Încă nu există evaluări
  • Laborator 4 PI-2020
    Laborator 4 PI-2020
    Document10 pagini
    Laborator 4 PI-2020
    Sandu Zastavnetchi
    Încă nu există evaluări
  • LP-NR 4
    LP-NR 4
    Document6 pagini
    LP-NR 4
    Dutcovici Radu
    100% (1)
  • Lab 4 MN
    Lab 4 MN
    Document3 pagini
    Lab 4 MN
    nn nnn
    Încă nu există evaluări
  • Lab 3 GC
    Lab 3 GC
    Document4 pagini
    Lab 3 GC
    Sergiu Şveţ
    Încă nu există evaluări
  • Lucrarea-Nr 8
    Lucrarea-Nr 8
    Document7 pagini
    Lucrarea-Nr 8
    Fil Gorea
    Încă nu există evaluări
  • TW Lab 6
    TW Lab 6
    Document6 pagini
    TW Lab 6
    DanuIepuras
    Încă nu există evaluări
  • PS Lab #3-2020 Short PDF
    PS Lab #3-2020 Short PDF
    Document19 pagini
    PS Lab #3-2020 Short PDF
    Nina Cavcaliuc
    Încă nu există evaluări
  • TW Lab4
    TW Lab4
    Document8 pagini
    TW Lab4
    Dan
    Încă nu există evaluări
  • Lucrare de Laborator NR.1 LFC
    Lucrare de Laborator NR.1 LFC
    Document10 pagini
    Lucrare de Laborator NR.1 LFC
    John Smith
    Încă nu există evaluări
  • PS Lab2
    PS Lab2
    Document13 pagini
    PS Lab2
    Dorin Osipov
    Încă nu există evaluări
  • Lucrare LFPC Cebotari Ion
    Lucrare LFPC Cebotari Ion
    Document12 pagini
    Lucrare LFPC Cebotari Ion
    Cebotari Ion
    Încă nu există evaluări
  • Raport 6
    Raport 6
    Document3 pagini
    Raport 6
    Dekionlolz В
    Încă nu există evaluări
  • Laborator 2 PI-2020
    Laborator 2 PI-2020
    Document2 pagini
    Laborator 2 PI-2020
    Sandu Zastavnetchi
    Încă nu există evaluări
  • Lab 1
    Lab 1
    Document10 pagini
    Lab 1
    Ion Cornea
    Încă nu există evaluări
  • AI-191 Medinschi Ion SO4
    AI-191 Medinschi Ion SO4
    Document5 pagini
    AI-191 Medinschi Ion SO4
    Carolin
    Încă nu există evaluări
  • Algoritmi Divide Et Impera
    Algoritmi Divide Et Impera
    Document36 pagini
    Algoritmi Divide Et Impera
    Alexandra Burecu
    Încă nu există evaluări
  • Algoritmi Divide Et Impera
    Algoritmi Divide Et Impera
    Document14 pagini
    Algoritmi Divide Et Impera
    Maria Marian
    Încă nu există evaluări
  • TMPS
    TMPS
    Document6 pagini
    TMPS
    Dragoş Ştefan Şoalcă
    Încă nu există evaluări
  • Algoritmi Si Structuri de Date 2 - Info 1 - Laborator 5
    Algoritmi Si Structuri de Date 2 - Info 1 - Laborator 5
    Document9 pagini
    Algoritmi Si Structuri de Date 2 - Info 1 - Laborator 5
    RoccoSuasito
    Încă nu există evaluări
  • 3
    3
    Document8 pagini
    3
    Paisie Rusu
    Încă nu există evaluări
  • Lab2 Apa
    Lab2 Apa
    Document17 pagini
    Lab2 Apa
    Slavic
    Încă nu există evaluări
  • Complexitatea Algoritmilor
    Complexitatea Algoritmilor
    Document47 pagini
    Complexitatea Algoritmilor
    Eugenia Ivanova
    Încă nu există evaluări
  • Lucrare de Laborator N3TS
    Lucrare de Laborator N3TS
    Document3 pagini
    Lucrare de Laborator N3TS
    Unknown Person
    Încă nu există evaluări
  • ASDN Lab. Nr. 3 GS
    ASDN Lab. Nr. 3 GS
    Document8 pagini
    ASDN Lab. Nr. 3 GS
    Unknown Person
    Încă nu există evaluări
  • ASDN Lab. Nr. 1 G.S.1
    ASDN Lab. Nr. 1 G.S.1
    Document11 pagini
    ASDN Lab. Nr. 1 G.S.1
    Unknown Person
    Încă nu există evaluări
  • ManagementulProiectelor PDF
    ManagementulProiectelor PDF
    Document104 pagini
    ManagementulProiectelor PDF
    Unknown Person
    Încă nu există evaluări
  • Steaua
    Steaua
    Document1 pagină
    Steaua
    Unknown Person
    Încă nu există evaluări
  • Rezenzie
    Rezenzie
    Document1 pagină
    Rezenzie
    Unknown Person
    Încă nu există evaluări