Sunteți pe pagina 1din 14

Ghid practic pentru analiza i proiectarea algoritmilor 25

#2
Metoda Divide
et Impera:
Prezentare general

Obiective:
1. Prezentarea principiului metodei Divide et Impera;
2. Exersarea metodei prin implementarea unor probleme specifice:
determinarea valorii extreme a unei mulimi de numere ntregi;
cutarea binar a unei valori ntr-o mulime ordonat cresctor;
cutarea unei sume ntr-o mulime de numere ntregi;
3. Verificarea nelegerii conceptului de rezolvare prin abordarea unor
probleme de dificultate asemntoare cu cele discutate.
















26 Ghid practic pentru analiza i proiectarea algoritmilor


2.1 Metoda Divide et Impera. Prezentare general

Metoda Divide et Impera reprezint o tehnic de programare care poate fi aplicat
acelor probleme pentru care exist o modalitate de descompunere succesiv n dou
sau mai multe subprobleme de dimensiuni mai mici (i implicit mai uoare),
subprobleme care trebuie rezolvate la rndul lor. Procedeul de mprire succesiv
(etapa divide) continu pn cnd se ajunge la subprobleme care admit o rezolvare
direct i imediat (spre exemplu, probleme de dimensiuni mici, n=1,2). Soluia
problemei iniiale se obine combinnd soluiile rezultate prin rezolvarea
subproblemelor (etapa impera).


Istoric

Expresia Divide et Impera este atribuit n general lui Iulius Cezar
potrivit cruia adversarii (politici, militari, etc.) trebuie mprii i
divizai de luptele dintre ei fiind astfel mult mai uor de nvins sau de
controlat. Puterea este mprit ntre grupuri care sunt astfel mai
slabe individual dect unite sub aceeai strategie.

Aceast strategie de a conduce a fost atribuit de-a lungul timpului i
altor suverani, de la Louis al XI-lea pn la dinastia Habsburg
1
.
Recent, reprezint i o strategie adaptat n economie n contextul
unei piee competitive cu mai muli juctori.

n domeniul programrii, ideea a fost introdus de Anatolii
Karatsuba
2
n anii 1960 prin intermediul unui algoritm de nmulire a
dou numere de n digii cu o complexitate sub O(n
2
).

Etapele de rezolvare ale unei probleme folosind aceast tehnic sunt:
1) Divide: problema iniial este descompus ntr-un numr de k
subprobleme de aceeai natur ns de dimensiuni mai mici. Procedeul
continu de natur recursiv pn cnd se ajunge la probleme de dimensiuni
elementare (n=1,2,...) care pot fi rezolvate direct;
2) Impera: problemele de dimensiuni elementare sunt rezolvate direct iar
soluiile lor sunt combinate pentru a obine soluiile subproblemelor de
dimensiuni mai mari, inclusiv soluia problemei iniiale.

Etapele succesive de mprire a problemei n subprobleme de aceeai natur ns de
dimensiuni mai mici permit atacarea unor probleme grele prin reducerea lor la cazuri
elementare care pot fi rezolvate direct i, folosind o tehnic de combinare a soluiilor
pariale, permit s fie obinut soluia problemei iniiale.

Procedura general descriind tehnica Divide et Impera este prezentat n continuare
folosind limbajul pseudocod. Varianta prezentat folosete recursivitatea ns acest
lucru nu este obligatoriu (i de regula nici recomandat) n practic.

1
http://en.wikipedia.org/wiki/Divide_and_rule
2
Anatolii Karatsuba, Yu Ofman, Multiplication of Many-Digital Numbers by Automatic Computers,
Physics-Doklady, 7 (1963), pp. 595596
Ghid practic pentru analiza i proiectarea algoritmilor 27




Pseudo
cod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedura DivideEtImpera(Problema P, dim n)
*) problema P poate fi rezolvata direct?
*) afirmativ pentru valori mici ale lui n
dac n <= c atunci
soluie RezolvDirect(P, n)
ntoarce soluie
altfel
*) mparte P n k subprobleme
(P,n) = (P
1
,n
1
)U(P
2
,n
2
)U ... U(P
k
,n
k
)
*) rezolv subproblemele
pentru i 1, k execut
soluie
i
DivideEtImpera(P
i
,n
i
)
*) combin soluiile subproblemelor
*) pentru a obine soluia problemei P
soluie Combin(
soluie
1
,
soluie
2
,
...
soluie
k

)

ntoarce soluie
sf.procedur

Procedurile RezolvDirect(...) i Combin(...) depind de natura problemei
i implementeaz rezolvarea cazurilor simple respectiv combinarea soluiilor pariale
pentru a obine soluia la o problem de o dimensiune mai mare.


Observaii

1: Natura tehnicii de a mpri problema iniial n subprobleme
permite o implementare recursiv.

2: Nu toate problemele pot fi rezolvate folosind tehnica Divide et
Impera ci numai acelea care permit o descompunere n subprobleme
de aceeai natur.

3: Prin modalitatea de descompunere i rezolvare a subproblemelor,
tehnica este adaptat pentru execuie multi-procesor sau multi-
main ntruct subproblemele distincte pot fi rezolvate distribuit i
independent, soluiile lor fiind apoi combinate.

4: Un dezavantaj al metodei este dat de folosirea mecanismului
recursivitii care presupune apeluri succesive de funcii ce conduc la
ncrcarea stivei aplicaiei.

28 Ghid practic pentru analiza i proiectarea algoritmilor


2.2 Determinarea valorii maxime dintr-un tablou de numere
ntregi

Determinarea valorii maxime

Problem

Fie o mulime de numere ntregi de dimensiune n. S se gseasc
elementul de valoare maxim.

Datele vor fi citite dintr-un fiier de intrare care conine pe prima
linie numrul de elemente n iar pe a doua linie elementele mulimii
separate printr-un spaiu. Fiierul de ieire va conine o singur linie
reprezentnd elementul de valoare maxim.

Intrare Ieire
7
3 1 8 2 7 3 5
8


Pentru a determina valoarea maxim pornim de la problema iniial de dimensiune
n: cum identificm elementul maxim aflat ntre elementele cu indicii 0 i n-1 din ir?
n acest moment putem aplica principiul diviziunii i anume, vom mpri problema
iniial de dimensiune n n 2 subprobleme de aceeai natur dar de dimensiuni mai
mici, respectiv jumtate din dimensiunea problemei iniiale, n/2. Astfel, etapa divide
va consta n mprirea irului iniial n 2 subiruri ale cror limite vor fi date de
perechile de indici {0,(n-1)/2} respectiv {(n-1)/2+1,n-1}. Dac vom rezolva
aceste 2 subprobleme vom avea drept soluii valorile maxime din cele 2 subiruri,
max
1
i max
2
. Cunoscnd aceste valori le putem combina (etapa impera) pentru a
obine soluia la problema de dimensiune n: valoarea maxim a elementelor dintre
indicii 0 i n-1 va fi cea mai mare valoare dintre max
1
i max
2
. Pentru a obine max
1

i max
2
procedm la divizri succesive ale celor dou iruri (etapa divide) pn cnd
ajungem la subiruri de dimensiuni mici 1 sau 2 pentru care soluia este evident i
imediat.


Pseudo
cod

1
2
3
4
5
6
7
8
9

procedura DeterminMaxim(a, p, q)
*) p i q sunt limitele ntre care cutm
*) valoarea maxim
dac p == q atunci
ntoarce a[p]
altfel
m (p + q) / 2
max
1
DeterminMaxim(a, p, m)
max
2
DeterminMaxim(a, m + 1, q)
ntoarce max
1
< max
2
? max
2
: max
1

sf.procedur

Ghid practic pentru analiza i proiectarea algoritmilor 29



Procedura DeterminMaxim identific elementul de valoare maxim n subirul din
a specificat de indicii p q, interval nchis. Vom apela procedura de determinare a
maximului cu limitele 0 respectiv n-1 astfel: DeterminMaxim(a,0,n-1).

Un exemplu care ilustreaz grafic parcursul algoritmului pentru fiierul de intrare
specificat n enunul problemei este prezentat n continuare. Aplicm succesiv etapa
Divide:



pn cnd ajungem la subiruri de dimensiuni foarte mici (n=1,2) pentru care
maximul poate fi determinat imediat efectund o singur comparaie. Vom aplica
apoi principiul impera, combinnd valorile maxime ale subirurilor obinute pn
ajungem la irul iniial al problemei de dimensiune n:




30 Ghid practic pentru analiza i proiectarea algoritmilor


Pentru analiza complexitii vom vizualiza divizrile succesive realizate de ctre
algoritm. Plecnd de la problema de dimensiune n vom obine 2 subprobleme de
dimensiune n/2, fiecare dintre acestea fiind iari mprite n cte 2 probleme de
dimensiune n/4, etc. La pasul j vom avea 2
j
probleme de dimensiune n/2
j
.




Putem scrie urmtoarea relaie de recuren pentru timpul de execuie necesar
algoritmului DeterminMaxim pentru a rezolva o problem de dimensiune n astfel:

> +
=
=
1 ) 1 ( ) 2 / ( 2
1 ) 1 (
) (
n n T
n
n T


pentru care avem succesiv:

) log(
1
2
2
2
1
) 1 ( ) 1 (
) 1 ( ) 2 / ( ) 2 / (
) 1 ( ) 4 / ( 2 ) 2 / (
) 1 ( ) 2 / ( 2 ) (
n
j j j
T
n T n T
n T n T
n T n T

=
+ =
+ =
+ =
+
M
M

Adunnd ecuaiile de mai sus obinem expresia pentru T(n):
Ghid practic pentru analiza i proiectarea algoritmilor 31





) 1 ( 2 ) 1 ( 2 ) (
) log(
0
) log(

|
|

\
|
+ =

=
n
j
j n
n T
, respectiv:

) ( ) 1 ( ) 1 2 ( ) 1 (
1 2
1 2
) 1 ( ) (
1 ) log(
n n n n n T
n
= + =

+ =
+


Algoritmul de determinare a elementului de valoare maxim are deci o complexitate
liniar n funcie de dimensiunea n a tabloului de numere, (n). Complexitatea
obinut prin tehnica Divide et Impera este aceeai ca i n cazul folosirii algoritmului
clasic.

2.3 Cutarea binar

Cutarea binar

Problem

Fie un tablou de numere ntregi a de dimensiune n. Tabloul este
ordonat cresctor. Fiind dat un element x, s se determine dac acest
element se regsete n cadrul tabloului.

Datele vor fi citite dintr-un fiier de intrare care conine pe prima
linie numrul de elemente n iar pe a doua linie elementele mulimii
separate printr-un spaiu. A treia linie conine elementul x ce va fi
cutat. Fiierul de ieire va conine o singur linie reprezentnd
poziia pe care s-a gsit elementul x n ir respectiv -1 n caz contrar.

Intrare Ieire
7
1 2 3 3 5 7 8
7
6


Cutarea elementului x ntr-un tablou de numere a poate fi fcut n timp liniar
parcurgnd fiecare element din ir i comparndu-l cu valoarea cutat. Cazul cel mai
defavorabil pentru acest algoritm apare atunci cnd elementul x nu este gsit ntruct
sunt necesare n comparaii cu fiecare element a[i],i=0..n-1. Complexitatea
acestui algoritm naiv de cutare va fi astfel liniar O(n).


Pseudo
cod

1
2
3
4
5

procedura Caut(a, n, x)
pentru i 0, n-1 execut
*) compar x cu fiecare element din ir
dac a[i] == x atunci
ntoarce i
ntoarce -1
sf.procedur

32 Ghid practic pentru analiza i proiectarea algoritmilor


Cunoscnd faptul c valorile irului sunt deja sortate n ordine cresctoare putem
aplica principiul metodei Divide et Impera pentru a obine un algoritm mai rapid.

S efectum de exemplu prima comparaie dintre elementul pe care l cutm x i
valoarea aflat la mijlocul irului a, a[(n-1)/2]. Dac x este mai mic atunci este
evident c nu mai este necesar s l comparm pe x cu elementele aflate n ir dup
poziia (n-1)/2 ntruct toate aceste elemente vor fi mai mari. Lum astfel decizia
de a cuta valoarea x n prima jumtate a irului a eliminnd jumtate din
comparaiile pe care primul algoritm le-ar fi efectuat. Dac x ar fi fost mai mare dect
valoarea de la mijlocul irului, a[(n-1)/2], atunci am fi luat decizia cutrii lui x n
a doua jumtate a irului a. Oricare jumtate am alege-o, repetm acelai principiu:
comparm elementul x cu valoarea aflat la mijlocul subirului. Reducem astfel
problema (etapa divide) la subprobleme de dimensiuni mai mici (jumtate din
dimensiunea problemei iniiale) pn cnd:
fie gsim condiia de egalitate dintre x i valoarea de la mijlocul subirului
curent pe care l procesm (etapa impera);
fie nu mai putem divide irul n continuare ntruct am ajuns la subproblema
de dimensiune n=1.

Algoritmul de cutare binar folosind aceast idee este prezentat n continuare.
Procedura CautBinar primete ca argumente pe lng irul a i valoarea de cutat
x i doi indici, p i q reprezentnd limitele subirului din a ntre care cutm valoarea
x. Procedura va fi apelat CautBinar(a,0,n-1,x).


Pseudo
cod



1
2
3
4
5
6
7
8
9
10
11

*) p,q reprezint limitele ntre care cutm
*) valoarea x n irul a
procedura CautBinar(a, p, q, x)
*) condiia de oprire (x nu a fost gsit)
dac p > q atunci ntoarce -1
*) calculm mijlocul intervalului
m (p + q) / 2
dac a[m] == x atunci
ntoarce m
altfel
dac a[m] < x atunci
ntoarce CautBinar(a, m + 1, q, x)
altfel
ntoarce CautBinar(a, p, m 1, x)
sf.procedur

O versiune iterativ a algoritmului de cutare binar este prezentat n continuare.

Ghid practic pentru analiza i proiectarea algoritmilor 33




Pseudo
cod

1
2
3
4
5
6
7
8
9
10
11
12

procedura CautBinar-Iterativ(a, n, x)
p 0
q n-1
ct timp p <= q execut
*) calculm mijlocul intervalului
m (p + q) / 2
dac a[m] == x atunci
ntoarce m
altfel
dac a[m] < x atunci
p m + 1
altfel q m - 1
ntoarce -1
sf.procedur

Pentru a analiza complexitatea procedurii de cutare binar vom porni prin a
determina numrul maxim de diviziuni succesive pe care algoritmul le realizeaz.
Problema iniial de dimensiune n este redus la o subproblem de dimensiune n/2
care, la rndul ei, este redus la una de dimensiune n/4, etc.



La fiecare pas dimensiunea subirului n care cutm (sau echivalent, dimensiunea
subproblemei pe care o rezolvm) se reduce la jumtate deci la pasul j vom cuta
ntr-un subir de dimensiune n/2
j
. Numrul maxim de pai k este obinut atunci
cnd valoarea cutat x nu se afl n ir, respectiv cnd ajungem prin divizri
succesive la un subir de dimensiune 1:

34 Ghid practic pentru analiza i proiectarea algoritmilor


1
2
=
(

k
n


Aplicnd inegalitatea

x x x < 1
obinem succesiv:

k k k
n n n
2 2
1
2

< ,
k k
n n
2
1 1
2
< ,

<
k
k
n
n
2
1
2
2
sau, echivalent,

<
) log(
1 ) log(
n k
k n
, respectiv ) log( 1 ) log( n k n < i, n final:

) log(n k =

De unde putem deduce complexitatea algoritmului de cutare binar ca fiind
logaritmic O(log(n)). Observm o reducere substanial a complexitii fa de
algoritmul de cutare liniar care ne furniza acelai rezultat n O(n).

2.4 Complexitatea algoritmilor Divide et Impera

Tehnica Divide et Impera poate fi descris prin apeluri recursive la subprobleme de
aceeai natur de dimensiuni mai mici ceea ce face ca timpul de execuie s poat fi
descris de asemenea printr-o relaie de recuren:

> + +

=
c n n I n D b n T a
c n
n T
) ( ) ( ) / (
) 1 (
) (


unde D(n) reprezint timpul necesar aplicrii etapei divide iar I(n) timpul necesar
aplicrii etapei impera.


Teorem
Teorema Master
Fie 1 a i 1 > b constante, f(n) o funcie i T(n) o funcie definit
prin recurena:
) ( ) / ( ) ( n f b n T a n T + =
Atunci T(n) poate fi delimitat asimptotic astfel:
Dac ) ( ) (
log
=
a
b
n O n f pt. 0 > atunci ) ( ) (
log a
b
n n T =
Dac ) ( ) (
log +
=
a
b
n n f pt. 0 > i dac
) ( ) / ( n f c b n f a pt. 1 < c atunci )) ( ( ) ( n f n T =
Dac ) ( ) (
log a
b
n n f = atunci ) log ( ) (
log
n n n T
a
b
=

Ghid practic pentru analiza i proiectarea algoritmilor 35




Exemplu
1) Fie funcia n n T n T + = ) 3 / ( 9 ) ( .
Avem a=9,b=3,f(n)=n,
2 9 log log
3
n n n
a
b
= =
Cum ) ( ) (
2
= n O n f obinem aproximarea ) ( ) (
2
n n T = (cazul 1)

2) Fie funcia n n n T n T log ) 4 / ( 3 ) ( + =
Avem a=3,b=4,f(n)=n*log(n),
79 . 0 3 log log
4
n n n
a
b
= =
Cum ) ( ) (
79 . 0 +
= n n f obinem ) log ( ) ( n n n T = (cazul 2)

3) Fie funcia 1 ) 3 / 2 ( ) ( + = n T n T
Avem a=1,b=3/2,f(n)=1, 1
1 log log
2 / 3
= = n n
a
b

Cum ) 1 ( ) ( = n f obinem aproximarea ) (log ) ( n n T = (cazul 3)

Putem aplica teorema Master pentru analiza complexitii algoritmilor de
determinare a elementului de valoare maxim respectiv de cutare binar, verificnd
astfel rezultatele la care am ajuns prin numrarea efectiv a pailor.


Exemplu
Determinarea elementului de valoare maxim

Timpul de execuie este descris recursiv de:

> +
=
=
1 ) 1 ( ) 2 / ( 2
1 ) 1 (
) (
n n T
n
n T

(att D(n) ct i I(n) se execut n (1)).

Avem a=2,b=2, ) 1 ( ) ( = n f , n n n
a
b
= =
2 log log
2

Cum ) ( ) ( n O n f = obinem aproximarea
) ( ) ( n n T =
(cazul 1)


Exemplu
Cutarea binar

Timpul de execuie este descris recursiv de:

> +
=
=
1 ) 1 ( ) 2 / (
1 ) 1 (
) (
n n T
n
n T

(att D(n) ct i I(n) se execut n (1)).

Avem a=1,b=2, ) 1 ( ) ( = n f , 1
1 log log
2
= = n n
a
b

Cum ) 1 ( ) ( = n f obinem aproximarea ) (log ) ( n n T = (cazul 3)

36 Ghid practic pentru analiza i proiectarea algoritmilor


2.5 Elementul sum

Vom considera n continuare o problem care poate fi rezolvat eficient prin
reducerea la aplicarea repetat a unei probleme rezolvate clasic (i eficient) folosind
tehnica Divide et Impera. Vom analiza att algoritmul imediat ct i o nou variant,
mai puin intuitiv, ns mult mai performant din punct de vedere al complexitii
temporale.

Elementul sum

Problem


Fie un ir de numere ntregi de dimensiune n i fie un numr x. S se
determine dac exist dou elemente din ir a cror sum s fie x.

Fiierul de intrare va conine pe prima linie numrul de elemente din
ir iar pe a doua linie elementele irului separate printr-un spaiu. A
treia linie conine valoarea x. Fiierul de ieire va avea o singur linie
coninnd cele dou elemente din ir care adunate dau suma x
respectiv -1 dac nu exist soluie.

Intrare Ieire
6
7 1 5 3 2 8
11
3 8


O prim variant de rezolvare este prezentat n continuare i presupune testarea
sumei tuturor perechilor de elemente din a. ntruct avem n*(n-1)/2 perechi de
elemente de testat, complexitatea algoritmului va fi ptratic, O(n
2
).


Pseudo
cod

1
2
3
4
5
6
7
8

procedura Suma(a, n, x)
pentru i 0, n-2 execut
pentru j i+1, n-1 execut
*) testm perechea (i, j)
*) din totalul n*(n-1)/2
dac a[i] + a[j] == x atunci
scrie a[i], a[j]
stop
scrie -1
sf.procedur

O alt variant mai puin intuitiv de rezolvare const n sortarea tabloului de
numere dup care, pentru fiecare element a[i], vom cuta binar n tabloul a
elementul complementar fa de x, x-a[i]. Dac acesta se afl n tablou atunci avem
soluia a[i],x-a[i].

Ghid practic pentru analiza i proiectarea algoritmilor 37




Pseudo
cod

1
2
3
4
5
6
7

procedura Suma-2(a, n, x)
*) sorteaz cresctor irul a
pentru i 0, n-1 execut
j CautBinar(a, i+1, n-1, x-a[i])
dac j != -1 atunci
scrie a[i], a[j]
stop
scrie -1
sf.procedur

Am demonstrat pentru algoritmul de cutare binar o complexitate logaritmic,
O(log(n)). Procedura Suma-2 va aplica cutarea binar repetat pentru fiecare
element din a deci vom avea o complexitate maxim pentru liniile 2-6 de
O(n*log(n)). Alegnd o metod de sortare care ordoneaz cresctor irul a ntr-o
complexitate liniar logaritmic
3
, O(n*log(n)), vom obine o complexitate total
pentru procedura Suma-2 de O(n*log(n)).

2.6 Probleme propuse

2.6.1 Implementai problema cutrii elementului maxim dintr-un tablou
de numere ntregi.

a. Modificai algoritmul de determinare a elementului maxim astfel nct s obinei
att valoarea maxim ct i valoarea minim din ir. Care este timpul de calcul
necesar? Care este complexitatea asociat?

b. Implementai varianta nerecursiv a algoritmului de determinare a elementului de
valoare maxim.

2.6.2 Implementai algoritmul de cutare binar a unei valori ntr-un
tablou deja sortat.

Implementai i algoritmul de cutare liniar i msurai timpul de execuie pentru
valori mari ale lui n (~1,000,000, 10,000,000, 100,000,000). Comparai
timpul de execuie pentru cei doi algoritmi i verificai grafic dependena liniar
respectiv logaritmic.
Elementele tabloului respectiv fiierul de intrare vor fi generate automat folosind un
generator de numere aleatoare disponibil n librriile limbajului de programare.

2.6.3 Rezolvai urmtoarele probleme aplicnd tehnica Divide et Impera.
Determinai pentru fiecare problem timpul de execuie folosind att metoda de
numrare a pailor ct i teorema Master.


3
Spre exemplu metoda sortrii prin interclasare (care folosete tot principiul Divide et Impera).
38 Ghid practic pentru analiza i proiectarea algoritmilor


Cel mai mare divizor comun

Problem


Fie un ir de numere ntregi de dimensiune n. S se calculeze cel mai
mare divizor comun al acestora.

Fiierul de intrare va conine pe prima linie numrul de elemente din
ir iar pe a doua linie elementele irului separate printr-un spaiu.
Fiierul de ieire va avea pe prima linie cel mai mare divizor comun.

Intrare Ieire
3
125 75 1500
25


Ghicete numrul

Problem


Scriei un program care va ghici un numr ales de dvs ntre 1 i n. De
fiecare dat cnd calculatorul va propune o soluie, i vei rspunde
cu urmtoarele variante:
numrul este prea mare
numrul este prea mic
numrul a fost ghicit

Valoarea n ct i variantele de rspuns vor fi citite ntr-o manier
interactiv de la tastatur.

Suma ptratelor

Problem


Fie un ir de numere ntregi de dimensiune n. S se calculeze suma
ptratelor elementelor irului folosind abordarea specific metodei
Divide et Impera.

Fiierul de intrare va conine pe prima linie numrul de elemente din
ir iar pe a doua linie elementele irului separate printr-un spaiu.
Fiierul de ieire va avea pe prima linie suma ptratelor.

Intrare Ieire
4
7 1 5 3
84

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