Sunteți pe pagina 1din 4

Divide et impera este o clas de algoritmi care funcioneaz pe baza tacticii divide et impera.

Cuprins

1 Prezentare general 2 Aplicaii o 2.1 Maximul dintr-un vector o 2.2 Cutare binar 3 Bibliografie

Prezentare general
Divide et impera se bazeaz pe principiul descompunerii problemei n dou sau mai multe subprobleme (mai uoare), care se rezolv, iar soluia pentru problema iniial se obine combinnd soluiile subproblemelor. De multe ori, subproblemele sunt de acelai tip i pentru fiecare din ele se poate aplica aceeai tactic a descompunerii n (alte) subprobleme, pn cnd (n urma descompunerilor repetate) se ajunge la probleme care admit rezolvare imediat. Nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici. Se poate afirma c numrul celor rezolvabile prin "divide et impera" este relativ mic, tocmai datorit cerinei ca problema s admit o descompunere repetat. Divide et impera este o tehnic ce admite o implementare recursiv. Principiul general prin care se elaboreaz algoritmi recursivi este: "ce se ntmpl la un nivel, se ntmpl la orice nivel" (avnd grij s asigurm condiiile de terminare). Aadar, un algoritm prin divide et impera se elaboreaz astfel: la un anumit nivel avem dou posibiliti: 1. s-a ajuns la o problem care admite o rezolvare imediat (condiia de terminare), caz n care se rezolv i se revine din apel; 2. nu s-a ajuns n situaia de la punctul 1, caz n care problema curent este descompus n (dou sau mai multe) subprobleme, pentru fiecare din ele urmeaz un apel recursiv al funciei, dup care combinarea rezultatelor are loc fie pentru fiecare subproblem, fie la final, naintea revnirii din apel.

Aplicaii
Maximul dintr-un vector

Se citete un vector cu n componente, numere naturale. Se cere s se tipreasc valoarea maxim. Funcia cutat va genera valoarea maxim dintre numerele reinute n vector pe o poziie dintre i i j (iniial, i=1, j=n). Pentru aceasta, se procedeaz astfel:

dac i=j, valoarea maxima va fi v[i]; n caz contrar, se imparte vectorul n doi subvectori - presupunem varianta pentru paralelizare pe 2 procesoare. Se calculeaz mijlocul m al intervalului [i, j]: m = (i+j) div 2. Primul subvector va conine componentele de la i la m, al doilea va conine componentele de la (m+1) la j; se rezolv subproblemele (aflndu-se astfel maximul pentru fiecare din subvectori), iar soluia curent va fi dat de valoarea maxim dintre rezultatele celor dou subprobleme.

#include<iostream.h> int v[10],n; int max(int i, int j) { int a, b, m; if (i==j) return v[i]; else { m = (i+j)/2; a = max(i, m); b = max(m+1, j); if (a>b) return a; else return b; } } main( ) { cout<<n=;cin>>n; for (int i=1; i<=n; i++) { cout<<v[<<i<<]=; cin>>v[i]; } cout<<max=<<max(1,n); }

Cutare binar
Se citete un vector cu n componente numere ntregi (numerele se presupun ordonate cresctor) i o valoare ntreag ("nr"). S se decid dac nr se gsete sau nu printre numerele citite, iar n caz afirmativ s se tipreasc indicele componentei care conine aceast valoare. O rezolvare n care nr se compar pe rnd cu toate cele n componente reperzint o pierdere de performan (nu exploateaz faptul c cele n valori sunt n secven

cresctoare). Algoritmul care va fi propus este optim i se poate spune c face parte dintre algoritmii "clasici". Funcia care va fi implementat va decide dac valoarea cutat se gsete printre numerele aflate pe poziii de indice cuprins ntre i i j (iniial, i=1, j=n). Pentru aceasta, se va proceda astfel:

dac nr coincide cu valoarea de la mijloc, aflat pe poziia de indice (i+j)/2, se tiprete indicele i se revine din apel (problema a fost rezolvat). n caz contrar, dac mai sunt i alte elemente de analizat (adic i<j, deci nu au fost verificate toate poziiile necesare), problema se descompune astfel: dac nr este mai mic dect valoarea testat (din mijloc), nseamn c nu se poate afla pe poziiile din partea dreapt, ntruct acestea sunt cel puin mai mari dect valoarea testat. Nr se poate gsi doar printre componentele cu indice ntre i i (i+j)/2 - 1, caz n care se reapeleaz funcia cu aceti parametri; dac nr este mai mare dect valoarea testat (din mijloc), nseamn c nu se poate afla n stnga; se poate gsi doar printre componentele cu indicele ntre (i+j)/2 + 1 i j, caz n care se reapeleaz funcia cu aceti parametri.

dac nu mai sunt alte elemente de analizat (pentru c i=j i valoarea din mijloc, v[i], nu coincide cu nr), se concluzioneaz c nr nu apare n cadrul vectorului.

Aceast problem nu mai necesit analiza tuturor subproblemelor n care se descompune, ea se reduce la o singur subproblem, iar partea de combinare a soluiilor dispare. n linii mari, aceast rezolvare este tot de tip "divide et impera".
#include<iostream.h> int v[100], n, nr; void caut(int i, int j) { int m = (i+j)/2; if (nr==v[m]) cout<<gasit, indice=<<m; else if (i<j) if (nr<v[m]) caut(i, m-1); else caut(m+1, j); else cout<<nu a fost gasit.; } main( ) { cout<<n=; cin>>n; for (int i=1; i<=n; i++) {

cout<<v[<<i<<]=; cin>>v[i]; } cout<<nr=; cin>>nr; caut (1,n); }

Marius Vivirski