Sunteți pe pagina 1din 74

Mitic Craus

Proiectarea Algoritmilor

Autorul cere scuze pentru eventualele greeli ce pot apare n text

Proiectarea Algoritmilor
_____________________________________________________________________________________

Cuprins
COMPLEXITATEA ALGORITMILOR........................................................................................................................... 5
Msurarea complexitii............................................................................................................................................................. 5
Clase de complexitate ................................................................................................................................................................ 5
Teze............................................................................................................................................................................................ 6
Complexitatea algoritmilor secventiali....................................................................................................................................... 7
METODE DE PROIECTARE A ALGORITMILOR ORIENTATE PE PROBLEM..................................................... 11
PROBLEMA CUTRII.............................................................................................................................................. 12
Cutarea secvenial................................................................................................................................................................. 12
Cutarea binar ........................................................................................................................................................................ 13
Arbori binari de cutare ........................................................................................................................................................... 14
Pattern Matching...................................................................................................................................................................... 15
PROBLEMA SORTRII.............................................................................................................................................. 17
Bubble Sort (sortare prin interschimbare)................................................................................................................................ 17
Insertion Sort (sortare prin inserare) ........................................................................................................................................ 17
Shell Sort (sortare prin metoda Shell) ...................................................................................................................................... 18
Radix Sort ................................................................................................................................................................................ 19
Heap_Sort ................................................................................................................................................................................ 20
Merge_Sort i Quick_Sort ....................................................................................................................................................... 24
METODE GENERALE DE PROIECTARE A ALGORITMILOR ................................................................................. 26
METODA DIVIDE-AND-CONQUER (DIVIDE-ET-IMPERA)....................................................................................... 28
Descrierea metodei...................................................................................................................................................................... 28
Modelul metodei.......................................................................................................................................................................... 28
Eficiena metodei......................................................................................................................................................................... 28
Modelul metodei pentru cazul arborelui binar de recursie: .................................................................................................. 30
Studii de caz ................................................................................................................................................................................ 30
Sortarea prin prin interclasare .................................................................................................................................................. 30
Sortarea rapida (C.A.R. Hoare)................................................................................................................................................ 32
METODA GREEDY..................................................................................................................................................... 36
Descrierea metodei...................................................................................................................................................................... 36
Modelul metodei.......................................................................................................................................................................... 36
Eficiena metodei......................................................................................................................................................................... 37
Studii de caz ................................................................................................................................................................................ 37
Interclasare optimala ................................................................................................................................................................ 37
Compresiile de date. Arbori Huffman...................................................................................................................................... 40
Drum minim ntr-un graf ( surs - destinatie ).......................................................................................................................... 42
Problema rucsacului (Knapsack)............................................................................................................................................. 43
PROGRAMAREA DINAMIC..................................................................................................................................... 46
2
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
Descrierea metodei ...................................................................................................................................................................... 46
Modelul metodei.......................................................................................................................................................................... 48
Eficiena metodei......................................................................................................................................................................... 49
Comparatie intre metoda programrii dinamice si metoda greedy........................................................................................ 49
Studii de caz................................................................................................................................................................................. 50
Problema rucsacului (0/1) ........................................................................................................................................................ 50
Inmultire optim de matrici ...................................................................................................................................................... 52
Arbori binari de cautare optimali ............................................................................................................................................. 53
METODA BACKTRACKING ...................................................................................................................................... 57
Descrierea Metodei ..................................................................................................................................................................... 57
Spatiul solutiilor. Restrictii...................................................................................................................................................... 57
Backtracking si Branch-and-Bound......................................................................................................................................... 59
Modelul metodei.......................................................................................................................................................................... 60
Studii de caz................................................................................................................................................................................. 61
Problema celor 8 dame ............................................................................................................................................................. 61
Submulimi de sum dat ......................................................................................................................................................... 62
METODA BRANCH AND BOUND ......................................................................................................................... 65
Descrierea metodei ...................................................................................................................................................................... 65
Branch and Bound (BB) cu strategie cost minim (LC) ............................................................................................................ 69
Modelul metodei pentru strategia LC ....................................................................................................................................... 69
Mrginire..................................................................................................................................................................................... 70
Modelul metodei pentru strategia LC cu mrginire .................................................................................................................. 70
Problema 0/1 a rucsacului ( 0/1 knapsack ) ............................................................................................................................. 71
Algoritmul BB_LC pentru problema 0/1 a rucsacului:............................................................................................................. 73

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Complexitatea algoritmilor
Teoria complexittii are ca obiect de studiu clasificarea problemelor, bazat pe timpul de executie si spatiul de lucru
utilizat de algoritmi pentru solutionarea lor. Cnd se analizeaz algoritmi paraleli, se poate lua n considerare si numrul de
procesoare.
Desi teoria complexittii a fost dezvoltat pentru probleme de decizie, aceasta nu este o restrictie sever deoarece multe
alte probleme pot fi formulate n termeni de probleme de decizie. De exemplu o problem de optimizare poate fi rezolvat
prin punerea ntrebrii existentei unei solutii cu cel mult sau cel putin o valoare specificat.

Msurarea complexitii
Complexitatea timpului de executie a unui algoritm paralel care rezolv o instant de dimensiune n a unei probleme, pe
o masin paralel cu p procesoare (p=dimensiunea masinii) se noteaz a cu T(p,n)=Tp(n).
O problem se numeste dependent de dimensiunea masinii (PDD) dac n este o functie de variabil p. Altfel,
problema se numeste independent de dimensiunea masinii (PID). Un algoritm dependent de dimensiunea masinii este un
algoritm ce rezolv o problem PDD. altfel, algoritmul se numeste independent de dimensiunea masinii.
Factorul de ncrcare (L) a unei probleme este raportul n/p. Viteza Sp(n)) unui algoritm paralel este raportul
T1(n)/Tp(n). Eficienta (Ep(n)) unui algoritm paralel se defineste ca fiind raportul dintre vitez si numrul procesoarelor:
E p(n)=Sp(n)/p=T1(n)/[pTp(n)].
Pentru a aprecia comportarea asimtotic a functiei Tp(n) se utilizeaz urmtoarele notiuni:
Fiind date dou functii f si g pozitive de variabile p si n se noteaz :
o(g)={f/()>0,[{p0,n0(p)} N] a.i.()[(p>p0) (n>n0(p))]: f(p,n)<g(p,n)}
Rezult c f este n o(g) dac limn(f/g)=0.
O(g)={f/ [{p0,n0(p)} N cR+] a.i.( )[(p>p0) ) (n>n0(p))]: f(p,n)<cg(p,n)}
Deci f este n O(g) dac functia f/g este mrginit.
(g)={f/ [{p0,n0(p)} N {c1,c2} R+] a.i.( )[(p>p0) ) (n>n0(p))]: 0<c1g(p,n)<f(p,n)<c2g(p,n)}
Aceasta nseamn c f(g) dac f/g este o functie strict pozitiv si mrginit.
(g)={f/ [{p0,n0(p)} N cR+] a.i.( )[(p>p0) ) (n>n0(p))]: 0<cg(p,n)<f(p,n)}
Rezult c f(g) dac f/g este mrginita inferior de o valoare strict pozitiv.

Clase de complexitate
Din punctul de vedere al calculului secvential, 3 clase snt relevante: P, NP, Pspace
Clasa P contine problemele solvabile n timp polinomial ceea ce nseamn c pentru aceste probleme exist algoritmi
determiniti secveniali cu timpul de executie mrginit de un polinom de variabil "dimensiunea problemei ". Problemele
din P snt numite, n mod curent, bine solutionabile sau usoare.
NP este clasa problemelor pentru care exista un algoritm sevenial nedeterminist cu timp de execuie polinomial
(echivalent : nu exist un algoritm secvenial determinist cu timp de executie polinomial.)
Pspace contine problemele care snt solvabile utiliznd un spatiu polinomial, adic spatiul de lucru este marginit de un
polinom de variabil " dimensiunea problemei ".
Evident, P NP Pspace . Se presupune c ambele incluziuni snt proprii (stricte).
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
O alt clas inclus n Pspace, neinteresant din punct de vedere al calculului secvential, dar important pentru calculul
paralel este Polylogspace. Aici snt incluse problemele rezolvabile n spatiu polilogaritmic (spatiul de lucru este mrginit de
un polinom de variabil "log(dimensiunea problemei)"). Multe probleme din P apartin lui Polylogspace, dar n general, se
crede c P Polylogspace. Se stie totusi c Polylogspace#
# Pspace .

Remarcabile n Pspace si NP snt problemele complete.Problemele Pspace-complete snt generalizri ale tuturor
celorlalte probleme din Pspace n termeni de transformri care necesit timp polinomial. Mai precis: o problem este
Pspace-complet sub transformri de timp polinomial dac apartine lui Pspace si oricare alt problem din Pspace este
reductibil la ea prin transformri care necesit timp polinomial. Urmeaz c dac o problem Pspace-complet ar apartine
lui P atunci Pspace = P. Deoarece se crede c aceasta egalitate nu este adevrat, este improbabil s existe un algoritm de
timp polinomial pentru o problem Pspace-complet. Problemele NP se definesc n mod asemntor, rezultnd aceleasi
concluzii.
Clasa P are si ea problemele ei complete. Problemele P-complete snt generalizri ale tuturor celorlalte probleme din
clasa P, n termenii transformrilor care necesit spatiu de lucru logaritmic. Formal, o problem este P-complet sub
transformri spatiale logaritmice dac apartine clasei P si orice alt problem din P este reductibil la ea prin transformri
ce utilizeaz spatiu logaritmic. Dac o problem P-completa ar apartine clasei Polylogspace, atunci ar fi adevrat
incluziunea P Polylogspace. Cum aceast incluziune se presupune a fi fals, nu este de asteptat s existe un algoritm
pentru o problem P-complet care s utilizeze spatiu de lucru polilogaritmic.

Teze

Relatia ntre calculul secvential si paralel este dat de teza calculului paralel (Chandra, Kozen & Stockmeyer, 1981;
Goldshlager, 1982): pentru orice functie T(n), (n= dimensiunea problemei), clasa problemelor solvabile de o masin cu
paralelism nemrginit n timp T(n)O(1) (polinomial n T(n) ) este egal cu clasa problemelor solvabile de masini secventiale
cu spatiu (T(n))O(1) .
Aceast tez este o teorem pentru multe dintre modelele relativ rezonabile. Astfel, clasa problemelor solvabile n
T(n)O(1) timp de o masin PRAM este egal cu clasa problemelor solvabile cu T(n)O(1) spatiu de lucru de o masin Turing,
dac T(n)log n (Fortune & Wyllie, 1978). In consecint, clasa problemelor solvabile de o masin PRAM n timp paralel
polinimial este egal cu clasa Pspace. De asemenea, Polylogspace este clasa problemelor solvabile de o masin PRAM n
timp paralel polilogaritmic.
Problemele din P
Polylogspace snt solvabile n timp paralel polilogaritmic. Ele pot fi considerate cele mai usoare
probleme din P, n sensul c influenta dimensiunii problemei asupra timpului de rezolvare a fost redus la minimum. O
reducere ulterioar a a timpului de solutionare la dimensiuni sublogaritmice este, n general, imposibil. Una din ratiunile
acestei afirmatii este aceea c o masin PRAM necesit O(log n) timp pentru activarea a n procesoare.
Pe de alt parte, este improbabil ca problemele P-complete s admit solutii n timp polilogaritmic. Dac o astfel de
problem ar fi rezolvabila n timp paralel polilogaritmic ar urma c apartine clasei Polylogspace si astfel ar fi adevrat
incluziunea P
Polylogspace. Din acest motiv, nu este de asteptat o solutie n timp paralel polilogaritmic. Orice metod de
rezolvare pentru problemele grele din P necesit probabil timp superlogaritmic si aceasta deoarece natura lor este probabil
inerent secventiala. Aceasta nu nseamn ns c paralelismul nu poate aduce cresteri substantiale de vitez, algoritmilor de
rezolvare.
In concluzie, clasa P poate fi partitionat n probleme foarte usoare (very easy) care snt rezolvabile n timp paralel
polilogaritmic si probleme mai putin usoare (not so easy), pentru care este improbabil cresterea vitezei prin paralelism.

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Complexitatea algoritmilor secventiali


La evaluarea (estimarea) algoritmilor secveniali se pune n eviden necesarul de timp i de spaiu de memorare.
Studierea complexitii presupune analiza completa n cadrul algoritmului a urmtoarelor 3 aspecte:
1.
configuraia de date cea mai defavorabil (cazurile degenerate);
2.
configuraia de date cea mai favorabil;
3.
comportarea medie.
Comportarea medie presupune probabilitatea de apariie a diferitelor configuraii de date la intrare.
Aspectul 1 este cel mai studiat i este folosit, de obicei, pentru compararea algoritmilor secveiali.
Complexitatea unui algoritm secvenial se exprim de regul n limbajul ordinului O.
Definitie
Fie f : N N si g : N N dou funcii.
Spunem c f O(g) i notm f = O(g) dac i numai dac o constant c R+ i un numr
n0 N astfel nct pentru n > n0 f(n) < cg(n)
Observaie:
n reprezint de obicei dimensiunea datelor de intrare iar f(n) timpul de lucru al algoritmului exprimat n "pai".
Lem:
Daca f este o functie polinomiala de grad k, de forma:
f(n) = ak nk + ak-1nk-1 + ... + a1 n + a0, atunci f = O(nk).
Fcndu-se majorari n membrul drept, obinem rezultatul de mai sus:
f(n) <= ak nk + ak-1 nk-1 + ... +a1 n +a0 < nk (ak + ak-1 + a0) < nk c
f(n) < c nk, cu n0 = 1.
Concluzie: f = O(nk), i ordinul O exprim viteza de variaie a funciei, funcie de argument.

pentru n > 1

Exemplul 1: Calcularea maximului unui ir


Max_Sir (A,n)
{
max = A[1];
for i = 2,,n if (A[i]) > max) max = A[i];
return (max)
}
Dac notm cu T(n) timpul de execuie n pai al acestui algoritm atunci T(n)= 1 + 2(n-1) = numrul de atribuiri i
comparaii
Cazul cel mai defavorabil: situaia n care vectorul este ordonat cresctor (pentru c de fiecare dat se face i
comparaie i atribuire).
Putem spune ca T(n) = O(n), este o functie polinomiala de gradul I. Conteaz doar ordinul polinomului, nu coeficientul
termenului de grad maxim, iar la numrarea pailor ne concentrm asupra numrului buclelor, nu asupra pailor din
interiorul buclei.
Exemplul 2: Insertion Sort (algoritmul de sortare prin inserare)
Algoritmul INSERTION SORT consider c n pasul k, elementele A[1k-1] sunt sortate, iar elementul k va fi inserat,
astfel nct, dupa aceasta inserare, primele elemente A[ 1k] s fie sortate.
Pentru a realiza inserarea elementului k n secventa A[1k-1], aceasta presupune:

memorarea elementului ntr-o varibil temporar;

deplasarea tuturor elementelor din vectorul A[1k-1] care sunt mai mari dect A[k], cu o poziie la
dreapta (aceasta presupune o parcurgere de la dreapta la stnga);

plasarea lui A[k] n locul ultimului element deplasat.


_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
Complexitate: O(n)
Insertion_Sort (A,n)
{
for k = 2,,n
{
temp = A[k];
i=k-1;
while (i >=1 and A[i] > temp)
{
A[i+1] = A[i];
i=i-1;
}
A[i+1] = temp;
}
Cazul cel mai dafavorabil: situatia n care deplasarea (la dreapta cu o poziie n vederea nserrii) se face pn la
nceputul vectorului, adic irul este ordonat descresctor.
Exprimarea timpului de lucru:
T(n) = 3(n - 1) +3(1 + 2 + 3+ ... + n - 1) = 3(n-1) + 3n (n - 1)/2
Rezult complexitatea: T(n) = O(n2) funcie polinomial de gradul II.
Observaie: Cnd avem mai multe bucle imbricate, nivelul buclei celei mai interioare dau gradul polinomului egal cu
ordinul de complexitate al algoritmului.
Bucla cea mai interioara ne da complexitatea algoritmului.
n

i = O( n2 )
i =1

Exemplul 3: nmulirea a dou matrici


Prod_Mat (A,B,C,n);
{
for i = 1,,n
for j = 1,,n
{
C[i,j] = 0;
for k = 1,,n
}
}

C[i,j] = C[i,j] + A[i,k] * B[k,j];

Rezulta complexitatea O(n3).


Exemplul 4: Cutarea binar (Binary Search)
Fie A, de ordin n, un vector ordonat cresctor. Se cere s se determine dac o valoare b se afl printre elementele
vectorului. Limita inferioar se numete low, limita superioar se numete high, iar mijlocul virtual al vectorului, mid (de la
middle).

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

low

middle

high

Binary_Search (A,n,b)
{
low = 1;
high = n;
while (low =< high)
{
mid = (low + high)/2 ;
if (A[mid]=b)
return (mid);
else
if A[mid]>b
high=mid-1;
else
low = mid+1;
}

// partea ntreag

// restrng cutarea la partea stng


// restrng cutarea la dreapta

return(0)
}
Calculul complexitii algoritmului const n determinarea numrului de ori pentru care se execut bucla while.
Se observ c, la fiecare trecere, dimensiunea zonei cutate se njumteste. Cazul cel mai defavorabil este ca
elementul cutat s nu se gaseasc n vector.
Pentru simplitate se considera n = 2k unde k este numrul de njumtiri. Rezulta k = log2 n si facnd o majorare,
T(n) log2 n + 1 .
Deci complexitatea timp a acestui algoritm este O(log2n). Baza logaritmului se poate ignora deoarece: logax = logab
logbx i logab este o constant, deci rmne O(log n), adic o funcie logaritmic.
Proprieti ale ordinului de complexitate O:
1) Fie f, g : N N.
Daca f = O(g)
| k f = O(g)
| f = O(k g) , k R
2) Fie f, g, h : N N.
si:
f = O(g)
|
g = O(h)
|
f = O(h)
3) Fie f1, f2, g1, g2 : N N.
si:
f1 = O(g1) |

| f1 + f2 = O(g1 + g2)
f2 = O(g2) |

| f1 f2 = O(g1g2)
Aceast proprietate permite ca, atunci cnd avem dou bucle imbricate (de complexiti diferite), complexitatea total
s se obin nmulindu-se cele dou complexiti. Cele dou complexiti se adun, dac buclele sunt succesive.
Teorem:
Oricare ar fi doua constante c > 0, a > 1, i f : N N, o functie monoton strict crescatoare, atunci
O(af(n))
Demonstraia se bazeaz pe limita

(f(n))c =

xp
x
x a

lim

ntre ordinul funciilor polinomiale i cel al funciilor exponeniale exist relaia: O(nc) O(an).
Au loc urmtoarele incluziuni:
O(1) O(log n) O(logk n) O(n) O(nlog n) O(n2) O(nklog n) O(nk+1) O(2n)
Pentru calculul complexitii se va ncerca ncadrarea n clasa cea mai mic de complexitate din acest ir:
O(1)
clasa algoritmilor constani;
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

O(log n)
O(logk n)
O(nlog n)
O(n)
O(n2)
O(nk+1)
O(nlogkn)
O(2n)

clasa algoritmilor logaritmici;


clasa algoritmilor polilogaritmici;
clasa algoritmilor liniari;
clasa algoritmilor patratici;
clasa algoritmilor polinomiali;
clasa algoritmilor exponentiali.

Tehnici de calcul a complexitii


Se folosesc urmtoarele sume:
n

i =
i =1
n

i =1

n(n + 1)
2

O(n 2 )

n(n + 1) (2n + 1)
6

n 2 (n + 1) 2
i =

4
i =1

O(n 3 )

O(n 4 )

21 = 2n+1 - 1
i =0

i 2

Sa calculm, de exemplu, suma:

i =1

Se noteaz:

G ( n) = i 2 i
i =1

i =1

i =1

i =1

i =1

G (n) = 2 G (n) G (n) = 2i 2 i i 2 i = i 2 i +1 i 2 i =


n

i =2

i =2

= n 2 n +1 2 + (i 1 i ) 2 i = n 2 n +1 2 2 i = (n 1) 2 n +1 + 2
n

Prin aceeai tehnic se calculeaz suma:

(n i ) 2

i =1

10

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Metode de proiectare a algoritmilor


orientate pe problem
Probleme foarte importante cum sunt cutarea i sortarea, ale cror soluii algoritmice sunt omniprezente n structurile
algoritmice ale soluiilor unor clase foarte largi de probleme, sunt studiate n mod special, n perspectiva construirii de
algoritmi optimali.

_______________________________________________________________________________

11

Proiectarea Algoritmilor
_____________________________________________________________________________________

Problema Cutrii
Problema apartenenei unui obiect la o mulime de obiecte nu n mod necesar distincte sau a incluziunii unei secvene n
alt secven apare frecvent ca subproblem n rezolvarea unei probleme prin metode algoritmice. Din acest motiv
algoritmii de cutare constituie o clas special, masiv studiat i foarte important.

Cutarea secvenial
Cutarea secvenial pornete de la premiza c mulimea de procesat este secvenializat ntr-un mod oarecare . Algoritmul
de cutare secvenial const n parcurgerea secvenei element cu element pn cnd fie este gasit obiectul cutat fie
secvena se termin. O secven poate fi implementat prin tablouri unidimensionale (vectori) sau liste liniare simplu
nlnuite. Corespunztor celor dou tipuri de structuri de date rezult doi algoritmi: Algoritmul 1 respectiv Algoritmul 2.
Algoritmul 1
Fie A, de ordin n, un tablou unimesional. Se cere s se determine dac elementul b se afl printre elementele tabloului.
Secv_Search_A(A,n,b)
// caut n tabloul A, de dimensiune n, obiectul b
{
i=1;
while (A[I]<>b and i<=n ) i=i+1
if (i>n)
return 0;
// b nu a fost gsit n tabloul A
else
return i;
// b a fost gasit pe poziia i n tabloul A
}
Algoritmul 2
Fie L o list liniara simplu nlanuit. Se cere s se determine dac obiectul b se afl printre elementele listei.
Secv_Search_L(L,b)
// caut n lista L obiectul b
{
p=L;
// data(p) = informaia de coninut a atomului adresat de p
// leg(p)=adresa atomului ce urmeaz n list atomului adresat de p
while (data(p)<>b and p<>null ) p=leg(p)
if (p=null)
return 0;
// b nu a fost gsit n lista L
else
return p; // b a fost gasit n lista L, ca informaie de coninut a atomului aflat pe poziia adresata de
pointerul p
}

Complexitatatea
Complexitatea timp pentru cazul ce mai nefavorabil este O(n) pentru ambii algoritmi.

12

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Cutarea binar
Cutarea binar folosete ca ipotez faptul c mulimea de procesat este secvenializat dup o cheie de sortare calculat n
funcie de compoziia obiectelor secvenei sau inclus n structura obiectelor ca o component a acestora. Deci secvena
int este sortat. Algoritmul de cutate binar const n eliminarea succesiv a unei jumati din subsecvena aflat n curs
de procesare pn cnd fie elementul cutat este gsit fie subsecvena rmas nu mai paote fi divizat. Aceast eliminare a
unei poriuni din subsecvena n curs de procesare este permis de ipoteza ordonrii care faciliteaz posibilitatea deciziei
asupra imposibilitii aflrii elementului cutat n una din jumtile subsecvenei. De exemplu dac cheia elementului din
mijlocul subsecvenei curente este 10 i cheia cutat este 12 iar ordonarea este cresctoare atunci sigur elementul cutat
(10) nu va fi gsit n prima jumtate. Implementare prin liste a secevnei nu aduce un spor de eficien algoritmului datorit
caracterului prin excelen secvenial al unei liste care face imposibil accesarea direct a elementului aflat la mijlocul listei.
De aceea algoritmul de cutare binar folosete implementarea secvenei sortate sub form de tablouri unidimesionale
(vectori).
Fie A, de ordin n, un vector ordonat cresctor. Se cere s se determine dac o valoare b se afl printre elementele
vectorului. Limita inferioar se numete low, limita superioar se numete high, iar mijlocul virtual al vectorului, mid (de la
middle).

low

middle

high

Binary_Search (A,n,b)
{
low = 1;
high = n;
while (low <= high)
{
mid = (low + high)/2 ;
if (A[mid]=b)
return (mid);
else
if A[mid]>b
high=mid-1;
else
low=mid+1;
}
return(0)

// partea ntreag
// b a fost gasit pe poziia mid n tabloul A
// restrng cutarea la partea stng
// restrng cutarea la dreapta

// b nu a fost gsit n tabloul A

Complexitatatea
Se observ c, la fiecare trecere, dimensiunea zonei cutate se njumteste. Cazul cel mai defavorabil este ca
elementul cutat s nu se gaseasc n vector.
Pentru simplitate se considera n = 2k unde k este numrul de njumtiri. Rezulta k = log2 n si facnd o majorare,
T(n) log2 n + 1 .
Deci complexitatea timp a acestui algoritm este O(log2n). Baza logaritmului se poate ignora deoarece: logax = logab
logbx i logab este o constant, deci rmne O(log n), adic o funcie logaritmic.

_______________________________________________________________________________

13

Proiectarea Algoritmilor
_____________________________________________________________________________________

Arbori binari de cutare


Mulimea de obiecte n care se face cutarea poate fi organizat ca arbore binar de cutare. Aceasta permite construirea de
algoritmi de cutare eficieni. Arborii binari de cutare snt acei arbori ale cror noduri snt organizate n functie de valorile
unor chei care snt calculate functie de valorile nodurillor. Pentru fiecare nod, cheia sa este mai mare dect valorile cheilor
tuturor nodurilor din subarborele stng si este mai mic dect toate cheile de noduri din subarborele drept. Nodurile
arborelui au chei distincte. In figura urmtoare este dat un arbore binar de cutare.

12

20

15

Traversarea n inordine pe un arbore binar de cutare produce o secvent sortat cresctor dup valorile cheilor.
Operatia de creare a unui arbore binar de cutare este O(n2) timp pentru cazul cel mai defavorabil cnd arborele se
construieste sub forma unei liste nlntuite. Pentru acest caz operatiile de insertie, stergere si de cutare a unui atom se fac
n O(n). Pentru cazul mediu crearea se face n O(n * log n) iar insertia, stergerea, cutarea se face n O(log n). O clas
special de arbori binari de cutare anume arborii binari echilibrati pentru care insertia, stergerea si cutarea se face n
O(log n) pentru cazul cel mai defavorabil.
Se consider functia de cutare ntr-un arbore binar de cutare.
search(r,x)
{
p=r;
while( p null)
{
if ( x < data(p) ) p=lchild(p);
else
if ( x > data(p) ) p=rchild(p);
else return(p);
}
return(p);
// return null
}
unde:
r este adresa rdcinii arborelui care are noduri de forma
(data, legtur la subarborele stng, legtur la subarborele drept)
x este valoarea cmpului de date a nodului cutat.
data(), lchild(), rchild() sint primitivele de acces la cele trei cmpuri ale unui nod, data, legtur la subarborele
stng, legtur la subarborele drept , respectiv.

Complexitatatea
Pentru un arbore echilibrat functia lucreaz n O(logn) timp, ceea ce nseamn c arborele binar echillibrat este arborele
binar optim atunci cnd se caut un element aleatoriu ales.
14

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Pattern Matching
Problema incluziunii unei secvene de obiecte n alt secven de acelai ( de exemplu a unui sir de caractere ca subir al
altuia de acelai tip) este cunoscut sub numele de pattern matching. Algoritmii de pattern matching au aplicaii n
procesarea de imagini, recunoaterea de caractere. Vom prezenta n cadrul acestei lucrri doi dintre acetia: algoritmul de
cautare naiv si algoritmul Rabin-Karp. Primul este important pentru ntelegerea conceptului de pattern matching iar al
doilea poate fi extins la pattern-uri bidimesionale deci poate fi utilizat in domeniile anterior menionate.

Algoritmul de cutare naiv


Este un algoritm foarte simplu dar si foarte ineficient: pentru fiecare poziie posibil n ir se testeaz dac pattern-ul se
potrivete cu subirul care ncepe cu acea poziie.
PM_Naiv(s,n,p,m) // caut n sirul s de dimnsiune n pattern-ul p de dimesiune m
{
i=0;
while (i<n-m and not gasit)
{
i=i+1;
// poziia n ir
j=i;
// poziia in subir
k=1;
// psoziia n pattern
while (s[j]=p[k] and not gasit)
if k=m
// a fost gasit o apariie a pattern-ului
gasit =true;
else
{
j=j+1;
// naintez n subir
k=k+1;
// nainteaz n pattern
}
}
if (not gsit)
return 0;
else
return i;

// pattern-ul p nu apare n irul s


// pattern-ul p apare n s pe poziia i

}
Complexitatatea
Evident complexitatea timp a algoritmului pentru cazul cel mai nefavorabil O(nm)
Algoritmul Rabin-Karp
Algoritmul Rabin-Karp utilizeaz tehnica tabelelor de dispersie (hashing). Un simbol este o subsecven de m obiecte a
secvenei s de dimesiune n . S presupumen c simbolurile sunt memorate ntr-o tabel de dispersie suficient de mare astfel
inct s nu existe coliziune. A testa dac pattern-ul p coincide cu un subir de lungime m din irul s este echivalent cu a
testa dac valoarea funciei de dispersie h este aceeai pentru ambele simboluri. Pentru ca o asemenea abordare s fie
justificat, timpul necesar evalurii funciei h pentru un simbol din tabela de dispersie trebuie s fie mult mai mic dect cel
necesar comparrii a dou iruri de lungime m. Aceasta se rezolv n felul urmtor|:
Se codific fiecare ir de lungime m ca un numr ntreg n baza d, unde d este numrul maxim de obiecte din irul s. Astfel
subirului s[i..i+m-1] i corespunde numrul x=index(s[i])dm-1_+ index(s[i+1])dm-2 + + index(s[i+m-1]) unde index este
o funcie care asociaz unui obiect din s numrul su de ordine ntr-o secvenializare a mulimii obiectelor care compun s.
Funcia de dispersie H va fi definit prin h(x)=x mod q , unde q este un numr prim suficient de mare. O deplasare la
dreapta n irul s va corespunde nlocuirii lui x cu (x- index(s[i])dm-1)d_+ index(s[i+m])
_______________________________________________________________________________

15

Proiectarea Algoritmilor
_____________________________________________________________________________________
PM-RK(s,n,p,m) ) // caut n sirul s de dimnsiune n pattern-ul p de dimesiune m
{
dm1=1;
for i-1..m-1
{
dm1=dm1d mod q
}
// dm1 = (puterea m-1 a lui d modulo) q
hp=0;
for i-1..m
{
hp=hpd +index(p[i])
}
// hp = valoare funciei de dispersie pentru simbolul p
hsm=0;
for i-1..m
{
hsm=hsmd +index(s[i]);
}
// hsm = valoare funciei de dispersie pentru simbolul s[1..m]
i=1;
while (hp<>hsm and i<n-m)
{
hsm = (hsm + qd - index(s[i]) dm-1 ) mod q;
hsm = (hsmd + index(s[i+m])) mod q;
// hsm = valoare funciei de dispersie pentru simbolul s[i+1..i+m]
i=i+1;
// deplasare la dreapta n irul s
}
if (hp=hsm)
return i;
// pattern-ul p apare n s pe poziia i
else
return 0;
// pattern-ul p nu apare n irul s
}
Complexitatatea
Complexitatea timp a algoritmului Rabin-Karp pentru cazul cel mai nefavorabil O(nm) dar n practic algoritmul execut
apoximativ n+m pai.

16

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Problema Sortrii
Sortarea ese o operaie foarte des ntlnit n rezolvarea unei probleme prin metode algoritmice. Din acest motiv algoritmii
de sortare constituie o clas extrem de important care merit o atenie special iar o analiz a celor mai cunoscui algoritmi
de sortare este util i necesar.

Bubble Sort (sortare prin interschimbare)


Bubble_sort (A,n)
// A[1..n] - seceventa de sortat
{
flag=1;
k=n;
while (flag 0 and k >= 1)
{
k=k-1;
flag=0;
for i=1,,k;
if ( A[i] > A[i+1] )
{
interchange ( A[i], A[i+1] );
flag=1;
}
}
}
Complexitatea: Evident O(n2)

Insertion Sort (sortare prin inserare)


Algoritmul Insertion Sort considera ca n pasul k, elementele A[1k-1] sunt sortate, iar elementul de pe poziia k va fi
inserat, astfel nct, dupa aceasta inserare, primele elemente A[1k] sa fie sortate.
Pentru a realiza inserarea elementului k n secventa A[1k-1], aceasta presupune:

memorarea elementului intr-o variabila temporara;

deplasarea tuturor elementelor din vectorul A[1k-1] care sunt mai mari dect A[k], cu o poziie la dreapta (aceasta
presupune o parcurgere de la dreapta la stnga);

plasarea lui A[k] n locul ultimului element deplasat.


insertion_sort(A,n)
{
for k=2,,n
{
temp = A[k];
i=k-1;
while (i>=1 and A[i] > temp)
{
A[i+1] = A[i];
i=i-1;
}
A[i+1] = temp;
}
}
_______________________________________________________________________________

17

Proiectarea Algoritmilor
_____________________________________________________________________________________

Complexitatea:
Cazul cel mai dafavorabil: situatia n care deplasarea (la dreapta cu o pozitie n vederea nserarii) se face pna la nceputul
vectorului, adica sirul este ordonat descrescator.
Exprimarea timpului de lucru:
T(n) = 3(n - 1) + (1 + 2 + 3+ ... + n - 1) = 3(n-1) + 3n (n - 1)/2
Rezulta complexitatea: T(n) = O(n2) functie polinomiala de gradul II.
Observatie: Cnd avem mai multe bucle imbricate, termenii buclei celei mai interioare dau gradul polinomului egal cu
gradul algoritmului.
Bucla cea mai interioara ne da complexitatea algoritmului.
n

i = O( n2 )
i =1

Shell Sort (sortare prin metoda Shell)


Sortarea se face asupra unor subsecvente care devin din ce in ce mai mari pina la dimensiunea n. Fiecare subsecventa i o
este determinata de un hi numit increment.
Incrementii satisfac conditia : ht > ht-1 > > h2 > h1
Fie hi = h. Avem urmatoarele subsecvente:
A[1], A[1+h], A[1+2h], A[1+kh];
A[2], A[2+h], A[2+2h],
.

A[h], A[h+h], A[1+2h],

Exemplu :
h=4

1
5
7
8
3
12
9
4
12
|____________________________|_____________________________|
|____________________________|
|____________________________|
|____________________________|

h=3

1
5
7
8
3
12
9
4
12
|_____________________|_____________________|
|_____________________|_____________________|
|_____________________|_____________________|

h=1

1
5
7
8
3
12
9
4
12
|_______|_______|_______|_______|_______|______|_______|_______|

Shell_sort (A,n,h,t);
// A[1..n] - seceventa de sortat
// H[1..t] - incrementii ht > ht-1 > >h1=1
18

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
{
for s=t,t-1,,1
{
h=H[s];
for j=h+1,,n
{
x=A[j];
i=j-h;
while (i>0 and x <A[i] )
{
A[i+h]=A[i];
i=i-h;
}
A[i+h]=x;
}
}
}
Complexitatea:
Greu de esitimat. Se presupune (din analiza rezultatelor experimentale) ca ar fi n1,2.

Radix Sort
Se presupune ca cheile de sortare sint numere intregi. Fiecare element din secventa de sortat are k cifre c1c2ck
radix_sort (A,n,k)
// se presupune ca numerele intregi sint reprezentate n baza b<=10
// secventa se afla intr-o coada globala gq iar q[j], j=0,,b-1 sunt cozi;
{
for i=0,,b-1
q[i]=;
for i=k,k-1,,1
{
while ( not isempty(gq) )
{
x=del(gq);
c[i]=cifra i din x;
add (q[c[i]],x);
}
for j=0,,b-1
while ( not isempty(q[j]) ) //adauga coada q[j] la cooda globala gq
add (gq,del(q[j])
}
for i=1,,n;
A[i]=del[gq];
}
Complexitatea:
O(nk)

_______________________________________________________________________________

19

Proiectarea Algoritmilor
_____________________________________________________________________________________

Heap_Sort
Definitie:Se numeste arbore heap un arbore binar T = (V, E) cu urmatoarele proprietati:
(1)
(2)

functia key : V R care asociaza fiecarui nod o cheie.


un nod v V cu degree(v) > 0 (nu este nod terminal), atunci:
key(v) > key(left_child(v)), daca left_child(v)
key(v) > key(right_child(v)), daca right_child(v)

(Pentru fiecare nod din arbore, cheia nodului este mai mare dect cheile descendentilor).
Observatie: De obicei functia cheie reprezinta selectia unui subcmp din cmpul de date memorate n nod.
Generare Heap
Generare Heap prin inserari repetate
heap_gen_1 (A,V, n)
// A[1..n] - seceventa de sortat
// V vectorul ce contine reprezentarea heap-ului;
// N numarul de noduri din heap,
{
N = 1 //se considera pentru nceput un heap cu un singur element,
//dupa care toate celelalte elemente vor fi inserate n acest heap
V[1]=A[1];
for i = 2,,n
insert(V, N, A[i]);
}
insert(V, N, a)
// V vectorul ce contine reprezentarea implicita a heap-ului;
// N numarul de noduri din heap,
// ambele sunt plasate prin referinta (functia insert le poate modifica);
// a atomul de inserat;
// 1) In reprezentarea implicita:
V [N + 1] = a ; N = N + 1
// n continuare se reorganizeaza structura arborelui astfel nct sa-si pastreze structura de heap.
// 2) Se utilizeaza interschimbarile. Comparatii:
//
Se iau 2 indici: child = N si
//
parent = [N/2]
//
Se compar V[child] cu V[parent]
//
Interschimbare daca V[child] nu este mai mic dect V[parent]
// 3) naintare n sus:
child = parent
//
parent = [child/2]
// 4) Se reia pasul 2) pna cnd nu se mai face interschimbarea.
{
N = N+1;
V[N] = a ;
child = N ;
parent = [N/2] ;
while (parent 1)
{
if key(V [child]) > key(V [parent])
{
interchange (V [child],V [parent]);
child = parent;
parent = [child/2];
}
else
break; // se paraseste bucla parent = 0
}
}
20

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
Complexitatea:
Complexitatea operatiei insert:
n cazul cel mai defavorabil se parcurge o ramura care leaga un nod terminal de radacina. Rezulta, complexitatea este data
de adncimea arborelui. Daca N este numarul de noduri din arbore, 2k N < 2k+1 , si adncimea arborelui este k+1.
2k - 1 N < 2k+1 - 1 k = log2N
|
|
|
|
|
|
nr. de noduri
nr. de noduri
ale arborelui
ale arborelui
complet de
complet de
adncime k
adncime k+1
k log2N < k + 1 adncimea arborelui este k+1 = log2N.+1
Deci complexitatea este O(log N).
Complexitatatea algoritmului heap_gen_1
Se fac n-1 operatii insert n heap-uri cu dimensiunea N n
Rezulta complexitatea acestor operatii nu depaseste O(nlog n). Facem un studiu pentru a vedea daca nu cumva ea este mai
mica dect O(nlog n).
Cazul cel mai defavorabil este situatia n care la fiecare inserare se parcurge o ramura completa. De fiecare data inserarea
unui element se face adaugnd un nod la ultimul nivel. Pentru nivelul 2 sunt doua noduri. La inserarea lor se va face cel
mult o retrogradare (comparatie).
nivelul 2 : 2 noduri 1 comparatie
nivelul 3 : 4 noduri 2 comparatii
nivelul 4 : 8 noduri 3 comparatii
-------------------------------------------------nivelul i
: 2i-1 noduri i-1 comparatii
Considernd un arbore complet (nivel complet) n = 2k - 1 numarul total de comparatii pentru toate nodurile este T(n)
de la nivelul 2 la nivelul k. Vom calcula:
k

T (n) = (i 1) 2 i 1
i =2

k 1

Sa aratam:

T ( n) = i 2 i

cu tehnica

T ( n) = 2 T ( n ) T ( n) .

i =1

k 1

k 1

k 1

i =1

i =1

Asadar:
k 1

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

= 1 2 + 2 2 + 3 2 +...+ ( k 2) 2
2

k 1

i =1

k 1

+ ( k 1) 2 k 1 2 1 2 2 2 3 2 3 ... ( k 1) 2 k 1 =
k 1

= 2 + ( k 1) 2 2 = ( k 1) 2 2 + 2 + 2 2 i =
k

i =2

i =0

= ( k 1) 2 + 1 (2 1) = ( k 2) 2 + 2
Rezulta:
T (n) = ( k 2) 2 k + 2 = ( k 2) (2 k 1) + k 2 + 2 = n ( k 2) + k
iar:
k = log 2 (n + 1) ,
din
n = 2k 1
Rezulta:
T (n) = n (log 2 (n + 1) 2) + log 2 (n + 1)
k

-----------------------termen dominant
Facndu-se majorari, rezulta complexitatea O(nlog n) pentru Heap_Gen_1.
_______________________________________________________________________________

21

Proiectarea Algoritmilor
_____________________________________________________________________________________
Generare Heap prin retrogradari repetate
Construim heap-ul de jos n sus (de la dreapta spre stnga). Cele mai multe noduri sunt la baza, doar nodurile din vrf
parcurg drumul cel mai lung.

II
noduri terminale

Presupunem ca elementele V[i+1,n] ndeplinesc conditia de structura a heap-ului:


j >i avem:
V[j] > V[2*j] , daca 2*j n
V[j] > V[2*j +1] , daca 2*j + 1 n
Algoritmul consta n adaugarea elementului V[i] la structura heap-ului. El va fi retrogradat la baza heap-ului (prelucrare
prin retrogradare):
heap_gen_2 (A,V, n)
// A[1..n] - secventa de sortat
// V vectorul ce contine reprezentarea heap-ului;
{
for i = 1,,n
V[i]=A[i];
for i = n/2 ,,1
retrogradare(V,n, i);
}
retrogradare(V, n, i)
{
parent = i ;
child = 2*i ;
// fiu stnga al lui i
while (child n)
{
if ( child+1 n and key(V[child+1]) > key(V[child] )
child = child + 1 ;
if key(V[parent]) < key(V[child])
{
interchange(V[parent], V[child]);
parent = child ;
child = 2*parent ;
}
else break;
}
}
22
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
Complexitatea
Fie un arbore complet cu n = 2k - 1. Cazul cel mai defavorabil este situatia n care la fiecare retrogradare se parcurg toate
nivelele:
nivel k
: nu se fac operatii
nivel k-1: 2k-2 noduri
o operatie de comparatie
nivel k-2: 2k-3 noduri
2 operatii
-----------------------------------------------------------------nivel i
: 2i-1 noduri
k-i operatii
------------------------------------------------------------------nivel 2
: 21 noduri
k-2 operatii
nivel 1
: 20 noduri
k-1 operatii

T ( n) =

Se aduna, si rezulta:

k 1

( k i ) 2i 1
i =1

Tehnica de calcul este aceeasi:


k 2

k 2

i =1

i =1

T ( n) = 2 T ( n) T ( n)

T (n) = ( k i ) 2 i ( k i ) 2 i 1 = ( k 1) 2 1 + ( k 2) 2 2 + ( k 3) 2 3 +...+3 2 k 3 + 2 2 k 2
( k 1) 2 ( k 2) 2 ( k 3) 2 ...2 2
0

k 3

= 22

k 2

k 3

( k 1) + 2 = 2
i =1

=2

k 1

+2

k 2

2 ( k 1) = 2

k 2

(2 + 1) k 1 = 3 2

k 2

k 1

k 3

( k 1) 2 + 2 1 =
0

i =0

k 1

T ( n ) = 3 2 k 2 k 1 3 ( 2 k 1) k 1

Rezulta:

T ( n ) 3 n log2 ( n + 1) 1
------termen dominant

Rezulta complexitatea O(n) pentru heap_gen._2

Algoritmul Heap Sort


heap_sort (A,n)
// A[1..n] - secventa de sortat
{
heap_gen(A, V, n); N = n;
for i = n,n-1,, 2
{
N=i;
A[i] = remove(V, N) ;
}
}
Aceasta procedura sorteaza un vector A cu N elemente: transforma vectorul A ntr-un heap si sorteaza prin extrageri
succesive din acel heap.
partea sortata
heap
i a vectorului

max

min

_______________________________________________________________________________

23

Proiectarea Algoritmilor
_____________________________________________________________________________________
Procedura remove
remove(V, N)
// V vectorul ce contine reprezentarea implicita a heapu-lui;
// N numarul de noduri din heap
// ambele sunt plasate prin referinta (functia remove le poate modifica);
// se scoate elementul cel mai mare care este radacina heap-ului; se initializeaza cei 2 indici;
// se reorganizeaza structura arborilor: se ia ultimul nod de pe nivelul incomplet si-l aduc n nodul
// radacina, si aceasta valoare va fi retrogradata pna cnd structura heap-ului este realizata.
// parent = max(parent, lchild, rchild).
//
Exista trei cazuri:
// 1. conditia este ndeplinita deodata;
// 2. max este n stnga retrogradarea se face n stnga;
// 3. max este n dreapta retrogradarea se face n dreapta.
{
a = V[1];
V[1] = V[N];
N = N-1;
parent = 1;
child = 2;
while (child N)
{
if child+1 N and key(V[child+1]) > key(V[child])
child= child+1;
if key (V[parent]) < key(V[child])
{
interchange(V[parent], V[child]);
parent= child;
child= 2*parent;
}
else break;
}
return(a);
}

Complexitatatea algoritmului heap_sort

Complexitatea algoritmului Heap_Sort este determinata de functiile remove ce nu pot fi aduse la complexitate < O(log n).
Astfel:
Heap_Sort = O(n) + O(nlog n)
--------------termen ce determina complexitatea
Rezulta complexitatea alg. Heap_Sort = O(nlog n)

Merge_Sort i Quick_Sort
Merge_Sort i Quick_Sort sunt doi dintre cei mai importani algoritmi de sortare. Acetia vor fi prezentai ca studii de caz
la metoda de proiectare Divide_et_impera (divide_and_conquer)

24

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

_______________________________________________________________________________

25

Proiectarea Algoritmilor
_____________________________________________________________________________________

Metode generale de proiectare a


algoritmilor

Construirea unui algoritm care rezolv o problem presupune ca etap intermediar construcia modelului matematic
corespunztor problemei. Raiunile definirii modelului matematic snt urmtoarele:
De multe ori problemele snt descrise informal (verbal). In acest fel, unele aspecte ale problemei pot fi omise sau
formulate ambiguu. Construcia modelului matematic evideniaz i elimin aceste lipsuri;
Instrumentele matematice de investigare n perspectiva identificrii i definirii soluiei, snt mult mai puternice;
Definirea soluiei n termenii modelului matematic uureaz foarte mult activitatea de construire a algoritmului.

O metod de proiectare a algoritmilor se bazeaz pe un anumit tip de model matematic i pune la dispoziie procedeee
prin care se poate construi i implementa un model particular corespunztor unei probleme. Definirea unui model
matematic cuprinde urmtoarele trei aspecte:
1. conceptual: presupune identificarea i conceptualizarea componentelor din domeniul problemei;
2. analitic: implic descoperirea tuturor relaiilor ntre conceptele care conduc la identificarea i descrierea soluiei
3. computaional: se refer la evaluarea calitativ a algoritmului ce construiete soluia.
Cele mai cunoscute metode de proiectare a algoritmilor snt urmtoarele: divide-and-conquer, greedy, programarea
dinamic, backtracking, branch-and-bound.

26

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

_______________________________________________________________________________

27

Proiectarea Algoritmilor
_____________________________________________________________________________________

Metoda Divide-and-Conquer (divide-etimpera)

Descrierea metodei
Prin aceast metod, o problem dat P este divizat recursiv ntr-un numr de subprobleme independente. Solutia
unei probleme situate pe un anumit nivel al recursiei, se compune din soluiile subproblemelor sale. Divizarea unei
probleme se face pn cnd se obin subprobleme de dimensiuni mici ce pot fi rezolvate prin meteode elementare.

Modelul metodei
Metoda poate fi descris astfel:
D_and_C (P(n));
{
if ( n<=n0)
rezolv subproblema P(n) prin metode elementare;
else
{
// divizarea problemei
mparte problema P(n) n subproblemele P1(n1),,Pa(na);
// Rezolvarea subproblemelor
rezolv recursiv subproblemele P1(n1),,Pa(na) obindu-se soluiile S1,,Sa;
// Asamblarea soluiilor
combina soluiile S1,,Sa pentru a obine soluia S a problemei P(n);
}
}

Deoarece metoda are un caracter recursiv, aplicarea ei trebuie precedat de o generalizare de tipul problem
subproblem prin care dimensiunea problemei devine o variabila liber.

Eficiena metodei
Vom presupune n continuare c dimensiunea problemei Pi este ni i satisface ni n/b , b >1. De asemenea vom
presupune c divizarea problemei n subprobleme i asamblarea soluiilor necesit timpul O(nk). Complexiatea timp T(n) a
algoritmului D_and_C este dat de urmtoarea relatie de recuren:
28

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

daca n n0
O( 1 ),

T(n) =
n
k
a T( b ) + O(n ) , daca n > n0
Teorema 1: Dac n >n0 atunci :

O(n logb a )

T (n) = O(n k log b n)

k
O(n )

, daca a > b k
, daca a = b k
, daca a < b k

Demontraie:
Fr a restrnge generalitatea se poate presupune n=bm n0 . De asemenea se mai poate presupune c T(n) = c n0k dac
n n0 i T(n ) = a T(n/b) + c nk dac n>n0 . Pentru n>n0 rezult:

n
k
= aT + cn
b

T ( n)

= aT (b

m 1

n0 ) + cn

k
k

m 2

= a ( aT (b
2

= a T (b
=

m 2

n
k
n 0 ) + c ) + cn
b

n k

k
n 0 ) + c a + n
b

= a T ( n 0 ) + c a
m

= a cn0 + c a
=

k m
cn 0 a

m 1

m 1 k

k
k

n
n
m1 +  + a + n k
b
b

b n0 +

bk
1 +
a

+a b

m 1 k

( )

n0 + b

m k

n0

m
bk
 +
a

bk
k
= ca unde cn 0 a fost renotat prin c.
i = 0 a
m

Se disting cazurile:
j

bk
k

1. a > b . Seria
este convergent i deci irul sumelor pariale este convergent. De aici rezult T(n) =
i = 0 a
m

O( a ) = O ( a
2.

logb n
m

) = O(n

a = b . Rezult a = b

km

logb a
k

)
k

= cn i de aici T(n) = O ( n m) = O ( n log b n)

_______________________________________________________________________________

29

Proiectarea Algoritmilor
_____________________________________________________________________________________
m

bk
km
k
3. a < b . Avem T(n)= O ( a ) = O (b ) = O ( n )
a
m

QED.

Dac pentru fiecare nivel r al recursiei, subproblemele Pi(r), i=1,...,q(r), ale acestui nivel satisfac conditia c d(Pi(r))
(1/b) d(PT(Pi(r))) unde d(Pi) reprezint dimensiunea subproblemei Pi, PT problema tat iar b este o constant pozitiv
supraunitar atunci adncimea recursiei este logaritmic.
Relativ la arborele de calcul, divide-and-conquer realizeaz parcurgerea acestuia n stil top-down si apoi
bottom-up . Aceasta se datoreaz recursiei.

Modelul metodei pentru cazul arborelui binar de recursie:


q(r +1) = 2 q(r),d( Pi (r)) =

d(PT( Pi(r))
2

d_and_c_binar (P(n));
{
if ( n=1) return (P(1));
else
{
d_and_c_binar (P(n/2));
d_and_c_binar (P(n/2));
combine(P(n/2),P(n/2));
}
}

Avem:
q(r ) =2q(r-1)= 2(2q(r-2))=22q(r-2)==2r q(r-r)=2rq(0)=2r ,

d(PT( Pi(r)))
d( Pi(r)) =
2

i = 2r

i =2r

d( P i (r)) =

i =1

i =1

d(PT( Pi(r)))
=
2

i = 2r

i =1

2 1

d(PT(PT( Pi(r)))
=
2

i = 2r

i =2

i = 2r

i =1

i =1

i =1

= 2 2d(PT(PT( Pi(r))) = 2 r d(PT(...(PT(d( Pi(r))...)= 2 r n = 2r 2 r n = d(P)=n

Deci pe oricare nivel al recursiei suma dimensiunilor subproblemelor corespunztoare acestui nivel este n.

Studii de caz
Sortarea prin prin interclasare
Pentru a sorta o secventa de n elemente ale unui vector A, se mparte vectorul n 2 segmente de lungime n/2 care sint
sortate separat recursiv, dupa care urmeaza interclasarea.
30

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Pseudocod: Procedura MERGE_SORT primeste ca argumente A - vectorul de sortat, si doi indici care delimiteaza o
portiune din acest vector. Apelul initial va fi MERGE_SORT(A, 1, n).
MERGE_SORT(A, low, high)
{
if (low high) return;
else
{
low + high
mid =
;
2

MERGE_SORT(A, low, mid) ;


MERGE_SORT(A, mid+1, high) ;
MERGE(A, low, mid, high) ;
}

//partea ntreaga
//sortare separata
//sortare separata
//interclasare

Procedura MERGE interclaseaza secventele sortate A[lowmid] si A[mid+1high]. Pentru aceasta este nevoie de un
vector auxiliar B, de aceeasi dimensiune cu A.
MERGE(A, low, mid, high)
{
i = low; j = mid+1; k = low;
while( i mid and j high)
{
if (A[i] < A [j]) {B[k] =A[i]; i=i+1;}
I
else { B[k] = A[j]; j=j+1;}
k=k+1;
}
while (i mid)
{
II
B[k] = A[i]; i=i+1;
k=k+1;;
}
while (j high))
}
III B[k] = A[j]; j=j+1;;
k=k+1;;
}
for k = low,, high
A[k] = B[k];
}
Corectitudinea :
Lema 1: Procedura MERGE_SORT sorteaz cresctor elementele vectorului A.
Demonstratie: Este suficient sa demonstram corectitudinea procedurii MERGE. Presupunem prin reducere la absurd
c n urma executiei procedurii MERGE exista un indice k pentru care B[k]>B[k+1].
Aceasta ar putea rezulta din urmatorele situatii:

1. B[k] fost initializat in bucla I iar B[k+1] in bucla II


2. B[k] a fost initializat in bucla I iar B[k+1] in bucla III
Cazul 1. Aceasta inseamna ca imediat dupa initializarea elementului B[k] situatia indicilor i si j este urmtoarea : i
mid si j > high. Deci A[i] >= A[high], B[k] = A[high] si B[k+1] = A[i]. Din B[k] > B[k+1] rezulta ca A[high] >A[i]
>= A[high]. Absurd.
Cazul 2. Aceasta inseamna ca imediat dupa initializarea elementului B[k] situatia indicilor i si j este urmtoarea : j
high si i > mid. Deci A[mid] < A[j], B[k] = A[mid] si B[k+1] = A[j]. Din B[k] > B[k+1] rezulta ca A[mid] >A[j] >
A[mid]. Absurd.

_______________________________________________________________________________

31

Proiectarea Algoritmilor
_____________________________________________________________________________________
Complexitatea :
Lema 2.Timpul de executie al algoritmului MERGE_SORT este:

n =1

0,

T ( n) =

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

Demonstratie: Consideram: n = 2k;


Evident procedura MERGE este de de complexitate O(n) .

T(n) = 2T(n/2) + n = 2(2T(n/4) + n/2) + n = ... = 22T(n/22) + 2n= 22 (2T(n/23) + n/22) + 2n =


3
= 2 T(n/23) + 3n = ... = 2kT(n/2k) + kn T(n) = kn = nlog2n , pentru ca n = 2k , si, deci, k=log2n
Asadar complexitatea algoritmului este O(nlog n).

Sortarea rapida (C.A.R. Hoare)


Pentru a sorta o secvent de n elemente ale unui vector A, se partitioneaz vectorul n 2 segmente dup schema
urmtoare utiliznd un element cu statut special numit pivot.

elemente

pivot

A[k]=pivot elemente

pivot

Urmeaz apoi sortarea recursiv a secventelor separate de pivot.


Quik_Sort(A, low, high)
{
if(high >low)
{
k= Partition(A, low, high) ;
// partitionare
Quick_Sort (A, low, k-1) ;
Quick_Sort(A, k+1, high) ;
}
}

// procedura de

Pseudocodul pentru functia partition:


Partition(A, low, high)
{
l= low; h= high;
x= A[l];
while (l < h)
{
I
while (A[l] x and l high) l=l+1;
II
while (A[h] > x and h low) h=h-1-;
if (l <h) interchange (A[l], A[h]) ;
}
interchange (A[h], A[low])
return(h);
}
Procedura Partition considera pivotul ca fiind: A[low]. Indicele l parcurge vectorul de la stnga la dreapta, iar indicele
h parcurge vectorul de la dreapta la stnga. Ei se apropie pna se ntlnesc (l=h). Deci, l lasa n urma numai elemente A[i]
pivot, iar h lasa n urma numai elemente A[i] > pivot.
32

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

aici.

Ciclul I while nseamna ca nainteaza l ct timp A[l] pivot. Acest ciclu se opreste pe conditia A[l] > pivot, fixndu-se

Ciclul II while nsemna ca nainteaza h ct timp A[h] > pivot. Acest ciclu se opreste pe conditia A[h] pivot, fixnduse aici.
Cele doua pozitii se schimba, astfel nct sa se permita naintarea indicilor mai departe.

low

Corectitudinea:
Lema3: Procedura Quick_Sort sorteaz cresctor elementele vectorului A.
Demonstratie: Inductie dupa n.
Pasul 1. Pentru un tablou unidimensional A de dimensiune 2 evident algoritmul functioneza corect.
Pasul 2. Presupenem ca procedura Quick_Sort functioenaza corect pentru tablori unidimensionale A de dimensiuni n
si demostram ca functioneaza corect si pentru A de dimensiune n+1:
Prodedura Partition separa vectorul A in dou segmente S1 cu elemente pivot si S2 cu elemente > pivot.
Procedura Quick_Sort aplicata asupra vectorilor S1 si S2 functioneza conform ipotezei de inductie.
Rezulta in final A = S1 { pivot } S2 . Datorita propriettilor pivotului si a vectorilor S1 si S2 vectorul rezultat A
este sortat crescator.
Complexitatea:
Lema 4. Timpul de executie al algoritmului Quick_Sort este: T ( n) = n( n 1) / 2
Demonstratie:
Cercetam cazul cel mai defavorabil. Fie cazul n care vectorul este ordonat descrescator. Pivotul gasit, la primul pas,
este elementul maxim din vector, rezulta ca trebuie plasat n ultima pozitie. Pivotul va fi maximul dintre elementele
secventei, deci, va fi plasat n ultima pozitie din secventa.
Problema se mparte n 2 subprobleme: P(n) P(n-1) , P(0).
Numarul de comparatii pentru functia Partition este (n-1). Vectorul se parcurge n doua directii, dar o singura data.
Rezulta ca timpul de functionare al algoritmului Quick_Sort este: T ( n ) = ( n 1) + T ( n 1)
Rezolvnd aceasta ecuatie, avem:

T ( n ) = n 1 + T ( n 1) = n 1 + n 2 + T ( n 2 ) =... = n 1 + n 2 + n 3+... +1 + T (1)

unde: T(1) este 0 (nu se partitioneaza). Rezulta:

T ( n) =

n 1

i = n(n 1) / 2
i =1

Aceasta suma este de complexitate O(n2). Rezulta ca este un algoritm ineficient.


Spatiul ocupat de algoritmul Quick-Sort

Quick_Sort(A, low, high)


{
if (low < high)
{
k = Partition(A, low, high) ;
Quick_Sort(A, low, k-1) ;
Quick_Sort(A, k+1, high) ;
}
}

low

high

Avem n acest algoritm doua apeluri recursive.


_______________________________________________________________________________

33

Proiectarea Algoritmilor
_____________________________________________________________________________________

Cazul cel mai defavorabil:

k
high

low

Consideram consumul de memorie n stiva : M(n) = c + M (n - 1) M(n) = O(n) un ordin de complexitate mare.
Pentru reducerea consumului de memorie, se concepe un alt algoritm la Quick_Sort, astfel nct un apel sa fie rezolvat
recursiv, iar celalalt apel iterativ.

k
secventa mica rezolvata recursiv

secventa mare rezolvata iterativ

Quick_Sort(A, low, high)


{
while (low < high)
{
k = Partition(A, low, high);
if( k-low > high-k)
{
Quick_Sort(A, k+1, high);
high = k-1;
}
else
{
Quick_Sort(A, low, k-1);
low = k+1;
}
}

Necesarul de memorie pentru aceasta este M(n) c + M(n/2), nsemnnd ca oricare ar fi secventa mai mica, ea este
dect jumatatea secventei din care a fost obtinut M(n) = O(log n) am redus ordinul de complexitate.

34

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

_______________________________________________________________________________

35

Proiectarea Algoritmilor
_____________________________________________________________________________________

Metoda Greedy

Descrierea metodei
Metoda Greedy este o metod general de proiectare a algoritmilor care const n construirea solutiei globale
optimale printr-un sir de solutii cu caracter de optim local atunci cnd este posibil exprimarea optimului global ca o
combinatie de o optime locale.
Schema de proiectare: Problema se prezint sub forma unei multimi S cu n componente. O parte din submultimile
lui S reprezint solutii care satisfac un anume criteriu si se numesc solutii admisibile. In spatiul solutiilor admisibile
prezint interes o solutie care maximizeaz/minimizeaz o functie obiectiv. Soluiile admisibile au proprietatea c odat cu
o soluie admisibil toate submulimile sale snt de asemenea admisibile. Metoda Greedy sugereaz un algoritm de
construcie a soluiei optimale pas cu pas pornind de la mulimea vid. La fiecare pas se selecteaz un element nou care va fi
nghiit n soluie (greedy) n baza unei proceduri de selecie. De exemplu la problemele de optimizare procedura de
selecie alege acel element care face s creasc cel mai mult valoarea funciei obiectiv. Desigur nu n toate problemele,
aceast strategie conduce la soluia optim, metoda Greedy nefiind o metod universal.

Modelul metodei
Fie S o multime finit de intrri i C o colecie de submulimi ale lui S. Spuneme c C este admisibil dac satisface
axioma de admisibilitate:

X C: X ( xX: X \ (x) C)
Dac C este admisibil atunci perechea (S,C) se numte sistem admisibil. O submulime XC se numete baz dac
este maximal ( nu exist xS \ X astefel nct X {x} C. Clasa de probleme pentru care se pot defini algoritmi greedy
este definit de urmtoarea schem:
Se consider date un sistem admisibil (S,C) i o funcie obiectiv f:CR.
Se cere determinarea determinarea unei baze B C. care satisface:

f(B) = optim { f(X) | X baz In C }

n general prin optim se va nelege minim sau maxim. Strategia greedy (lacom) const n gsirea unui criteriu
de selecie a elementelor din S care candideaz la formarea bazei optime, numit criteriu de selecie greedy sau criteriu de
selecie locala sau optim local.
Schema strategiei greedy este urmtoarea:

36

// Iniial
S1 = S;
B = ;
repeat
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
// pasul de selecie greedy
alege x din S1 conform unui criteriu de optim local ;
S1 = S1 - {x} ;
dac B {x} este n C atunci B = B {x};
// Condiia de terminare
until (nu se mai pot aduga elemente din S1 la B)
Obs. n studiile teoretice, optimul local are o definiie exact:

f(B {x}) = optim { f(B {y}) | y S1}

n practica construirii de algorimi greedy, este recomandabil s fie lasat liber definiia optimului local. Exist
totui restricia ca definiia acestuia s nu depind de alegerile ulterioare sau de soluiile subproblemelor. n schimb poate
depinde de seleciile fcute la acel moment. n acest fel se obine o flexibilitate mai mare n proiectarea de algoritmi greedy
dar de fiecare dat trebuie demonstrat c selecia conform optimului local conduce la o baz pentru care se obine optimul
global pentru funcia obiectiv.
Din pcate numai condiiile de optim local i admisibilitate nu asigur existena unui crieriu de selecie local care s
conduc la determinarea unei baze optime. Aceasta nseamn c pentru anumite probleme algoritmii greedy nu construiesc
o soluie optima ci numai o baz pentru care funcia obiectiv poate avea valori apropiate de cea optim. Acesta este cazul
unor probleme NP-complete.

Eficiena metodei
Se presupune c pasul de alegere greedy selectioneaz elemente x n O(kp) timp unde k = #S1 iar testarea condiiei B {x}
C necesit O(lq) timp, l = #B, k + l n . De asemenea se presupune ca operaiile B {x} i S - {x} necesit O(1) timp.
Rezult:
T(n)= O(np +1q) + + O(1p + nq ) = O(1p ++ np + 1q + + nq)= O(np+1 + nq+1 ) = O(nmax(p+1, q+1))

Studii de caz
Interclasare optimala
Definirea problemei: Avem secventele X1,X2,.....Xn
fiecare sortate.Sa se gaseasca o strategie de interclasare dou cte
dou astfel nct numrul de operatii sa fie minim.
Exemplu:
Fie urmatoarele secvente X1, X2, X3 unde

X1
are
30 elem.
are
20 elem.
X2
are
10 elem.
X3
Se aplic citeva variante de organizare a interclasrii
1.

Y=merge(X1,X2)
Z=merge(Y,X3)

50 operatii
60 operatii
---------------

Y-50 elem.

_______________________________________________________________________________

37

Proiectarea Algoritmilor
_____________________________________________________________________________________

110 operatii
2. Y=merge(X2,X3)
Z=merge(Y,X1)

30 operatii
60 operatii
--------------90 operatii

Y-30 elem.

Solutia: Problema se rezolv aplicind o tehnic Greedy la fiecare pas cind se interclaseaza cele mai mici 2 secvente.
Problema se poate reprezenta ca un arbore binar.

95

Exemplu

y4

y2 35
y1 15
5
x4

60
x1

20

30

x5

y3
30

x2

10
x3

X3,X4 -> Y1 -15 elem.


X1,Y1 -> Y2 -35 elem.
X2,X5 -> Y3 -60 elem
Y3,Y2 -> Y4 -95 elem.
205 elem.
Nodul x4 este la distanta 3 de nodul y4, deci valoarea din x4 se va aduna de 3 ori.
Daca notam di distanta de la radacina la nodul frunza xi si cu qi valoarea nodului, atunci
di = level ( qi ) - 1
n

q d
i

i =1

= nr. total operatii

5*3 + 10*3 + 20*2 + 30*2 + 30*2 = 15 + 30 +40 + 60 + 60 = 205


n

S=

q d
i =1

se numeste lungimea drumurilor externe ponderate ale arborelui

O interclasare optimal corespunde construirii unui arbore binar optimal relativ la S.


Algoritm pentru construirea unui arbore binar optimal

tree ( L,n )
{

38

// L- o list de arbori. Initial contine arbori de forma (val, 0, 0 ) - noduri terminale


// foloseste: get_node() -- crearea unui nod
// least(L)
-- sterge din lista arborele cu valoarea din rdcin minim
// insert(L,t) -- insereaz in list un arbore
for i=1,,n-1
{
t = get_node()
lchild(t) = least(L)
rchild(t) = least(L)
data(t) = data(lchild(t)) + data(rchild(t))
insert(L,t)
}
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

return (least(L))
}
Teorema 1 Fie algoritmul tree si L continnd initial n arbori cu cte un singur nod de valori ( q1, q2, ... qn ). Atunci tree
n

genereaz un arbore binar cu S =

d q
i

minim ( di distanta de la rdcin la nodul qi )

i =1

Demonstratie . Demonstratia se face prin inductie dup n

1. n = 1 evident , arbore minimal


2. P(n-1) : Pentru orice secvent initial de valori nod ( q1, q2, ... qm ), 1mn-1 tree genereaz un arbore Tam optimal
Presupunem P(n-1) adevrat.
P(n) : Pentru orice secvent initial de valori nod ( q1, q2, ... qn ), tree genereaz un arbore Tan
Demonstrm P(n) adevrat.

optimal

Lema 1 : Fie qi si qj cele mai mici dou valori ale secventei (nodurile care vor fi returnate n prima iteratie a buclei for de
functia least ). Fie T un arbore optimal ( nu neaprat cel construit de tree). Fie P nodul interior cel mai ndeprtat de
rdcin si presupunem c descendentii lui P au valorile qk, ql diferite de qi, q :
(qi qk) si / sau (qj ql) se pot interschimba n arbore T, obtinndu-se un arbore T care ramne optimal.
Demonstratie:

Fie

di
dj
dk
dl

distanta de la nodul de valoare qi la rdcin


distanta de la nodul de valoare qj la rdcin
distanta de la nodul de valoare qk la rdcin
distanta de la nodul de valoare ql la rdcin

qi
qj
qk

S(T) =

q d
r =1

ql

+ qi d i + q k d k

r i ,k

Dupa interschimbarea valorilor qi, qk se obtine :


n

S(T') =

q d
r =1

+ q k d i + qi d k

r i ,k

_______________________________________________________________________________

39

Proiectarea Algoritmilor
_____________________________________________________________________________________

Avem D = S(T') - S(T) = qi(dk-di) - qk(dk-di) = (dk-di) (qi-qk)


= -(dk-di) (qk-qi)
Dar dk di pentru ca P-ul e mai ndeprtat
S(T')-S(T) 0 S(T') S(T)
qk qi pentru ca qi , qj minime
T minimal

S(T) = S(T) .
Analog se procedeaz pentru perechea (qj,ql). Se obtine T pentru care S(T)=S(T).
Revenim la demonstratia P(n) adevrat:
Din Lema anterioara rezult c T este optimal pentru secventa de valori nod ( q1, q2, ... qn ) si contine nodul P care are n
descendenti valorile qi , qj cele mai mici.
nlocuim subarborele P cu un nod care are valoarea qi+qj .Noul arbore T fiind un subarbore al arborelui T este optimal
pentru secventa de valori nord (q1 ... qi-1 qi+qj qi+1 ... qj-1 qj+1 ... qn) deci S(T) = q1d1++qi-1dI-1+ (qi+qj)di+j+
qi+1di+1++ qj-1dj-1+ qj+1dj+1++ qndn minim
S(T) - S(T) = (qidi+ qjdj ) - (qi+qj)di+j= qi(di-di+j) + qj(dj-di+j)=qi+qj.

Rezult S(T) = S(T) + qi+qj


Nodul P este construit de tree n prima iteratie, dup care n iteratia urmtoare se intr n secventa de valori nod (q1 ... qi-1
qi+qj qi+1 ... qj-1 qj+1 ... qn)
Conform ipotezei inductive algoritmul construieste un arbore optimal Tan-1 pentru secventa de valori nord (q1 ... qi-1 qi+qj
qi+1 ... qj-1 qj+1 ... qn) deci S(Tan-1) minima. Rezult S(Tan-1) = S(T)
Din modul de constructie a lui Tan-1 si Tan avem S(Tan)-S(Tan-1)=(qidi+ qjdj ) - (qi+qj)di+j= qi(di-di+j) + qj(dj-di+j)=qi+qj .
Rezult in final S(Tan) = S(Tan-1)+ qi+qr = S(T) + qi+qj = S(T) deci Tan este optimal.

Complexitatea : Bucla for se execut de n ori .

Functiile least() si insert():


L - list nlntuit:
least() - O(n)
insert() - O(1)
L - list nlntuit ordonat:
least() - O(1)
insert() - O(n)
L - heap:
least() - O(logn)
insert() - O(logn)

tree O(n2)
tree O(nlogn)

Obs. Metoda functioneaz si pentru arbori k-ari ( fiecare nod cu k descendenti )

Compresiile de date. Arbori Huffman


Definirea problemei:
Fie D = ( D1, D2, ... , Dn ) un grup de date, fiecare de lungime l si M un mesaj compus din aceste
date . Exemplu: Di octeti de date si M un fisier ). Se cunoaste c Di apare n M de qi ori i = 1, n. S se construiasc un sistem
de coduri binare pentru elementele lui D a. M s fie de lungime minim.
Solutia: Se codific fiecare dat Di , i = 1, n cu un numr variabil de biti pe baza unui arbore binar cu arcele etichetate
astfel:

40

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

0 - pentru arcele de forma ( p, left(p))


1 - pentru arcele de forma ( p, right(p))
Arborele are n noduri terminale cte unul asociat fiecrei date Di. Codul asociat datei Di va fi secventa de biti de biti (0,1)
care apar ca etichete pe drumul de la rdcin la Di.
Exemplu: D = ( D1, D2, ... , Dn ) = ( rosu, alb, verde, crem, bleu, galben, negru, maro)
r
a
v
c
b
g
n
m

coduri(D) = ( 000, 001, ... , 111 )

0
0

1
1

1 0

ins, de asemenea, poate fi si coduri(D) = ( 00, 01, 100, 101, 1100, 1101, 11110, 11111)
0

a 0

0
0

1
1

Obs. Pentru a codifica n obiecte sunt necesare log2n biti


Decodarea: 1. Codurile sunt de aceeasi lungime . Este suficient o tabel de indirectare.
2. Codurile sunt de lungime variabil. Se foloseste arborele de codare . Aceasta se bazeaz pe faptul c se
obtine un sistem de coduri care sunt "prefix distinctibile", adic i, j cod(Di) nu este prefix al secventei
cod(Dj).

Exemplu:

M = 01 1111 00 00 01 01 01 101 1110 1100 00 100 1101 1101


a
m r r a a a c
n
b r v
g
g

Lungime mesaj:
M=amrraaacnbrvgg
n prima codare: l(M) = 14*3 = 42 biti
n a doua codare: l(M) = 40 biti
_______________________________________________________________________________

41

Proiectarea Algoritmilor
_____________________________________________________________________________________
Obs. Problema determinrii unei codri care s minimizeze lungimea lui M se reduce la determinarea unui arbore binar cu
lungimea drumurilor externe ponderate minime

Fie M = Di1 Di2 ... Dik compus din datele (D1, D2, ...Dn) cu frecventele de aparitii
aparitii n M ale datelor Di, atunci
n

l(M) =

Q = (q1, q2, ...,qn) , qi = nr. de

q lungime(cod ( D )) = q dist ( D )
i

i =1

i =1

dist(Di) - distanta de la rdcin la Di


Pentru exemplul anterior:
M=amrraaacnbrvgg,
D = ( b, m, v, n, c, g, r, a )
Q = ( 1, 1, 1, 1, 1, 2, 3, 4 )
Rezult M de forma:
M = 00 0101 11 11 00 00 00 100 0111 0100 11 0110 101 101 -- 39 biti
a m r r a a a c
n
b r v
g g
cu desenul din figura urmtoare:
14
0

0
4
a

1
0

1
2

2
0
1
b

0
4

1 0
1
1
m v

0
1
c

1
3 3
r
1
2
g

1
1
n

Obs. - Metoda este eficient atunci cnd frecventa aparitiilor este cunoscut exact, si nu estimat;
- Ambele procese codor, decodor trebuie s cunoasc arborele;
- Pstrarea codificrii lui M mpreun cu arborele de decodificare ridic probleme de ineficienta ocuprii spatiului;
- Pentru texte se foloseste un arbore cu qi estimate statistic;
- Exemplu pentru un CD-ROM cu crti nmagazinate - se poate pstra un album 38 frunze ( alfabetul latin , plus
semnele de punctuatie );

Drum minim ntr-un graf ( surs - destinatie )


Definirea problemei : Se d G = ( V, E ) un graf, e: E
k 1

unde dist(s,d) =

e( v , v
i =1

42

i +1

R+ functia de etichetare. Se cere un drum (s = v1v2...vk = d),

) minimal.

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
Obs. : Exist un algoritm care da toate aceste drumuri ( cu nmultire de matrici , de cost O(n3)).

Algoritmul Greedy pentru determinarea drumurilor minime de la nodul i la toate celelalte noduri :
short_path( G, C, s, n )
{
// G = ( V, E ) , V = {1,2,...,n}

e(i , j ), (i , j ) E
+, altfel

// C - matrice de cost C[i,j] =

// folosim vectorii dist[1..n] si pred[1..n]


// S - multimea nodurilor atinse

S = {s}
for i=1,,n
{
dist[i] = C[s,i]
pred[i] = s
}
for k=2,,n-1
{
fie u a.. dist[u] = min{dist[w]}
//
x V\S
S = S {u}
for all v V\S
{
if ( dist[v] > dist[u] + C[u,v] )
{
dist[v] = dist[u] + C[u,v]
pred[v] = u
}
}
}
return (dist, pred)
}

Teorema 2 . Algoritmul obtine drumurile minime de la s la orice nod v V.


Complexitatea: O(n2).

Problema rucsacului (Knapsack)


Definrea problemei: Datele problemei sunt:

obiectele:
greuttile:
profiturile:
capacitatea:

i1
w1
p1
M

i2
w2
p2

...
...
...

in
wn
pn

_______________________________________________________________________________

43

Proiectarea Algoritmilor
_____________________________________________________________________________________

Se cere o alegere X = ( x1 , x2 , ... , xn ) , 0 xi 1, astfel nct

x w
i

M (*) si

x p
i

- maxim (**)

o solutie admisibil satisface (*).

o solutie optim este admisibil si satisface (**)

Obs. 1. Daca

w
i

M solutia optimala este xi=1, i=1,,n. Deci problema are sens pentru wi > M i astfel

condiia de admisibilitate a unei soluii devine

x w
i

=M .

Un algoritm relativ performant se obtine pornind de la sortarea obiectelor n ordinea descresctoare a valorilor pi/wi.
greedy_knapsack (P,W,M,n)
// P(1..n) - profiturile
// W(1..n) - greuttile
// M - capacitatea rucsacului
// X(1..n) vectorul solutie
// obiectele snt ordonate astfel nct P(i)/W(i) P(i+1)/W(i+1)
{
for i=1,,n X(i) = 0; i=1;
C = M; // C = capacitatea rmas
while (C > W(i) and i n)
{
C=C - W(i);
X(i) = 1;
i=i+1;
}
if (in) X(i) = C/W(i);
return (X)
}
Teorema 3. Solutia generat de GREEDY_KNAPSACK este optimal.
Demonstratie: Fie X=(x1,x2,,xn) solutia generat de algoritm. Din modul de constructie rezult
n

w x = M.
i =1

Dac X=(1,1,.,1) rezult X optimal.


j

w x =M
Presupunem c X nu este optimal. Fie Y=(y ,y ,,y ) o solutie admisibil astfel ncit p y > p x
Daca X (1,1,.,1) fie j indicele pentru care xi=1, 1i<j ; 0xj<1; xi=0 , j<in . Rezulta

i =1

Putem presupune c

w y
i =1

= M.

(***) Fie k cel mai mic indice pentru care xk yk. Demonstrm yk<xk .
Exista urmtoarele posibilitti:
1. k<j : Atunci xk=1. Dar yk xk deci yk<1. Rezult yk<xk.
2. k=j

44

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
n

j 1

i =1

i =1

wi y i = M = wi y i + w j y j +
M wj x j + wj y j +

j 1

i = j +1

i =1

wi y i = wi x i + w j y j +

wi y i = M + w j ( y j x j ) +

i = j +1

Dac yj>xj atunci M=

wi y i = M + w j ( y j x j ) +
i =1

3.

w y

i = j +1

w y

i = j +1

w y
i

i = j +1

>M. Imposibil. Deci yj<xj adic yk<xk.

k>j

k 1

k 1

i =1

i =1

i=k

i =1

i=k

i =1

wi yi = wi yi + wi yi = wi xi + wi yi = wi xi +

k 1

i = j +1

i=k

wi xi + wi yi =

= M + 0 + wi y i > M
i=k

Imposibil.
n

w y

Crestem acum yk pn la xk si descrestem yk+1, yk+2, ., yn att ct este necesar astfel nct

i =1

(capacitatea total rmne M). Se obtine o solutie Z=(z1,z2,,zn) cu zi=xi , i=1,,k si

w (y
i

i = k +1

=M
zi ) = w k ( z k y k )

Suma ponderilor descresterilor yk+1, yk+2, ., yn este egala cu ponderea cresterii lui yk ).
Pentru Z avem :
n

pz
i =1

i i

p y
i =1

p y
i =1

=
+ (z k y k ) pk +

(z

i = k +1

+ [( z k y k ) w k

y i ) pi = pi y i + ( z k y k ) w k p k / w k

i =1

(y

i = k +1

i =1

i =1

(y

i = k +1

z i ) wi p i / wi

z i ) wi ] p k / w k = p i y i > p i x i

n relatia anterioara au fost utilizate inegalittile pi/wi pi+1/wi+1 , i=1n-1.


Dac Z=X rezulta o inegalitate imposibil :

p x > p x
i

. Deci presupunerea inital X nu este optimal este fals.

Dac Z X atunci repetm (***) cu Z in locul lui Y si continum procesul pna cnd obtinem Z = X adica ipoteza X nu este
optimal fals.
Complexitatea: O(n)

_______________________________________________________________________________

45

Proiectarea Algoritmilor
_____________________________________________________________________________________

Programarea dinamic.

Descrierea metodei
Se aplic atunci cnd solutia unei probleme poate fi privit ca rezultat al unei secvente de decizii.
Exemple:
a) Problema rucsacului

-- decizia 1 - xi1 ponderea obiectului i1


-- decizia 2 - xi2 ponderea obiectului i2
b) Interclasarea optimal
-- decizia 1 - prima pereche
-- decizia 2 - a doua pereche
c) Drumuri minime de la i la celelalte noduri
-- decizia 1 - n S se adaug i
-- decizia 2 - n S se adaug nodul de distant minim
Nu toate problemele permit ca la fiecare pas s se determine decizia care conduce la solutia optimal.
Ex. drum minim de la i la j
initial : P = {i}
decizia 1 : care din vecinii lui i vor fi pe drumul minim ?
O solutie este a se ncerca toate variantele posibile de decizie.
*
Programarea dinamic reduce numrul de ncercri eliminnd o serie de secvente care nu pot fi optimale si aceasta apelnd
la principiul optimalittii:
" O secvent optimal de decizii are proprietatea ca pornind de la o stare initial si considernd prima decizie d1 ,
secventa de decizii rmase d2, ..., dn trebuie s fie optimal relativ la starea rezultat din prima decizie."
Problemele care ndeplinesc acest principiu sunt susceptibile de a fi rezolvate prin programare dinamic.
Exemple :
Drum minim de la i la j , dou noduri ntr-un graf.
Drumul minim de la i la j este de forma ( i, i1, i2, ..., im, j ). Presupunem c s-a luat decizia c i1 este primul nod dup i n
solutia optimal. Secventa ( i1, i2, ..., im, j ) trebuie s fie drum minim de la i1 la j , altfel, dac (i1, r1, r2, ..., rl, j) este drumul
minim de la i1 la j atunci (i, i1, r1, r2, ..., rl, j ) este drumul minim de la i la j si nu ( i, i1, i2, ..., im, j ).
Problema rucsacului [0,1]
Problema rucsacului 0/1 se enunt n mod identic cu problema general a rucsacului cu observatia c obiectele snt
indivizibile adic apare restrictia suplimentar asupra ponderilor xi care trebuie s fie 0 sau 1.
Formularea problemei:
se cunosc obiectele:
i1 , i2 , ....in
obiectele au greuttile:
w1 , w2 , ....wn
obiectele au valorile (profiturile)
p1 , p2 , ....pn
se consider o capacitate M.
O alegere de obiecte este un vector X=( x1 , x2 , ....xn) unde xi=1 semnific faptul c obiectul i a fost ales iar
xi=0 semnific faptul c respectivul obiect nu a fost ales.
Problema const n determinarea acelei alegeri care nu depaseste capacitatea dar care maximizeaz profitul, adic:
n

x i pi -maxim iar
i =1

46

x w
i =1

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Problema se noteaz cu : knap(1,n,M). Presupunem c exist o secvent X=( x1 , x2 , ....xn) reprezentnd o alegere
optimal.
Exist urmtoarele dou variante:

1. x1=0 si atunci secventa ( x2 , x3 , ....xn) este optimal pentru problema knap(2,n,M).


2. x1 =1 si atunci secventa ( x2 , x3 , ....xn) este optimal pentru problema knap(2,n,M-w1).
Se observ c si n acest caz principiul optimalittii se respect

**

Fie s0 starea initial a problemei. Presupunem c snt necesare n decizii d1 , d2 , ....dn. Prima decizie poate lua una
din valorile multimii D={ r1, r2, .rk}. Dac decizia d1 ia valoarea ri fie si starea problemei dup aceast decizie, si fie Ri
secventa optimal corespunztoare subproblemei corespunztoare starii si.. Dac este indeplinit principiul optimalittii
secventa optim global va fi cea mai bun din secventele: r1R1, r2R2 ,.., rkRk.
Exemple:
Drum minim

Se caut ntr-un graf drumul minim de la nodul i la nodul j. Fie Ei={ i1, i2, .is} multimea succesorilor nodului i si fie
drumurile minime corespunztoare de la fiecare din acesti succesori la j, anume Rk= drumul minim de la ik la j, (k=1,,s).
Atunci drumul minim de la nodul i la nodul j va fi cel mai mic dintre drumurile (i Rk ), k=1,,s.
Problema rucsacului 0/1

Fie problema knap(1,n,.M) si fie 0(M) valoarea profitului maxim pentru aceast problem. In general pentru o problem
knap(j+1,n,Y) valoarea profitului maxim se noteaz cu j(Y). Deoarece x1 ia valori din multimea de decizii D1={0,1},
avem:
0(M)= max{ 1(M), 1(M-w1)+p1}
(*)
***

Dac pentru o problem dat este valabil principiul optimalittii n starea initial, atunci se poate aplica acest principiu si la
urmtoarele stari intermediare
Exemple:
Drum minim

Dac (i, i1, i2, ..im, j) este drumul minim de la nodul i la nodul j si ik este un nod intermediar, atunci secventa ( i, i1, ,i2,
ik) este drum minim de la nodul i la nodul ik iar secventa (ik,ik+1, .j) este drum minim de la nodul ik la nodul j.
Problema rucsacului 0/1

Fie (x1,x2,xn) o secvent alegere optimal pentru problema knap(1,n,M). Atunci pentru orice valoare j ( j=1,n) :
j

(x1, x2, ..xj) este solutie optimal pentru problema knap(1,j,

w x
i =1

)
j

(xj+1,xj+2, xn) este solutie optimal pentru problema knap(j+1, n, M-

w x
i =1

Relatia anterioar ( * ) se generalizeaz la


j(Y) = max { j+1(Y), j+1(Y-wj+1) + pj+1 }
( ** )
relatia (**) este o recurent care se poate calcula stiind c n(Y)=0 pentru orice Y numr real.

_______________________________________________________________________________

47

Proiectarea Algoritmilor
_____________________________________________________________________________________

****
Exemplele anterioare evidentiaz recurente de tip forward ( n fat). Se pot defini aceste recurente si n mod backward.
Exemple
Drum minim

Dac (i, i1, i2, ..im, j) este drumul minim de la nodul i la nodul j, fie Ej={k ; (k,j)=arc din graf}, |E|=p multimea
predecesorilor nodului j. Pentru fiecare predecesor k fie Rk drumul minim de la nodul i la nodul k. Evident, drumul minim
general va fi cel mai scurt drum din drumurile de forma (Rk j) pentru k=1,,p
Probelema rucsacului (0/1)

Dac se noteaz cu fi(x) valoarea optim a problemei knap(1,i,x) se obtin recurentele:


fi (x)= max { fi-1 (x), fi-1 (x-wi) + pi} i=1,2, n (*)
Recurentele snt rezolvabile stiind c f0(x) = 0 x 0, f0(x) = , x < 0

Modelul metodei
Problemele ale cror solutii se pot obtine prin programarea dinamica sunt probleme de optim. Un prototip de astfel de
problem este urmtorul:
S se determine determine :
optim R(x1,,xm)
n conditiile n care acestea satisfac restrictii de forma
g(x1,,xm) ? 0
unde ? {<, , =, , >}.

(1)
(2)

Prin optim se ntelege de obicei min sau max iar ecuatia (1) se mai numeste si functie obiectiv. Un alt prototip este furnizat
de digrafurile ponderate, unde R(x1,,xm) exprima suma poderilor arcelor x1,,xm iar restrictiile impun ca x1,,xm s fie
drum sau circuit cu anumite proprietti.
Metoda programrii dinamice propune determinarea valorii optime prin luarea unui sir de decizii <d1, ..., dn> numit si
politic, unde decizia di transform starea (problemei) si-1 n starea si , aplicnd principiul de optim:
Secventa optim de decizii (politic optimal) care corespunde strii s0 are proprietatea ca dup luarea primei decizii,
care transform starea s0 n starea s1 , secventa de decizii (politica) rmas este optim pentru starea s1 .

De cele mai multe ori prin stare a problemei se ntelege o subproblem. Unei stri i se asociaz o valoare z si se defineste
f(z) astfel nct, dac starea s corespunde problemei initiale, atunci:
f(z) = optim R(x1,,xm)

(3)

Principiul de optim conduce la obtinerea unei ecuatii functionale de forma:


f(z)= optim [H(z,y,f(T(z,y)))]

(4)

unde z este valoarea asociat strii s, T(z,y) calculeaz valoarea asociat strii s rezultat n urma deciziei y iar H exprim
algoritmul de calcul al valorii f(z) dat de decizia y care transform starea s n starea s. Dintre toate deciziile care se pot
lua n starea s (producnd s ) , se alege una care d valoarea optim n conditiile n care politica aplicat n starea s este si
ea optim.

48

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
Ex: Problema rucsacului :
i(Yi) = max {i+1(Yi), i+1(Yi-wi+1) + pi+1 }
i

unde i(Yi ) = valoarea de optim pentru Knap(i+1,n,Yi), Yi= M-

w x
k =1

Notatiile din (4) conduc la urmtoarele:


z=i , s=si , f(i) = optim-Knap(i+1,n,Yi) = i(Yi). Rezult: f(i)=f(i+1)+pi+1xi+1
y {0,1}, T[i,y]=i+1, s=si+1 , H(i,y,f(T(i,y)))=f(i+1)+ pi+1y
H(i,0,f(T(i,0))) = H(i,0,f(i+1)] = f(i+1) = i+1(Yi+1) = i+1(Yi)
H(i,1, f(T(i,1))) = H(i,1,f(i+1)] = f(i+1)+pi =i+1(Yi+1)+pi+1 =i+1(Yi- wi+1)+pi+1
Rezult : f(i)= max {i+1(Yi), i+1(Yi-wi+1) + pi+1 }
Principiul de optim implic proprietatea de substructur optim a soluiei, care afirm c soluia optim a problemei include
soluiile optime ale subproblemelor sale. Aceast proprietate este utilizat la gsirea soluiilor corespunztoare starilor
optime. n general, programele care implementeaz modelul dat de programarea dinamic au dou prti:
1. Determinarea valorilor optime date de sirul de decizii optime, prin rezolvarea ecuatiilor (4)
2. Construirea solutiilor (valorilor xi care dau optimul) corespunztoare strilor optime pe baza valorilor calculate n prima
parte, utiliznd proprietatea de substructur optim.

Eficiena metodei
n general, nu se recomand scrierea unui program recursiv care s calculeze valorile optime. In cazul programelor
recusive, dac n procesul de descompunere problem subproblem, o anumit subproblem apare de mai multe ori, ea
va fi rezolvat ori de cte ori apare. Asa se procedeaz n cazul aplicrii metodei Divideand-Conquer. Este mult mai
convenabil ca valorile optime corespunztoare subproblemelor s fie memorate ntr-un tablou i apoi combinate pe baza
ecuatiilor (4) pentru a obtine valoarea optim a unei subprobleme. n acest fel orice subproblem este soluionat o singur
dat, iar calcularea valorilor optime se face de la subproblemele mai mici la cele mai mari (bottom-up). Prin memorarea
valorilor optime ntr-un tablou se reduce si timpul de calcul pentru optimul unei subprobleme, datorit accesului la un
element dintr-un tablou n O(1) timp.
Complexitatea algoritmilor care implementeaz metoda programrii dinamice depinde direct de tipul de recursivitate
implicat de recurentele rezultate prin aplicarea principiului optimalittii. n cazul recursiei liniare valorile optime pot fi
calculate n timp liniar. In cazul recursiei n cascad rezult 2n subprobleme. De obicei n aceste situatii se studiaz
posibilitatea redefinirii starilor astfel nct sa rezulte o recursie liniar

Comparatie intre metoda programrii dinamice si metoda greedy


1.

- Metoda greedy utilizeaz proprietatea alegerii locale: solutia globala optim este construita prin selectii optime locale
- Metoda programrii dinamice utilizeaz proprietatea de substructur optim: solutia optim a unei probleme include n
structura sa soluiile optime ale subproblemelor

2.

- Alegerea local n cazul metodei greedy nu depinde de alegerile ulterioare, deci metoda greedy nu are caracter
recursiv.
- Proprietate de substructur optim utilizat n programarea dinamic are un caracter recursiv: pentru a construi solutia
optima a problemei este necesar cunoasterea solutiilor subproblemelor. Deci rezolvarea problemei implic
rezolvarea subproblemelor.

3.

- Parcurgerea arborelui subproblemelor in cazul metodei greedy se face n manier top-down


- Parcurgerea arborelui subproblemelor in cazul metodei programarii dinamice este facut n stil bottom-up
_______________________________________________________________________________

49

Proiectarea Algoritmilor
_____________________________________________________________________________________

Studii de caz
Problema rucsacului (0/1)
Relatiile de recurent backward rezultate din aplicarea principiului de optim sint urmtoarele:
fi (x)= max { fi-1 (x), fi-1 (x-wi) + pi} i=1,2, n (*)
unde fi(x) este valoarea optim a problemei knap(1,i,x).
Recurentele snt rezolvabile stiind c f0(x) = 0 x 0, f0(x) = , x < 0
Exemplu :

n=3,

(w1 , w2 , w3) = (2 , 3 , 4),

f0(x) = 0

M=6

g1(x) = f0(x-w1)+p1 = f0(x-2) + 1

f1(x) = max{f0(x) , f0(x-2) + 1}

f2(x) = max{f1(x) , f1(x-3) + 2}

50

(p1 , p2 , p3) = (1 , 2 , 5),

g2(x) = f1(x-w2) + p2 = f1(x-3) + 2

g3(x) = f2(x-w3) + p3 = f2(x-4) + 5

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

f3(x) = max{f2(x) , f2(x-4) + 5}

gi(x) -se obtine din fi printr-o translatie (wi , pi)

Se observ c functia fi este specificat de perechile (w'j , p'j), j = 1,r , unde w'j sunt abscisele n care fi are un salt , p'j =
f(w'j).
Exemplu: f3 caracterizat de (0,0) , (2,1) , (3,2) , (4,5) , (6,6) , (7,7) , (9,8). Se observ c functia este cresctoare, adic w'j

< w'j+1

p'j < p'j+1 si c fi(x) = fi(w'j) pentru w'j x<w'j+1 j = 1,r , fi(x) = w'r x w'r , r = numrul de salturi ale functiei.

Fie Si multimea perechilor care caracterizeaz fi . Atunci Si-1 caracterizeaz fi-1.


Se noteaz cu Ti = {(w,p) / (w-wi,p-pi) Si-1} multimea ce caracterizeaz gi(x) = fi-1(x-wi) + pi.
Ti se obtine din Si-1 adunnd la fiecare pereche (wi,pi).
Si se obtine combinnd Ti cu Si-1astfel nct s se obtin maxim din cele dou functii fi-1 si gi. Combinarea celor dou
multimi Ti si Si-1 se face dup urmtorul principiu (principiul dominantei ) :
Fie (w'j,p'j) Ti si (w'k,p'k) Si-1 sau (w'j,p'j) Si-1 si (w'k,p'k) Ti.
Dac p'j < p'k si w'j > w'k , atunci (w'j,p'j) se elimin.
Pentru exemplul anterior:
S0 = {(0,0)}
T1 = {(2,1)}
1
T2 = {(3,2) , (5,3)}
S = {(0,0) , (2,1)}
2
T3 = {(4,5) , (6,6) , (7,7) , (9,8)}
S = {(0,0) , (2,1) , (3,2) , (5,3)}
3
S = {(0,0) , (2,1) , (3,2) , (5,3) , (4,5) , (6,6) , (7,7) , (9,8)}
Observatii: 1. n calculul multimilor Si se pot elimina toate perechile (w,p) cu w > M, deoarece nu se calculeaz fi(x) cu x
> M.
2. n conditiile eliminrilor de la obs.1. valoarea de optim a solutiei este dat de ultima pereche din Sn , (w,p)
, anume p este valoarea de optim.
3. Metoda prezentat nu ofer nc o solutie completa. Cum se deduce solutia (x1 x2 ... xn) ?
Fie (w,p) ultima pereche din Sn . Dac (w,p) Sn-1 , atunci xn = 0 altfel xn=1. Dac
(w,p) Sn-1,
n-1
atunci
(w-wn, p-pn) S .
Se consider (w',p')= (w-wn, p-pn) dac (w,p) Sn-1 . Altfel (w',p')= (w, p). Se testeaz (w',p') Sn-2 etc.

Pentru exemplul anterior:


M = 6 , S3 = {(0,0) , (2,1) , (3,2) , (4,5) , (6,6)}
(w,p) = (6,6) , (6,6) S2 , deci x3 = 1
(6-w3, 6-p3) = (2,1)
(2,1) S2 , (2,1) S1 x2 = 0
(2,1) S1 , (2,1) S0 x1 = 1

_______________________________________________________________________________

51

Proiectarea Algoritmilor
_____________________________________________________________________________________
dinamic_knapsack(w,p,n,M)
{
S0 = {(0,0)} ;
for i =1,,n
{

Ti = {(w,p) / (w-wi,p-pi) Si-1 si w M} ;


Si = combine(Ti,Si-1) ;

}
fie (w,p) ultima pereche din Sn ;
for i=n,n-1,,1
if (w,p) Si-1
xi=0;
else
{xi=1; w=w-wi; p=p-pi; }
}
Complexitate
Algoritmul construieste element cu element multimile S0, S1, .Sn. In cazul cel mai defavorabil cnd nu se elimin nimic |
S0|=1, |S1|=2, .|Si|=2*|Si-1|=2i, . Un calcul simplu produce urmtorul rezultat
n 1

|S

| =

i= 0

n 1

= 2n 1

i= 0

Rezult o complexitate de timp si de spatiu exponential O(2n)


Metoda deci este extrem de ineficient.

Inmultire optim de matrici


Presupunem c avem produsul de matrice A1 x A2 x A3 x ... x An , unde pentru i=1,,n, Ai are dimeniunile di si di+1 .
Pentru nmultirea acestor matrice numrul total de operatii este d1 * d2 *...*dn. Asociativitatea permite o strategie de solutie
care s minimizeze numrul total de nmultiri.
Exemplu: fie produsul de matrice A1 x A2 x A3 x A4
de dimensiuni:

(100,1)

(1,100)

(100,1)

(1,100)

Considerm urmtoarele variante de asociere a nmultirilor:


1) (A1 x A2) x (A3 x A4) nr.oper. = 10000 + 10000 + 1000000 = 1020000
2) (A1 x (A2 x A3)) x A4 nr.oper. = 100 + 100 + 10000 = 10200
Rezolvarea problemei prin programare dinamic:

Fie Ai,j = Ai x Ai+1 x ... x Aj 1 i j n si cost[ i,j] - costul nmultirii.


Observm cost[ i,i] = 0 1 i n
cost[i, i+1] = di * di+1 * di+2 pentru 1 i n-1
Principiul optimalittii se poate formula astfel:
Pentru un pas general al nmultirii:
(Ai x Ai+1 x ... x Ak) x ( Ak+1 x Ak+2 x ... x Aj)
dk,dk+1 dk+1,dk+2 dk+2,dk+3
dj,dj+1
di,di+1 di+1,di+2
(*)

cost[ i, j ]= min { cost[ i,k ]+ cost[ k+1,j ] + di * dk+1 * dj+1 }


i k<j

Putem calcula acest cost[i,j] n ordinea :

j-i=1
j-i=2
.....
j - i = n - 1 pn la cost[1,n].

Construim matricea cost[i,j]. Observm c matricea este triunghiular.

52

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
prod(n,d,cost)
{
// d[1..n+1] contine di, i = 1,n+1 - dimensiunile matricilor
// cost[1..n, 1..n] matricea costurilor
for i =1,,n
cost[1,i] = 0
for k =1,,n-1
// diferenta j - i
for i =1,,n-k
{
j=i+k
cost[ i,j ] = min { cost[ i,p ] + cost[ p+1,j ] + di * dp+1 * dj+1 / i p < j }
cost[ j,i ]= q
// q -indicele pt care se realiz. minimul anterior.
}
}
Pentru exemplul anterior, calculul costului este urmtorul:
n=4
d = ( 100, 1 , 100 , 1 , 100 )
cost[1,1] = cost[2,2] = cost[3,3] = cost[4,4] = 0
Pentru k = 1:
i = 1, j = 2, p =1
0
10000
cost[1,2] = 0 + 0 + 10000 = 10000
1
0
i = 2, j = 3, p = 2
1
2
cost[2,3] = 0 + 0 + 100 = 100
1
3
i = 3, j = 4, p = 3
cost[3,4] = 0 + 0 + 10000 = 10000
Pentru k = 2 :
i=1,j=3
cost[1,3] = min{cost[1,1] + cost[2,3] + d1d2d4 , cost[1,2] + cost[3,3] + d1d3d4}
= min{0 + 100 + 100 , 10000 + 0 + 10000}= 200
i=2,j=4
cost[2,4] = min{cost[2,2] + cost[3,4] + d2d3d5 , cost[2,3] + cost[4,4] + d2d4d5}
= min{0 + 10000 + 10000 , 100 + 0 + 100}= 200
Pentru k = 3 :
i=1,j=4
cost[1,4] = min{cost[1,1] + cost[2,4] + d1d2d5 , cost[1,2] + cost[3,4] + d1d3d5 ,
cost[1,3] + cost[4,4] + d1d4d5 }
= min{0+200+10000 , 10000+10000+1000000, 200+0+10000}= 10200

200
100
0
3

10200
200
10000
0

Complexitate:

Se poate usor observa c algoritmul lucreaz n O(n3) , ntruct sunt dou bucle for, plus numrul de comparatii pentru
selectia minimului.
n 1 n k

n 1 n k

n 1

n 1

n 1

n 1

k =1 i =1

k =1 i =1

k =1

k =1

k =1

k =1

n 1

( j i 1) = (i + k i 1) = (n k )( k 1) = nk - n - k + k
=n

k =1

n(n 1) .
n(n 1)(2n 1) n(n 1)
- n 2n+ n +
= O(n3)
2
6
2

Arbori binari de cautare optimali


Fie A=( a1, a2, . an ) secventa sortat cresctor cu valori din care se construieste un arbore de cutare. Se consider c
operatia de cutare se execut cu anumite frecvente. Anume:
P = ( pi ; pi - probabilitatea de a fi cutat elementul ai , i= 1,n )
Q = ( qi ; qi - probabilitatea de a fi cutat un element x cu proprietatea ai<x<ai+1 , i=0,n )
unde a0= - , an+1= + .
In aceste conditii se noteaz:
_______________________________________________________________________________

53

Proiectarea Algoritmilor
_____________________________________________________________________________________
n

p
i =1
n

q
i=0

- probabilitatea de succes

- probabilitatea de insucces

iar
n

p
i =1

q
i=0

=1

Pentru P si Q date arborele binar de cutare optimal este cel pentru care operatia de cutare ofera timp mediu minim. Pentru
a pune n evident timpul mediu se considera arborele binar de cutare completat cu o serie de pseudonoduri
corespunztoare intervalelor de insucces, pseudonoduri care se asociaz pointerilor nuli. In exemplul de mai jos se prezint
un arbore si completatul su.
a2

a2

a1

a4

a4

a1

a3

E1

E0

a3

E2

E4

E3

Nodul Ei corespunde tuturor cutrilor fr succes pentru valori cuprinse n intervalul


(ai, ai+1). Timpul unei operatii de cutare pentru un element x este dat de adncimea nodului de valoare x sau de adincimea
pseudonodului corespunztor intervalului care-l contine pe x.
Costul unui arbore reprezint timpul mediu al unei cutari pentru o valoare x , adic

Cost (T ) =

p * level ( a ) + q * (level ( E ) 1)
i =1

i=0

Prin level(a) se noteaz nivelul nodului a si reprezint numrul de comparatii efectuate de functia de cutare pe drumul de
la rdcin pn la nodul a. Pondernd acest numr cu probabilitatea de a fi cutat nodul a si efectund suma pentru toate
nodurile se obtine timpul mediu de cutare cu succes a unui nod. In mod similar se calculeaz timpul mediu de cutare
pentru insucces, cu observatia c din level(Ei) se scade valoarea 1 deoarece decizia de apartenent la un interval nu se face
la nivelul pseudonodului ci la nivelul printelui su.
Dat fiind secventa de valori A se pot construi o multime de arbori binari de cutare cu cheile nodurilor din A. Un arbore
binar de cautare optimal este arborele de cost minim.
Din punctul de vedere al programrii dinamice, construirea unui arbore optimal const ntr-un sir de decizii privind nodul
care se alege ca rdcin n fiecare pas.
Fie ( a1, a2, ..ak, . an) secventa de noduri sortat cresctor si presupunem c n primul pas se alege ca rdcin nodul
ak. Conform principiului optimalittii vom avea:

subarborele stng L este construit cu secventa ( a1, a2, ..ak-1) si clasele (E0,E1, Ek-1)

Cost ( L ) =

k 1

i =1

54

p i * level ( a i ) +

k 1

q * (level ( E ) 1)
i= 0

subarborele drept R este construit cu secventa ( ak+1, ak+2, ..an) si clasele (Ek, Ek+1, ..En)
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Cost ( R ) =

i = k +1

* level ( a i ) +

q * (level ( E ) 1)
i=k

Valoarea level() se calculeaz relativ la subarborii L, R, respectiv.


Costul asociat arborelui devine

Cost (T ) = p k + Cost ( L ) + Cost ( R ) +


k 1

Sumele

i =1

pi +

k 1

qi +
i=0

i = k +1

pi +

k 1

i =1

pi +

k 1

qi +
i=0

i = k +1

pi +

q
i= k

(*)

q
i=k

reprezint valorile suplimentare care apar datorit faptului c arborele

intreg
T introduce un nivel suplimentar (cel al rdcini) fat de subarborii L,R. In continuare relatia ( * ) se rescrie ca :

Cost(T ) = p k + Cost( L ) + Cost( R ) + q 0 +

k 1

(p
i =1

+ qi ) + q k + ( pi + qi )

( ** )

i = k +1

Notnd

wi , j = q i +

(p

k = i +1

+ q k ) se obtine:

Cost(T ) = p k + Cost( L ) + Cost( R ) + w 0,k 1 + w k ,n .


( *** )
Atunci cnd acest cost este minimal el devine egal cu

Cost ( L) + Cost ( R) + w0, n .

Principiul optimalittii este respectat deoarece subarborii L si R trebuie s fie optimi.


Se noteaz cu ci,j costul unui subarbore optimal Ti,j care are nodurile din secventa (ai+1, ai+2, ..aj) si pseudonodurile
din (Ei, Ei+1, .Ej ).
Pentru situatia discutat anterior, n conditiile n care arborele cu nodul rdcin ak este optimal, notatiile devin:
c0,k-1=Cost( L )
ck,n =Cost( R )
Principiul optimalittii se scrie astfel:

c 0, n = min{ c 0, k 1 + c k , n + p k + w0, k 1 + wk , n }
1 k n

( **** )
Generaliznd,

c i, j = min {c i , k 1 + c k , j + p k + wi , k 1 + wk , j } =
i +1 k j

min {c i , k 1 + c k , j + wi, j }

i +1 k j

Costul optimal c0,n se poate calcula efectiv folosind ultima relatie de recurent pentru j-i=1 apoi j-i=2, .
Valorile initiale snt ci,i=0, wi,i=qi, 0in . In plus se foloseste relatia w = p + q + w
i,j
j j i,j 1

_______________________________________________________________________________

j-i=n .

55

Proiectarea Algoritmilor
_____________________________________________________________________________________

Algoritmul de calcul al arborelui optimal


opt-bst(P,Q,n)
// (a1,a2,.an) secventa de noduri (valori)
// P, Q, secventele de succes si insucces
// Se calculeaza C=(ci,j)- costurile, W=(wi,j) si R matricea de indici ai radacinilor
// ri,j=indicele nodului radacina al subarborelui optimal format din secventa (ai+1,ai+2,.aj)
{
for i =1,,n-1
{ci,i = 0; ri,i = 0; wi,i = qi ;
ci,i+1 = qi + pi+1 + qi+1 ;
/*
/* arborii cu un nod
ri,i+1 = i+1;
/*
wi,i+1 = qi + pi+1 + qi+1 ;
}
wn,n = qn; rn,n = 0; cn,n = 0;
for m =2,,n
for i =0,,n-m
{
j= i+m;
wi,j = wi,j-1 + pj + qj;
fie k indicele care relizeaz valoarea minim pentru{ ci,h-1+ch,j ; h I=[i+1,j]} ;
(XXX)
ci,j = wi,j + ci,k-1 + ck,j ;
ri,j = k ;
}
}

//

Complexitate

In mod obisnuit algoritmul lucreaz n timp O(n3) . Exist o observatie a lui Knuth prin care in linia marcat (XXX) n
algoritm nu se consider intervalul de indici I=[i+1, j] ci intervalul I=[ ri,j-1 , ri+1,j], algoritmul lucrnd astfel corect n timp
O(n2).

56

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Metoda Backtracking

Descrierea Metodei
Metoda BackTracking se aplic n probleme de cutare. Metoda este adecvat problemelor n care solutia se poate exprima
ca un n-uplu (x1 x2 ... xn) , xi Si - finita , i = 1,n . Solutia trebuie s satisfac sau s minimizeze / maximizeze o functie
criteriu P(x1 x2 ... xn). Uneori se solicit toate solutiile.Daca |S1| = m1 , |S2| = m2 . . . |Sn| = mn , atunci numrul total de n-uple
este m=m1 m2 ... mn. Metoda nu asigur c nu se vor ncerca toate cele m posibilitati , dar practic reduce mult numrul de nuple care se ncearca prin folosirea functiei criteriu. Ideea este de a folosi o form partial a functiei criteriu Pi(x1 x2 ... xi)
care elimin familii ntregi de n-uple. Dac de exemplu solutia partial (x1 x2 ... xi) nu are nici o sans de a conduce la o
solutie complet , toate cele mi+1 mi+2 ... mn n-uple cu (x1 x2 ... xi) pe primele i pozitii se abandoneaz.

Spatiul solutiilor. Restrictii.


S1 S2 ... Sn se numeste spatiul solutiilor problemei, iar restrictiile de forma (x1,x2,...,xn) S1 S2 ... Sn se numesc
restrictii explicite ; restrictiile (x1, x2 ,...,xn) satisfcnd P se numesc restrictii implicite
Exemplu 1: Problema celor 8 dame pe tabla de sah : Dat fiind S={1,2,3......8}=multimea celor 8 dame si o tabla de sah (
8 linii si 8 coloane) s se plaseze cele 8 dame asfel ncit s nu existe dou dame pe aceeasi linie, coloan sau diagonal.
O solutie poate fi exprimat printr-un 8-uplu X=(x1,x2,....x8) unde xi = coloana pe care se plaseaza dama I ( linia pe care se
plaseaz dama I este i )
- Deoarece Si = S, i=1,,8 rezult ca spatiul de solutii SSS... S are 88 8-uple;
de 8ori
- Restrictia explicit: 1xi8 , i=1,,8
- Restrictii implicite -o singura dama pe o coloana : xixj , () ij, i,j=1,,8
-o singura dama pe o diagonala : |i-j||xi-xj| , () ij, i,j=1,,8
Exemplu 2: Submulimi de sum dat : Date fiind S={w1,w2,....wn}, wi0 1 in si M-o valoare
determine toate submultimile S S, S`={x1,x2,....xk} cu proprietatea x1+x2+......+xk=M

M > 0, s se

Cazul n=4 : S={11,13,24,7} M=31 S=(11,13,24,7); solutii : X1=(11,13,7), X2=(24,7) sau exprimate prin indicii i ai
elementelor wi S, X1=(1,2,4), X2=(3,4)
Pentru cazul exprimrii solutiilor prin indicii i ai elementelor wi S restrictiile snt urmtoarele:

- Restrictii explicite 1xin, , i=1,,n


- Restrictii implicite: xixj si

xi

xi

=M

xi<xi+1 pentru a evita generarea aceleasi multimi


ex.:{1,2,4}={2,4,1}

_______________________________________________________________________________

57

Proiectarea Algoritmilor
_____________________________________________________________________________________
n

O alt abordare: X=(x1,x2,........xn),

x w

xi = 0 sau 1;

i =1

=M

Spatiul solutiilor este de dimensiune 2n.


Organizarea sub form de arbore a spatiului solutiilor

Metoda backtracking rezolv o problem prin cutarea sistematica a solutiei n spatiul solutiilor. Conceptual , aceasta
cutare foloseste o organizare a spatiului solutiilor sub forma unui arbore.
Exemplul 1 : Problema celor n-dame
folosim n=4

x =1
1

x =3
2

3
x =3
3

11

13

x =4
2

x =4
4

x =2
1

x =2
2

x =4
1
x =3
1

10

12

n acest arbore arcele de la nivel i la i+1 snt etichetate cu valori xi.


Spatiul solutiilor = secventele de etichete de la rdcin la nodurile frunz.Nodurile snt etichetate n
sensul parcurgerii depth-first.
Exemplul 2: Submulimi de sum dat (11,13,24,7) M=31
1
x =1
1

4
2

2
2
6
x =3
3
12

7
4
13

8
4

14

3
3

4
4

5
4

10

11

4
15

X4 = 4
16

Traversare breadth-first.
Notiuni :
-starea problemei - fiecare nod ntr-un arbore defineste o stare a problemei;
-spatiul strilor - toate drumurile de la rdcin la noduri;
-stri solutie - acele stri (noduri) pentru care drum de la rdcin la nod etichetat cu un n-uplu;
-stri raspuns - stari care satisfac conditiile implicite P;
-arborele spatiului strilor - spatiul strilor problemei organizat sub form de arbore.
Arborii construiti astfel snt arbori statici si nu depind de instanta problemei. Exista arbori dinamici care depind de
problem. Un exemplu ar fi cazul n care functie de valoarea lui x1 se decide dac la primul nivel este x1 sau x2 s.a.m.d.

58

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Backtracking si Branch-and-Bound
Exista dou strategii de generare a nodurilor corespunztoare starilor problemei : depth-first si breadth-first.
Nodurile se clasific n:
-nod viu
-nod generat pentru care nu s-au generat descendenti;
-E-noduri
-noduri n expandare - noduri vii pentru care procesul de generare al
descendentilor este in curs;
-noduri moarte
-nod generat care nu are descendenti (si nici nu va avea)
sau pentru care toti descendentii s-au generat.
In strategia depth-first, pentru E-nodul curent se identifica un descendent C care devine noul E-nod si procesul se aplica
recursiv.
n strategia breadth-first, pentru E-nodul curent se genereaz toti descendentii si se trec in lista de noduri vii sau moarte.
n ambele strategii n orice moment se aplic functia criteriu (restrictiile implicite), numita si functia de mrginire care
seteaz un nod ca nod mort fara a-i mai genera descendentii.
Prima tehnica este numit backtracking
A doua tehnica este numit Branch-and-Bound
Exemplu pentru tehnica backtracking: Problema celor 4 dame:

1
*

2
*

2
*

1
*

2
3

Ordinea de generare este:


1

x = 1
1
x = 2
2
3
B

x = 2
1

2
4

3
8

2
13
3

x = 4 2
3
14
11

x = 2
3

x = 3
4
15

= 1

16

18
3

19

24

4
29

30

x = 1
3
x = 3
4

31

_______________________________________________________________________________

59

Proiectarea Algoritmilor
_____________________________________________________________________________________

Modelul metodei
Fie (x1,x2,......xi) un drum de la radacin la un nod ntr-un arbore spatiu de stri.
Fie T(x1,x2,........xi) multimea tuturor valorilor posibile pentru xi+1 astfel nct
(x1,x2,.....xi,xi+1) este de asemenea un drum de la radcin la un nod.
Fie Bi+1(x1,x2,.....xi+1) functia (predicatul) de marginire derivat din P - functia criteriu
Bi+1(x1,x2,.....xi+1) = false dac xi+1 este nod mort, de blocaj;
true dac xi+1 se extinde;

Backtrack-iterativ (n)
// Solutile snt generate n x[1,2,...n];
// T(x1,..xk-1)={xk / (x1,x2....xk-1,xk) - drum radcin la nod}
// Bk(x1, ......xk) - functie (predicat) de marginire;
{
k=1 ;
while (k>0)
{
if ( y T (x1,x2,....,xk-1) nencercat si Bk(x1,x2, ....xk-1,xk=y)=true )
{
print (x1,x2, ....xk) ;
if ( (x1,x2, ....xk) = solutie nod rspuns)
k=k+1;
}
else
k=k-1 ;
}
}

backtrack-recursiv (k)
// Solutile snt generate n x[1,2,...n];
//T(x1,..xk-1)={xk / (x1,x2..xk-1,xk) - drum de la radcin la nod }
//Bk(x1, ......xk) - functie (predicat) de mrginire;

for (each xk a.i. xk= y T(x1....xk-1)


{

and Bk(x1.....xk-1,xk)=true

if (x1...xk-1,xk) = sol.(nod de rspuns)


backtrack-recursiv(k+1)

print (x1.....xk-1,xk)

}
Observatii
1.Eficienta algoritmului depinde de
- timpul pentru generarea urmtorului xk;
- numrul de elemente din T(x1.....xk-1)
- functia de mrginire B;
- numrul total de noduri.
2.Pentru multe probleme, multimile Si, se pot lucra n orice ordine, iar elementele din T(x1,......xk-1) la fel.
60

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Folosind aceasta observatie se pot stabili anumite euristici - strategii de organizare a elementelor lui Si cu scopul de a
reduce nivelul de backtraking.
3.Ordinul de complexitate este O(2n) sau O(n!)
Metoda nsa rezolva , de obicei, mult mai rapid problemele fra nsa a se sti exact cit de repede.
Uneori se poate incerca o estimare a timpului backtrcking si aceasta pornind de la o estimare a numrului de noduri.
Estimarea numrului de noduri se poate face prin urmatoarea procedura generala:
estimate ( )
{ nr=1; r=1; k=1; t=true;
while (t)
{ Tk={xk | xkT(x1..xk-1) si Bk(x1,x2...xk)=true}
if(|Tk|=0) break;
r=r|Tk| ;
nr=nr+r ;
xk=random-choose(Tk);
k=k+1;
}
return (nr)
}

Studii de caz
Problema celor 8 dame
Dac se consider 2 elemente pe aceeasi diagonal (i,j) ,(k,l)
i-j=k-l sau
i+j=k+l
j-l=i-k
j-l=k-i
adic se poate folosi conditia |j-l|=|k-i|.
Construim functia place(k) care returneaz true dac dama cu numarul de ordine k poate fi plasata pe coloana data de x[k].
Operatiile care se fac snt:
- se testeaza daca x[k] x[i] i=1,2,,k-1
- se testeaza daca nu alta dama in aceeasi diagonal.
Functia place lucreaza in O(k-1)
place(k)
{ i=1;
while(i<k)
{ if ( x[i]=x[k] or abs(x[1]-x[k])=abs(i-k) )
return false ;
i=i+1 ;
}
return true
}

_______________________________________________________________________________

61

Proiectarea Algoritmilor
_____________________________________________________________________________________

n_queen (n)
{ // x[1.. n] - vectorul de solutii
x[1)=0; k=1;
while (k>0)
{
x[k]=x[k]+1;
while ( x[k]n and place(k)=false)
x[k]=x[k]+1;
if( x[k]n )
//place(k)=true - o pozitie gasit
{
if (k=n)
// solutia este complet ?
print(x);
else
{k=k+1; x[k]=0 }
}
else
k=k-1;
// x[k] > n backtrack
}
}

Submulimi de sum dat


Fie n numere pozitive

wi>0

S ={w1,w2,......wn}

S se determine toate submultimile S` S cu

wi wj

ij

w =M

si M>0.

wS '

Folosim notatia solutiei sub forma X={x1,x2......xn}

xi=0 sau 1

wi=M

i =1,n

Arborele spatiului strilor va fi de forma:


1

x =1
1
x =1
2

x =0
1

x =01
2
6
5

0
7

Consideram w1,w2....wn n ordine cresctoare (fr a fi o restrictie general)


Functia de mrginire
k

Bk(x1,x2,....xk) = true if (

x w + w
i

i =1

i = k +1

and

wi + wk+1M)

i =1

wi-cresc.

= false - altfel

SumSubset(s,k,r)
{
//(x1,x2,....xn) - vectorul solutie . Psp. x1,,xk-1 calculati
k 1

//s =

wi

r=

i =1

i=k

//Psp. w1M si

M [ deci initial (k=1) Bk-1 = true ]

i =1

62

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

{
xk=1;
if (s+wk=M)
print (xj , j=1..k);
else
{
if(s+wk+wk+1M )

// nu se mai ncearc valori pentru xk+1>0.....


// Bk = true
k

// nu se mai verific

x
i =1

XXX

wi+

SumSubset(s+wk, k+1, r-wk);

deoarece s+r>M si xk=1

i = k +1

// apel recursiv

if (s+r-wkM and s+wk+1M)

// Bk = true

//generaza arborele din dreapta cu (xk=0)


{
xk=0;
SumSubset(s,k+1,r-wk);
}
}
return
}
Observatie:

Functia intr n executie ,avnd asigurate conditiile Bk-1=true : s+wkM si s+rM.


Initial w1M si 0+

i =1

i =1

wi M corespunznd apelului SumSubset (0,1, wi )

Aceste conditii sunt asigurate la apelul recursiv.


Nu se verific explicit k>n deoarece initial s = 0 < M si s+r M. Rezult r 0 deci k nu poate depsi n. De asemenea n
linia XXX deoarece s+wk < M si s+r M rezult r wk, deci k+1 n.

_______________________________________________________________________________

63

Proiectarea Algoritmilor
_____________________________________________________________________________________

64

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Metoda branch and bound

Descrierea metodei
Metoda se aplic la probleme de forma urmtoare:
Se dau multimile S1,S2.....Sn.
Sa se determine x = (x1,x2,......xn) S1 S2S3 . Sn (sp. de solutii) care satisface P(x1,x2,....xn)
-maxim
-minim
-conditii booleene
Spatiul solutiilor se organizeaza sub forma unui arbore Atunci cind arborele se genereaza prin tehnica parcurgerii in
adincime - backtrack
Cind generarea nodurilor se face prin traversare in latime (sau traversarea D) - branch and bourd. Conform acestei tehnici
pentru nodul viu x care este E-nodul curent , se genereaza toate nodurile (descendenti) si se depun in lista de noduri vii
dupa care se trece la urmatorul E-nod care se alege din lista nodurilor vii. Daca aceasta lista e o coada , avem de-a face cu o
traversare in latime; daca lista se organizeaza ca stiva , avem de-a face cu o traversare D.
DFS
BFS
D

Ex.

1,2,4,3,11,5,6,8,9,7,10;
1,2,5,7,4,3,6,8,9,10,11;
1,7,10,5,9,8,6,2,3,11,4.

x =1
1
x =1
2

2
2

3
2

1
6

2
8

3
9

10

11

T(x1,x2,....xi) = numarul de valori posibile pentru xi+1


(restrictiva explicita )
(restricta implicita.)
Bi+1(x1,x2,...xi) = predicatul de marginire derivat din T
Aceste concepte nu se mai pot folosi in traversarile BFS, D. Branch and Bound numeste de fapt toate tehnicile care au in
comun faptul ca in E-nodul curent se genereaza toate nodurile descendentilor dupa care se alege urmatorul E-nod ,dupa o
strategie oarecare.
Deoarece arborele sp. de solutii este foarte mare sau chiar infinit ,aceasta strategie trebuie sa contina elementele care sa
limiteze cautarea .
Ex. Problema celor 4 dame

x1
x2
x3
x4
_______________________________________________________________________________

65

Proiectarea Algoritmilor
_____________________________________________________________________________________

Arborele FIFO Branch and Bound:


(4)
2

:
2

+
7

x :
4

8
4

18

19

20

21

(3)

+
5

4
1

3
(3)

2 +
x

x :
1

(2)
10

1 3

(1)
22

13

12

11

23

24

4
(1)

+
B

(0)

16

17

+
27

26

15

B 2

14

2
31

(0)

25

3
30

+
28

29

+
32
B

- Se observa ca backtracking lucreaza mai eficient ca spatiu


- In cazul banch-and-bound (BB) se pastreaza o coada de situatii destul de mari
- Se sugereaza determinarea unei functii care sa dirijeze cautarea (o strategie # FIFO)
Printr-un calcul suplimentar sa presupunem ca se poate calcula pt. fiecare nod x o functie cost c(x).
Ex.: c(x)=lungimea dr. minim de la x la un nod solutie din subarborele de rad.x.
Folosind functia c(x) , se poate genera arborele intr-un mod dirijat.
1
2

3
9

11

10
22

23

30

Aceasta functie c (ideala) este greu de determinat . Se lucreaza cu o estimare a acestei functii - c* si de obicei c*(x) =
f(h(x)) + g*(x) unde
h(x) =costul drumului de la rad. la x (ex.- lg. drumului)
f - o functie oarecare
g*(x) = costul estimat atingerii unui nod solutie pornind din x
Strategia BFS se obtine pt. f(h(x))=level(x) si g* =0
Strategia D se obtine pt. f(h(x))=0 si g* o functie care asigura g*(y) = min {c*(z) } - 1
z lista noduri vii
In plus , se asigura ca c*(x)c(x) , x - un nod.
Aceasta metoda de cautare (dupa c*(x) = f(h(x)) + g*(x)) , se numeste cautare LC (least cost) si este un prim criteriu care
intervine in metoda BB (branch-and-bound). Pentru problema damelor - dificil de pus in evidenta o estimare eficienta.
Ex. 15-puzzle

1
6
8
11

3
2

5
7

9 10 12
13 14 15

1
5

2
6

3
7

4
8

9
13

10
14

11 12
15

Spatiul solutiilor contine 16! combinatii ( daca nu se verifica ciclitatile)


In plus, intereseaza modul de obtinere a solutilor ,adica drumul de la radacina la solutia finala.
Pentru o pozitie data se poate decide daca pozitia are solutie (poate conduce la pozitia finala), ori nu.
66
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Se defineste o ordine a locatiilor in patrat anume:


1

10

11

12

13

14

15

16

In fapt, o configuratie este o aplicatie injectiva:


poz:{1,2,3,......,15, 16}{1,2,3,.....,16}
piatra libera
poz (x) = i - piatra notata cu nr. x se afla pe pozita i ; in exemplul anterior poz(3)=2, poz(16)=7 etc.
Pentru fiecare configuratie si pt. orice pietricica de valoare (i) se defineste
least(i)=|{j / 1j16, j<i si poz(j) >poz(i)}|
Ex. anterior : least(6)=1
Teorema:

least(7)=0

least (16 ) =9

Pentru o configuratie data exista un sir de transformari pina la configuratia scop ddaca

16

S=

(least (i )) +p=nr.par
i=1

unde p se calculeaza astfel:


fie i, j {1,2,3,4}-linia si coloana unde este plasat spatiul liber (piatra nr.16):
p = 0, daca i+j - par
(pozitia alba)
= 1, daca i+j - impar (pozitia hasurata)

Demonstratie: Pentru configuratia scop I : S(I)=0+0 - par


Fie o configuratie T pentru care S(T) = nr. par si T` obtinut din T prin una din mutarile permise
Caz.1:

T`

pT`=(pT+1)mod 2
leastT`(16)=leastT(16)-1

leastT`(i)=leastT(i) i#16
Rezulta S(T`) - nr.par.
Caz.2 :

Similar cazului 1
_______________________________________________________________________________

67

Proiectarea Algoritmilor
_____________________________________________________________________________________

T`

Caz.3:

x
y

z k

k
y

T
pT` = (pT+1) mod.2
leastT ' (16)=leastT (16)-4

(*)
(**)

z
T`

( 3 casute de la (i,j) la (i+1,j)

Fie x,y,z, placutele pentru pozitia initiala a lui k si cea finala :


- avem situatiile :
a) k<x k schimba locul cu 16 - se scade 1 din least(x)
b) k>x se aduna 1 la least(k)
Oricum in suma totala se scade sau se aduna 1.
Obs. de mai sus este valabila pt. x,y,z ,deci la S se aduna sau se scade un nr. impar (1sau 3).Combinind cu (*) si (**), se
observa ca S(T`) ramine par.
Caz.4 :

simetric cu 3

Spunem ca o configuratie T este valida ddaca un sir de transformari de la T la configuratia scop I .


Deoarece prin transformarile nu se schimba paritatea valorii S si S(I) - para T-valida ddaca S(T) para.
Pentru acest exemplu ,vom considera:
c*(x) = f(x) + g*(x)
f(x) = level(x), iar g*(x) = nr. de placute care nu sint la locul lor.

68

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Branch and Bound (BB) cu strategie cost minim (LC)


Modelul metodei pentru strategia LC
BB_LC (T, c*)
// cauta in arborele T al spatiului solutiilor un nod raspuns de cost minim
// e = E-nodul curent
// add(x) - depune x in lista de noduri vii
// least( ) - returneaza nodul x cu c*(x) minim din lista de noduri vii
{
if (exista solutii)
{
e=T; // primul E-nod
while ( nu a fost gasita o solutie )
{
if (e = nod raspuns)
// c*(e)=c(e)
{
a fost gasita o solutie;
afiseaza drumul de la T la e;
return
}
else
for (fiecare x = descendent al lui e)
{
add(x);
// insereaza x in lista de noduri vii
parent(x)=e;
// inlantuire pentru refacerea drumului
} //end for
// end if (x = nod -raspuns)
e=least()
} // end while
} //end if (exista solutii)
}
Teorema 1 : e este un nod raspuns de cost minim
Demonstratie:

Din definitia costului estimat optimist c*, rezulta urmatoarele:


1. Pentru un nod raspuns r : c*(r) = c(r)
2. Un nod x satisface c*(x) c*(s), s fiu al lui x. Rezulta prin tranzitivitate ca c*(x) c*(d), d descendent al lui x.
Nodul e este primul nod raspuns extras din lista de noduri vii, deci celelalte noduri raspuns (daca exista) sunt in lista de
noduri vii sau sunt descendenti ai unor noduri din lista de noduri vii.
_______________________________________________________________________________

69

Proiectarea Algoritmilor
_____________________________________________________________________________________

Rezulta :
a.
b.

c(e)=c*(e) c*(x), x nod din lista de noduri vii (e=least())


c*(x) c*(r)=c(r), r nod raspuns descendent al lui x = nod aflat in lista de noduri vii

In consecinta c(e) c(r), r nod raspuns.

Mrginire
Unele probleme ( ex: problemele de optimizare ) permit si definirea unei functii (criteriu) de marginire : c*(x) c(x) u(x);
c(x) este necunoscuta.
Marginea superioara u are propietatea ca u(s) u(x), s fiu al lui x. Aceasta rezulta din structura lui u(x)=f(h(x)+k*(x) unde
f i h au semnificaiile de la c* iar k* exprima o estimare supraevaluata (pesimista) a costului de la x la un nod raspuns (o
solutie). Din u(s) u(x), s fiu al lui x, rezulta prin tranzitivitate ca u(d) u(x), d descendent al lui x.
Se pune problema determinarii unui nod raspuns r ( rR=multimea nodurilor raspuns) pentru care u(r) = min{ u(x) / xR }.
Observatie:

Pentru un nod raspuns c*(x) = c(x) = u(x). Deci problema determinarii lui r este echivalenta cu problema determinarii unui
nod raspuns de cost minim

Modelul metodei pentru strategia LC cu mrginire


BB_LC_UB (T, c*, r)
// cauta in arborele T al spatiului solutiilor un nod raspuns r cu u(r) = min{ u(x) / xR }
// e = E-nodul curent
// add(x) - depune x in lista de noduri vii
// least( ) - returneaza nodul x cu c*(x) minim din lista de noduri vii
{
if (exista solutii)
{
Initializeaza u
e = T ; // primul E-nod
while ( (c*(e)<u) (mai exista noduri vii ) )
for (fiecare x = descendent al lui e)
if (c*(x)<u)
{
add(x);
// insereaza x in lista de noduri vii
parent(x)=e;
// inlantuire pentru refacerea drumului
if (x = nod raspuns) { u=c(x); r =x };
else u=min(u,ux+);
}
// end for
e=least() // e=null nu mai exista noduri vii
} // end while
} // end if
}
Teorema 2 : r este un nod raspuns pentru care u(r) = min{ u(x) / xR }
Demonstratie : Minimalitatea lui u(r) rezulta urmatoareale :

70

_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________

Deoarece u(x) c(x) c*(x) rezulta ca daca c*(x) u atunci si u(x) u. Deci este suficient sa se testeze c*(x) < u
pentru a decide daca nodul x va fi generat (inserat in lista de noduri vii) ) sau nu. Aceasta conduce insa la generarea
unor noduri care pot avea u(x) u deoarece c*(x) < u nu asigura u(x) < u
2. Atunci cind un nod rapuns este generat acesta va avea costul c*(x)=c(x)=u(x) inferior lui u deci costul sau va defini
noua valoare a lui u.
3. Nodurile x care schimb valoarea lui u i nu sunt noduri rspuns, nu pot fi ultimele care realizeaz aceast modificare
Demonstratie:
c*(x) u(x) < u(x) + = u, deci x este un posibil viitor E-nod (urmeaza deci i alte
iteraii).
c*(y) u(y) u(x) < u(x) + = u , y descend al lui x, deci toti descendentii lui u vor fi generati deoarece u
ramane neschimbat pina la terminarea executiei algoritmului. Deoarece u(x) rezulta ca printre descendentii lui x
z = nod raspuns. Rezulta ca va fi generat un nod raspuns fara ca acesta sa schimbe valoarea lui u deoarece x este
ultimul care a facut aceasta. (qed)
Din 1-3 rezulta ca ultimul nod raspuns retinut (r) va fi si ultimul care micsoreaza u iar alte noduri care pot micsora u nu mai
exista. Rezulta ca r satisface u(r) = u = min{ u(x) / xR }
1.

Problema 0/1 a rucsacului ( 0/1 knapsack )

Definirea problemei: Datele problemei sunt:

obiectele:
greuttile:
profiturile:
capacitatea:

i1
w1
p1
M

i2
w2
p2

...
...
...

in
wn
pn

Se cere o alegere X = ( x1 , x2 , ... , xn ) , xi {0,1} astfel nct

x w
i

M (*) si

x p
i

- maxim (**)

o solutie admisibil satisface (*).

o solutie optim este admisibil si satisface (**)

Obs. 1. Daca

w
i

M solutia optimala este xi=1, i=1,,n. Deci problema are sens pentru wi > M .
i

Spatiul solutilor se poate organiza sub forma unui arbore binar :

_______________________________________________________________________________

71

Proiectarea Algoritmilor
_____________________________________________________________________________________

x =0
1
2
x =0
2

1
3

xi =

0 - obiectul i se ignora
1 - obiectul i se introduce in rucsac

Nodurile raspuns sint cele care reprezinta solutii admisibile

wi M

i =1

Pentru orice nod raspuns c(x) =

pi

i =1

Pentru orice nod terminal care nu este nod raspuns c(x) =+

Pentru orice alt nod y se defineste c(y) = min {c(lchild(y)), c(rchild(y)) }


Construim doua functii : c*(x) si u(x) a.i. c*(x) c(x) u(x)
Fie x un nod de pe nivel k; valorile x1,x2,......xk-1 sint deja calculate.

Valorile c*(x) si u(x) pot fi calculate cu procedura urmatoare:

bound(p,w,rw,cp,n,k,c*x,ux)
// rw = capacitatea ramasa
// cp = profitul deja obtinut
// obiectele k,,n nu au fost inca analizate
{
ux = cp; c = rw
72
_______________________________________________________________________________

Proiectarea Algoritmilor
_____________________________________________________________________________________
for i=k,,n
{
if (c w(i)) // obiectul i poate fi incarcat in rucsac
c = c - w(i); ux = ux - p(i);
else
// obiectul i nu poate fi incarcat in rucsac
{
c*x = ux c p(i)/w(i); // c*x = profitul maxim posibil pentru nodul x : p(i)/w(i) >= p(j/w(j) ,j=i+1,..,n
for j = i+1,n
{
if (c >= w(j))
//obiectul j poate fi incarcat in rucsac
{
c = c - w(j);
ux = ux - p(j);
}
} // end for j = i+1,n
// -ux = profitul sigur ce se poate obtine din nodul x
return;
} // end if (c w(i))
} // end for i=k,,n
c*x = ux;
// toate obiectele k,k+1,,n pot fi incarcate in rucsac
}

Algoritmul BB_LC pentru problema 0/1 a rucsacului:


Crearea si adaugarea unui nod in lista de noduri vii
newnode (nod,par,lev,t,cap,prof,cost);
// creaza un nod nou i si l adauga la lista de noduri vii
{
getnode(nod);
parent(nod)=par; level(nod)=lev; tag(nod)=t;
rw(nod)=cap; cp(nod)=prof; c*(nod)=cost;
add(nod)
}

Procedura BB-LC pentru problema 0/1 a rucsacului


LC_KnapSack(p,w,M,n,s)
// p(1,,n) -- profiturile
// w(1,,n) -- greuttile
// M -- capacitatea rucsacului
// obiectele sunt ordonate astfel nct p(i)/w(i) p(i+1)/w(i+1)
// E = E-nodul curent
// r = nodul raspuns cu u(r) minim ntre nodurile raspuns atinse
// least( ) -- functie ce returneaza nodul x cu c*(x) minim (profit estimat maxim), din lista de noduri vii

_______________________________________________________________________________

73

Proiectarea Algoritmilor
_____________________________________________________________________________________
{

Initializeaza lista de noduri vii


bound(p,w,M,0,n,1c*x,ux);
// calculeaza volorile initiale pentru c*x si ux
if (c*x = ux) return ("toate obiectele pot fi incarcate in ruscsac")
else
{
u=ux+;
getnode(e); parent(e) = 0; level(e) = l; rw(e) = M; cp(e)=0; c*(e)=c*x;
// creaza primul Enod = e
while ( (c*(e) < u) (mai exista noduri vii ) )
{
i = level(e); cap = rw(e); prof = cp(e);
// vezi daca fiul din stinga poate deveni viu
if (cap >= w(i) ) // c*(x)= c*(e) deci c*(x) < u
{
newnode(x,e,i+1,1,cap-w(i),prof+p(i), c*(e))
if (i=n) { u = [prof+p(i)]; r = x}; // nod raspuns : c*(x) = c(x) = [prof+p(i)];
else u=min(u,ux+);
};
// vezi daca fiul din dreapta poate deveni viu
bound(p,w,cap,prof,n,i+1,c*x,ux);
if ( c*x < u)
// fiul din dreapta devine viu
{
newnode(x,e,i+1,0,cap,prof,c*x);
if (i=n) { u = prof; r =x }; // nod raspuns : c*(x) = c*x = c(x) = prof
else u=min(u,ux+);
}
e = least(); // (e=nul nu mai exista noduri vii
} //end while
return(r)
}
}

74

_______________________________________________________________________________