Sunteți pe pagina 1din 9

Metoda DIVIDE - ET - IMPERA

Rezolvarea unei probleme se poate face uneori astfel: - se pariioneaz problema n pri mai mici, - se rezolv fiecare parte separat, apoi se combin soluiile obinndu-se soluia final. Aceast abordare conduce, mai ales atunci cnd este folosit recursiv, la soluii eficiente pentru probleme la care subproblemele sunt versiuni mai mici ale problemei iniiale. Vom ilustra aceast tehnic prin doua exemple.

Problema turnurilor din Hanoi: Se dau trei tije simbolizate prin a, b, c. Pe tija a se gsesc discuri de diametre diferite, aezate n ordinea descresctoare a diametrelor, privite de jos n sus. Se cere s se mute discurile, respectnd urmtoarele reguli: - la fiecare pas se mut un singur disc; - nu este permis s se aeze un disc cu diametrul mai mare peste un disc cu diametrul mai mic. Dac n=1 se face mutarea ab, adic se mut discul de pe tija a pe tija b. Dac n=2 se fac mutrile ac, ab, cb. n cazul n care n>2 probm cu H(n, a, b, c) irul mutrilor celor n discuri de tija a, pe tija b, utiliznd ca tij intermediar tija c. Conform strategiei Divide et impera ncercm s descompunem problema n alte 2 subprobleme de acelai tip, urmnd apoi combinarea soluiilor.

n acest sens observm c mutarea celor n discuri de pe tija a pe tija b, utiliznd ca tij intermediar tija c, este echivalent cu: - mutarea a n-1 discuri de pe tija a pe tija c, utiliznd ca tij intermediar tija b; - mutarea discului ramas pe tija b; - mutarea a n-1 discuri de pe tija c pe tija b, utiliznd ca tij intermediar tija a. Parcurgerea celor trei etape permite definirea recursiv a irului H(n, a, b, c), astfel: ab, n = 1 H (n, a, b, c) = H(n-1, a, c, b), ab, H(n-1, c, b, a), n > 1 Exemplu: Pentru n=2, avem: H(2, a, b, c) = H(1, a, c, b), ab, H(1, c, b, a) = ac, ab, cb Pentru n = 3 avem: H(3, a, b, c) = H(2, a, c, b), ab, H(2, c, b, a) = H(1, a, b, c), ac, H(1, b, c, a), ab, H(1, c, a, b), cb, H(1, a, b, c) = ab, ac, bc, ab, ca, cb, ab Pentru n=4 avem: H(4, a, b, c) = H(3, a, c, b), ab, H(3, c, b, a) = ac, ab, cb, ac, ba, bc, ac,ab, cb, ca, ba, cb, ac, ab, cb -> imagine

#include <stdio.h> char a, b, c; int n; void han (int n, char a, char b, char c) { if (n = = 1) printf ( %c %c , a, b); else { han ( n-1, a, c, b); printf (%c, a, b); han (n-1, c, b, a); } } main ( ) } printf (n = ); scanf ( %d, &n); a =a, b=b; c=c; han (n, a, b, c); }

Exemplul 2: Sortare rapida ( QUICK SORT ) Fie vectorul a cu n componente numere ntregi. Se cere ca vectorul s se sorteze cresctor. Pentru rezolvare este necesar o funcie poz, care trateaz o poriune dintr-un vector, cuprins ntre indicii li (limita inferioar) i ls (limita superioar). Rolul acestei funcii este de a poziiona prima componenta a[li] pe o poziie k cuprins ntre li i ls astfel nct componentele vectorului, cuprinse ntre li i k-1 s fie mai mici sau egale dect a[k] i toate componentele vectorului cuprinse ntre k+1 i ls s fie mai mari sau egale dect a[k]. n aceast funcie exist doua moduri de lucru: 1) i ramne constant, j scade cu 1 2) i creste cu 1 i j ramne constant. Funcia este conceput astfel: - iniial i va lua valoarea li, iar j va lua valoarea ls; - se trece la modul de lucru 1) - ct timp i < j se executa: - dac a[i] > a[j], atunci se inverseaz cele 2 numere i se schimb modul de lucru; - i i j se modific corespunzator modului de lucru n care se afl programul; - k ia valoarea comun a lui i i j.

Exemplu: a = (6, 9, 3, 1, 2); li = 1; ls = 5 Modul de lucru 1) - i = 1, j = 5 a[1] > a[5] se inverseaz a[1] cu a[5] a = (2, 9, 3, 1, 6) i se trece la modul de lucru 2) - i = 2, j = 5 a[2] > a[5] a = (2, 6, 3, 1, 9) i se revine la modul de lucru 1) - i = 2, j = 4 a[2] > a[4] a = (2, 1, 3, 6, 9) i se trece la modul de lucru 2) - i = 3, j = 4 funcia se ncheie, elementul aflat iniial pe poziia 1 se gaseste acum pe poziia 4, toate elementele din stnga lui fiind mai mici dect el, i totodat toate elementele din dreapta lui sunt mai mari dect el. Funcia Quick are parametrii li i ls, astfel nct n cadrul ei se utilizeaz metoda Divide et impera, dupa cum urmeaza: - se apeleaz poziia; - se apeleaz Quick pentru li i k-1; - se apeleaz Quick pentru k+1 i ls.

# include <stdio.h> int a[100], n, k; void poz( int li, int ls, int &k, int a[100] { int i = li, j = ls, i1=0, j1 = - 1; while ( i < j) { if( a[i] > a[j] ) } c=a[j]; a[j]=a[i]; a[i]=c; c=i1; i1=-j1; j1=-c; } i=i+i1; j=j+j1; } k=i; } void quick (int li, int ls) { if (li<ls) { poz (li, ls, k, a); quick (li, k-1); quick (k+1, ls); } }

main ( ) { int i; printf (n=); scanf (%d, &n); for (i=1; in, i + + ) { printf ( a[%d] = , i); scanf (%d, &a[i]); } quick(1, n); for (i =1; i n; i + +) printf (%d, a[i]);