Documente Academic
Documente Profesional
Documente Cultură
Divide Et Impera Clasa - Odt
Divide Et Impera Clasa - Odt
et impera
Metoda
Divide et
Impera
(Imparte si
Stapaneste)
este o metoda
de programare
care se aplica problemelor care pot fi descompuse in subprobleme independente, similare problemei
initiale, de dimensiuni mai mici si care pot fi rezolvate foarte usor.
Procesul se reia pana cand (in urma descompunerilor repetate) se ajunge la probleme care
admit rezolvare imediata.
Metoda presupune:
Descompunerea problemei Pb curente in subprobleme independente SubPbi.
In cazul in care subproblemele SubPbi. admit o rezolvare imediata se compun solutiile si se rezolva
problema Pb.
Altfel se descompun in mod similar si subproblemele SubPbi.
Evident, nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici.
Majoritatea algoritmilor de Divide et Impera presupun prelucrari pe tablouri (dar nu obligatoriu).
Aceasta metoda (tehnica) se poate implementa atat iterativ dar si recursiv. Dat fiind ca problemele
se impart impart in subprobleme in mod recursiv, de obicei impartirea se realizeaza pana cand sirul
obtinut este de lungime 1, caz in care rezolvarea subproblemei este foarte usoara, chiar banala.
Spre exemplu fie un vector X=[x1, x2, x3, …xi … xmij… xj, …xn] asupra caruia se aplica o prelucrare.
Pentru orice secventa din vector delimitata de indecsii st si dr, st<dr exista o valoare p astfel incat
prin prelucrarea secventelor :
xst, xst+1, xst+2, xst+3, …xmij si xmij+1, xmij+2, xpmij3, …xdr
se obtin solutiile corespunzatoare celor doua subsiruri care prin compunere conduc la obtinerea
solutiei prelucrarii secventei:
xst, xst+1, xst+2, xst+3, …xdr
în caz contrar, se imparte vectorul în doi subvectori - presupunem varianta pentru paralelizare pe 2
procesoare. Se calculează mijlocul m al intervalului [st, dr]: m = (st+dr) div 2. Primul subvector va
conține componentele de la st la m, al doilea va conține componentele de la (m+1) la dr; se rezolvă
subproblemele (aflându-se astfel maximul pentru fiecare din subvectori), iar soluția curentă va fi
dată de valoarea maximă dintre rezultatele celor două subprobleme.
#include <iostream>
using namespace std;
int v[10],n;
int max(int st, int dr)
{ int a, b, mij;
if (st==dr)
return v[st];
else
{ mij = (st+dr)/2;
a = max(st, mij);
b = max(mij+1, dr);
if (a>b)
return a;
else
return b;
}
}
int main( )
{ int i;
cout<<"n=";cin>>n;
for(i=1; i<=n; i++)
{ cout<<"v["<<i<<"]=";
cin>>v[i];
}
cout<<"max="<<max(1,n);
return 0;
}
int main( )
{ int i;
cout<<"n=";cin>>n;
for(i=1; i<=n; i++)
{ cout<<"v["<<i<<"]=";
cin>>v[i];}
cout<<cmmdc(1,n);
return 0;
}
Produsul intr-un vector
#include <iostream>
using namespace std;
int v[10],n;
int produs(int st, int dr)
{ int p1, p2, mij;
if (st==dr)
return v[st];
else
{ mij =(st+dr)/2;
p1 = produs(st, mij);
p2 = produs(mij+1, dr);
return p1*p2;}
}
int main( )
{ int i;
cout<<"n=";cin>>n;
for(i=1; i<=n; i++)
{ cout<<"v["<<i<<"]=";
cin>>v[i];
}
cout<<"produs="<<produs(1,n);
return 0;
}
Cautarea binara
Funcția care va fi implementată va decide dacă valoarea căutată se găsește printre numerele aflate
pe poziții de indice cuprins între st și dr (inițial, st=1, dr=n). Pentru aceasta, se va proceda astfel:
dacă x este mai mic decât valoarea testată (din mijloc), înseamnă că nu se poate afla pe pozițiile
din partea dreaptă, întrucât acestea sunt cel puțin mai mari decât valoarea testata
x se poate găsi doar printre componentele cu indice între st și mij-1, caz în care se
reapelează funcția cu acești parametri;
• dacă x este mai mare decât valoarea testată (din mijloc), înseamnă că nu se poate afla în stânga; se
poate găsi doar printre componentele cu indicele între mij+1 și st, caz în care se reapelează funcția
cu acești parametri.
• dacă nu mai sunt alte elemente de analizat (pentru că st=dr și valoarea din mijloc, v[mij], nu
coincide cu x), se concluzionează că x nu apare în cadrul vectorului si se returneaza -1.
#include <iostream>
using namespace std;
int v[100], n, x;
int cautare(int st, int dr)
{int mij;
if(st<dr)
{mij =(st+dr)/2;
if (x==v[mij])
return 1;
else
if (x<v[mij])
cautare(st, mij-1);
else cautare(mij+1, dr);
}
else
return -1;
}
int main( )
{
cout<<"n="; cin>>n;
for (int i=1; i<=n; i++)
{
cout<<"v["<<i<<"]="; cin>>v[i];
}
cout<<"x="; cin>>x;
cout<<cautare (1,n);
return 0;
}