METODA DIVIDE ET IMPERA Metoda Divide et Impera

• Slides: 10

METODA DIVIDE 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.

Sortarea prin interclasare (Merge Sort) � � � #include<iostream. h> int a[20], n; void mergesort(int i, int m, int j) {int b[20], x=i, k=1, y=m+1; while(x<=m && y<=j) if (a[x]<a[y]) b[k++]=a[x++]; else b[k++]=a[y++]; while (x<=m) b[k++]=a[x++]; while (y<=j) b[k++]=a[y++]; int t=i; for (k=1; k<=(j-i)+1; k++) a[t++]=b[k]; } void divimp(int i, int j) {if (i<j) {int m=(i+j)/2; divimp(i, m); divimp(m+1, j); mergesort(i, m, j); } } void main() { cout<<"n="; cin>>n; for(int i=1; i<=n; i++) {cout<<"a["<<i<<"]="; cin>>a[i]; } divimp(1, n); cout<<"vectorul sortat este: "<<endl; for(i=1; i<=n; i++) cout<<a[i]<<' '; }

Suma elementelor unui vector � #include<iostream> int v[20], n; int suma(int li, int ls) {int m, d 1 , d 2; if(li!=ls) {m=(li+ls)/2; d 1=suma(li, m); d 2=suma(m+1, ls); return d 1+d 2; } else return v[li]; } void main() { cout<<"n="; cin>>n; for(int i=1; i<=n; i++) {cout<<"v["<<i<<"]="; cin>>v[i]; } cout<<"suma celor "<<n<<" elemente ale vectorului "<<suma(1, n); }

Maximul unui numar. #include<iostream> int v[100], n; � int max(int i, int j) { int a, b; if(i==j) return v[i]; else { a=max(i, (i+j)/2); b=max((i+j)/2+1, j); if(a>b) return a; else return b; } } � void main() { cout<<"n="; cin>>n; for(int i=0; i<n; i++) { cout<<"v["<<i<<"]="; cin>>v[i]; } cout<<"maximul este: "<<max(0, n-1); } �

C. m. m. c � #include<iostream> int cmmdc(int a[20], int li, int ls) { if(li==ls) return a[li]; else { int x, y; x=cmmdc(a, li, (li+ls)/2); y=cmmdc(a, (li+ls)/2+1, ls); while(x!=y) if(x>y) x=x-y; else y=y-x; return x; } } void main() { int a[20], n, i; cout<<"n="; cin>>n; for(i=1; i<=n; i++) cin>>a[i]; cout<<"cmmdc este: "<<cmmdc(a, 1, n); }

Problema turnurilor din Hannoi � #include<iostream> char a, b, c; int n; void h(int n, char a, char b, char c) { if(n==1) cout<<a<<b<<" "; else { h(n-1, a, c, b); cout<<a<<b<<" "; h(n-1, c, b, a); } } void main() { cout<<"n="; cin>>n; h(n, 'a', 'b', 'c'); }

Căutarea binară a unui element într-un vector #include<iostream. h> int v[100], n, x; � void cautare(int i, int j) { if(x==v[(i+j)/2]) cout<<"gasit"<<"indice "<<(i+j)/2; else if(i<j) if(x<v[(i+j)/2]) cautare(i, (i+j)/2 -1); else cautare((i+j)/2+1, j); else cout<<"nu s-a gasit"; } � void main() { cout<<"n="; cin>>n; for(int i=0; i<n; i++) { cout<<"v["<<i<<"]="; cin>>v[i]; } cout<<"numarul cautat: "; cin>>x; cautare(0, n-1); } �

Sortarea rapida (Quick sort) #include<iostream. h> int v[100], n, x; � void caut(int i, int j) { if(x==v[(i+j)/2]) cout<<"gasit"<<"indice "<<(i+j)/2; else if(i<j) if(x<v[(i+j)/2]) caut(i, (i+j)/2 -1); else caut((i+j)/2+1, j); else cout<<"nu s-a gasit"; } � void main() { cout<<"n="; cin>>n; for(int i=0; i<n; i++) { cout<<"v["<<i<<"]="; cin>>v[i]; } cout<<"numarul cautat: "; cin>>x; caut(0, n-1); } �

� � � � � Problema taieturilor 7. Se da o bucata dreptungiulara de tabla avand lungimea L si inaltimea h. Pe suprafata ei se gasesc n gauri, de coordonate intregi, stiute, cu diametre neglijabile. Sa se decupeze o bucata de tabla de arie maxima, fara gauri, facand numai taieturi paralele cu laturile placii ( verticale sau orizontale ). Coordonatele gaurilor sunt retinute in doi vectori vx[i] pentru abscisele gaurilor si vy[i] pentru ordonate ( acesti vectori nu sunt neaparat sortati, gaurile putand fi memorate in ordine cronologica, de exemplu ). Dreptunghiul initial si apoi dreptunghiurile care apar in procesul de taiere sunt memorate prin coordonatele coltului din stanga jos ( x, y ), prin lungime L si prin inaltime h ( fiecare dreptunghi se identifica printr-un set de 4 variabile : x, y, L, h, cu ajutorul carora se formeaza coordonatele celor 4 colturi ). Pentru fiecare dreptunghi, incepand cu cel initial, cautam daca exista gaura ( existenta gaurii este semnalizata de variabila logica gasit ). Conditiile pentru ca o gaura sa se gaseasca intr-un dreptunghi dat de coordonate ( x, y, L, h ) sunt : a) vx[i] > x b) vx[i] < x+L c) vy[i] > y d) vy[i] < y+h In situatia cand avem o gaura, vom face prin ea doua taieturi, una orizontala si alta verticala, ceea ce face ca dreptunghiul curent sa se divida in alte patru, deci problema admite o descompunere in alte patru de acelasi tip ( conform strategiei " DIVIDE ET IMPERA " ). Aria maxima se memoreaza prin coordonatele dreptunghiului de arie maxima ( x. M, y. M, LM, h. M ). Daca nu avem gaura in dreptunghiul curent, acesta ar putea fi solutia problemei, deci aria acestuia se compara cu aria maxima retinuta pana la momentul respectiv si daca este cazul, se va retine ca arie maxima.

Fractali: Curba lui Koch � Un fractal este o figura geometrica fragmentata sau franta care poate fi divizata in parti astfel incat fiecare dintre acestea sa fie o copie miniaturala a intregului. � Termenul a fost introdus de Benoit Mandelbrot in 1975 si este derivat din latinescul “fractus” insemnand spart sau fracturat.