Documente Academic
Documente Profesional
Documente Cultură
ANALIZA ALGORITMILOR
PRELIMINARII
Abu Ja`far Mohammed ibn Musa al-Khowarizmi (autor persan, sec.
VIII-IX), a scris o carte de matematic cunoscut n traducere latin c
Algorithmi de numero indorum, iar apoi c Liber algorithmi, unde
algorithm provine de la al-Khowarizmi, ceea ce literal nseamn din
oraul Khowarizm. n prezent, acest ora se numete Khiva i se afl n
Uzbechistan. Att al-Khowarizmi, ct i ali matematicieni din Evul Mediu,
nelegeau prin algoritm o regul pe baza creia se efectuau calcule
aritmetice. Astfel, n timpul lui Adam Riese (sec. XVI), algoritmii foloseau
la: dublri, njumtiri, nmuliri de numere. Ali algoritmi apar n lucrrile
lui Stifer (Arithmetica integra, Nrnberg, 1544) i Cardano (Ars magna
sive de reguli algebraicis, Nrnberg, 1545). Chiar i Leibniz vorbete de
algoritmi de nmulire. Termenul a rmas totui mult vreme cu o
ntrebuinare destul de restrns, chiar i n domeniul matematicii.
Kronecker (n 1886) i Dedekind (n 1888) semneaz actul de natere al
teoriei funciilor recursive. Conceptul de recursivitate devine indisolubil
legat de cel de algoritm. Dar abia n deceniile al treilea i al patrulea ale
secolului nostru, teoria recursivitii i algoritmilor ncepe s se constituie
ca atare, prin lucrrile lui Skolem, Ackermann, Sudan, Gdel, Church,
Kleene, Turing, Peter i alii.
1. ALGORITMI
Un algoritm const ntr-o procedur de calcul bine definit care, ntr-o
succesiune finit de pai, transform o mulime de valori (date de intrare)
ntr-o alt mulime de valori (date de ieire sau rezultatul prelucrrii).
Un algoritm constituie un mijloc de rezolvare a problemelor de calcul
bine definite. Un enun corect al unei astfel de probleme descrie, n termeni
generali, relaia intrare/ieire corespunztoare algoritmului problemei.
Conceptele de funcie calculabil i algoritm formeaz obiectele
principale de studiu n teoria calculabilitii. Ele apar n diferite domenii ale
informaticii i matematicii sub diverse grade de abstractizare.
Dezvoltarea unor tiine implic, printre altele, construirea unor
algoritmi care s rezolve o gam ct mai variat de probleme.
Noiunea de algoritm se ntlnete nc din clasele elementare relativ la
cele patru operaii fundamentale aplicate numerelor naturale reprezentate n
baza zece. Mai trziu, se studiaz algoritmul lui Euclid i algoritmi cu
privire la rezolvarea unei ecuaii, determinarea inversei unei matrice
nesingulare etc.
Exemplu 1.1:
S descriem un algoritm de nmulire a dou numere naturale x, y numit
nmulirea La Russe.
P1. Se consider un tablou bidimensional cu dou coloane. Pe prima
linie se afl x n prima coloan i y n a doua coloan.
P2. Numrul din prima coloan se mparte la 2 (mprire ntreag), iar
cel din a doua coloan se nmulete cu 2.
P3. Pasul P2 se repet pn cnd n prima coloan se obine numrul
natural 1.
P4. Se vor elimina liniile care conin n prima coloan un numr par.
P5. Se vor nsuma numerele naturale din coloana a doua care corespund
liniilor rmase.
Suma obinut reprezint produsul xy.
Fie numerele x = 245 i y = 37. Conform algoritmului descris se obine:
DENMULIT
NMULITOR
245
37
122**
74**
61
30**
15
7
3
1
xy
148
296**
592
1184
2368
4736
9065
Cazuri particulare:
a) n (algoritmul se execut n timp liniar);
b) nlog n (algoritmul se execut n timp liniar log);
c) n2 (algoritmul se execut n timp ptratic);
d) n3 (algoritmul se execut n timp cubic);
n! (algoritmul se execut n timp factorial);
kn (k > 1, constant) (algoritmul se execut n timp exponenial).
Exemplul 2.1.
S considerm un algoritm care efectueaz operaii de punere/extragere
a unei date de 32 bii efectuate pe o stiv cu elemente ntregi. Astfel de
operaii vor necesita un timp constant. Un algoritm care se execut ntr-un
timp constant mic se zice c este perfect.
Exemplul 2.2.
S presupunem un algoritm a crui intrare const dintr-un ir de n
caractere. El poate prelucra intrarea sa caracter cu caracter, solicitnd
acelai timp pentru fiecare astfel de caracter. n acest caz, f(n) = n. Un astfel
de algoritm care se execut n timp liniar se zice c este excelent.
Exemplul 2.3.
Un algoritm poate cicla direct intrarea sa format din numere ntregi sub
forma
f(n) = n + f(n - 1).
Iternd aceast relaie se obine f(n) = n + f(n - 1) = n + ((n-1) + f(n - 2))
=.....
= n + (n - 1) + (n - 2) + .... + 2 + f(1) = n2/2 + n/2 + k, unde k este o
constant. Pentru un n suficient de mare, k i n/2 sunt mici fa de n2. Un
astfel de algoritm se execut ntr-un timp ptratic.
Un algoritm care solicit o prelucrare a celor n2 perechi de caractere ce
corespund unei intrri care const dintr-un ir de n caractere, solicit tot un
timp ptratic de execuie.
Pentru intrri de dimensiuni mari algoritmii care se execut n timp
ptratic vor evolua mai lent.
Exemplul 2.4.
Un algoritm poate prelucra, la fiecare pas, jumtate din intrarea sa.
Aadar,
f(n) = f(n/2) + 1
(cu aproximare n cazul n care n nu este o putere natural a lui 2).
Fie n = 2x. Atunci, f(n) = f(2x) = 1 + f(2x-1) = 1 + (1 + f(2 x-2)) = ... = x +
0
f(2 ) = x + k, unde k este o constant.
10
n acest caz, f(2x) este aproximativ x, iar f(n) este aproximativ log2n. Un
astfel de algoritm se execut n timp log. Aceti algoritmi au o cretere
foarte lent i sunt foarte buni n practic.
Este foarte cunoscut algoritmul Divide et Impera folosit n Quicksort,
Mergesort etc. Pentru acest algoritm, f(n) = n + 2f(n/2).
Pentru n = 2x, folosind un mic artificiu, se obine:
f(2x)/2x = 2x/2x + 2*f(2x/2)/2x = 1 + f(2x-1)/2x-1 = 1 + (1 + f(2x-2)/2x-2) = ...=
x + f(20)/20 =
= x+k, unde k este o constant.
Rezult c f(2x) = 2x(x + k) = 2xx + tm. Prin urmare, f(n) = nlog2n + tm.
n concluzie, algoritmul respectiv se execut n timp liniar log.
Exemplul 2.5.
S presupunem c intrarea unui algoritm const ntr-o mulime de n
numere ntregi. Se cere s se gseasc o submulime a acestei mulimi cu
proprietatea c suma elementelor sale este nul.
Printr-o cercetare exhaustiv, n cazul cel mai defavorabil, se vor
verifica toate cele 2n submulimi posibile. Un astfel de algoritm se va
executa ntr-un timp exponenial.
Exemplul 2.6.
Un algoritm, prin care se cere obinerea tuturor anagramelor
corespunztoare unui cuvnt format din n caractere la intrare, se va executa
ntr-un timp factorial, pentru c exist n! astfel de posibiliti.
Funcia n! crete aproximativ cu aceeai vitez ca nn, dar mai repede
dect 2n.
n 1964, Cobham a introdus clasa P a problemelor rezolvabile
algoritmic n timp polinomial, adic o problem ce se rezolv printr-un
algoritm A care pentru orice numr natural n, funcia sa de complexitate
este mrginit superior de un polinom cunoscut p(n) n variabila n, adic
f(n) kp(n), unde k este o constant nenul. n aceast clas se ntlnesc aa
numitele probleme facile. Se mai spune despre un algoritm de
complexitate polinomial c reprezint rezultatul unei cunoateri detaliate a
problemei pe care o rezolv.
Despre un algoritm care nu este de complexitate polinomial se zice c
se comport exponenial. n aceeai clas a algoritmilor exponeniali
sunt ncadrai i algoritmii de complexitate nlog n dei nu corespund n
sensul strict matematic al noiunii respective. Avnd n vedere viteza de
cretere sau ordinul de cretere a timpului de execuie n raport cu n a
funciilor exponeniale fa de cele polinomiale, n general, algoritmii
exponeniali sunt inutilizabili n practic. Despre un algoritm de
11
12
3. COMPLEXITATE ASIMPTOTIC
O simpl caracterizare a eficienei unui algoritm const n viteza de
cretere a timpului su de execuie care ofer posibilitatea de a compara
performanele relative ale unor algoritmi alternativi.
n general, este destul de dificil de a determina expresia exact ce
definete timpul de execuie al unui algoritm n funcie de dimensiunea
problemei, de aceea se stabilesc anumite limite ntre care el poate varia.
Complexitatea se exprim n funcie de aceast dimensiune.
Cnd datele de intrare au dimensiuni suficient de mari, astfel nct
numai viteza de cretere a timpului de execuie s fie relevant, vom studia
eficiena asimptotic a algoritmilor. Mai exact, se va urmri viteza de
execuie a mai multor algoritmi cu acelai obiectiv, sau, altfel zis, viteza de
cretere a funciilor a cror expresie reprezint timpul de execuie a unor
astfel de algoritmi. n practic exist un interes deosebit asupra modului de
cretere a timpului de execuie a unui algoritm o dat cu creterea
dimensiunii datelor de intrare pn la cazul limit n care aceast
dimensiune crete la infinit. Se folosete, n acest sens, conceptul de timp
asimptotic de execuie a unui algoritm. Pentru exprimarea unui astfel de
timp se va folosi un limbaj riguros care cuprinde urmtoarele simboluri
asimptotice: , O , o , , . Se vor folosi funcii al cror domeniu de
definiie l reprezint mulimea numerelor naturale N. Notaia se poate
extinde, n unele situaii, la domeniul numerelor reale sau restrnge la o
submulime a mulimii numerelor naturale.
Fie mulimea funciilor nenegative care au ca domeniul de definiie
mulimea numerelor naturale N = {0, 1, 2, ....}.
Fie funciile f(n), g(n) f n , g n .
3.1. - notaia
Definiia 3.1.1. f (n) = (g(n)) (n ) dac exist constantele c1 > 0,
c2 > 0 i n0 N , astfel nct n n0 , 0 c1 g n f n c2 g n .
Notaia n indic, o dat n plus, faptul c relaia asimptotic are loc
pentru valori suficient de mari ale lui n. ntr-o scriere asimptotic, chiar
dac nu este prezent aceast notaie cu scopul de a simplifica scrierea, ea
este subneleas.
Din punct de vedere matematic este corect a folosi notaia
f n g n , pentru c g n f n /exist constantele c1 > 0, c2 >
0 i n0 N , astfel nct n n0 , 0 c1 g n f n c2 g n .
13
c2g(n)
f(n)
c1g(n)
n
n0
f(n) = (g(n))
n literatura de specialitate, se folosete, printr-un abuz de utilizare a
semnului de egalitate, notaia f (n) = (g(n)) (n ). Se accept ambele
notaii i pentru celelalte simboluri care vor urma. Se spune despre funciile
f(n) i g(n) c au aproape aceeai vitez de cretere avnd n vedere
constantele pozitive multiplicative c1, c2 sau c ele sunt funcii egale pn la
un factor constant. Vom spune c funcia g(n) constituie o margine
asimptotic tare sau strns (inferioar i superioar) pentru funcia f(n).
Din definiia mulimii (g(n)) se observ c este necesar ca elementele
sale s fie funcii nenegative pentru valori ale lui n suficient de mari. O
funcie asimptotic pozitiv este strict pozitiv pentru orice valoare a lui n
suficient de mare ( n n0 ).
n mod intuitiv, pe baza definiiei simbolului , ntr-o expresie
polinomial ce reprezint timpul de execuie a unui algoritm se ia n calcul
doar termenul dominant (de ordin maxim) i se neglijeaz toi termenii de
ordin inferior ct i coeficientul termenului dominant.
Fie f(n)= (3/7)n2- 4n. Pentru a arta c f(n)= (n2) trebuie s determinm
constantele pozitive n0, c1, c2 astfel nct
0 c1 n 2 3 n 2 4n c2 n 2 .
7
are loc inegalitatea 3
Pentru
4 c
7 n 2 , iar
3 4 c . n
inegalitatea
7 n 1
c1 1 , c2 3 i n0 = 10 astfel
35
7
n 1, c2 3
pentru
7 se observ c
n 1, c1 1 are loc
35
concluzie,
exist
constantele
14
g n f n / c 0, n0 N
astfel nct 0 f n g n , n n0 .
cg(n)
f(n)
n0
f(n) = (g(n))
15
0, n0 astfel nct
f n
l , n n0 . Adic
g n
f n
f n
l l
l .Alegnd
gn
g n
16
f n
l 1, n n0 . Exist dou constante pozitive
g n
n0 , n10 l 1 astfel nct n n0 , g n 0, 0 f n n10 * g n .
Aadar f(n) = O(g(n)).
Aceast condiie nu este i necesar. Justificai aceast afirmaie printrun contraexemplu.
f n cg n 0, n n0 .
f(n)
c(n)
n0
f(n) = (g(n))
n studiul algoritmilor, simbolul este util pentru a pune n eviden un
timp minim posibil de execuie. Aadar simbolul este util n precizarea
unei margini asimptotice inferioare nu neaprat tare.
Exerciiu 3.3.1:
Artai c f n g n g f n f n .
n practic se demonstreaz existena marginilor asimptotice tari
pornind de la margini asimptotice superioare i inferioare i nu invers.
3.4. o - notaia
17
3.4.2.
condiie
lim n f n 0 este ca f n 1
necesar
suficient
ca
3.5. - notaia
Definiia 3.5.1. f(n) = (g(n)) (n) dac c 0, n0 N astfel
nct nn0, are loc relaia f(n) > cg(n) 0. Simbolul se raporteaz la
ntr-un mod asemntor lui o fa de O. Aadar,
g n f n c 0, n0 N astfel ca f n cg n 0, n n0
Se observ c f(n) = (g(n)) dac i numai dac g(n) = o(f(n)).
Aadar desemneaz o margine asimptotic inferioar care nu este o
margine asimptotic inferioar tare.
Exemplul 3.5.1.
n2 = (n), iar n2 (n2).
Se observ c f(n) = (g(n)) implic lim n
exist).
3.6. ~ - notaia
Definiia 3.6.1.
f(n) ~ g(n)(n ) dac exist lim n
f n
(dac limita
g n
f n
1.
g n
18
lim n
f n g n lim f n 1
n
g n
g n
lim n
f n
1 0
g n
19
20
Exemplul 1.3.9.
n4 + 3n3 - 2 ~ n4
(1)
2
(5n + 1) ~ 25n2
(2)
6n 7n 1
3n 5
5
~ 2n2
(3)
4n + 8log n + 78 ~ 4n
(4)
sin 1/n ~ 1/n
(5)
n + sin n ~ n
(6)
5. RELAII RECURENTE
Cel mai important ctig al exprimrii recursive este faptul c ea este
natural i compact, fr s ascund esena algoritmului prin detaliile de
implementare. Pe de alt parte, apelurile recursive trebuie folosite cu
discernmnt, deoarece solicit i ele resursele calculatorului (timp i
memorie). Analiza unui algoritm recursiv implic rezolvarea unui sistem de
recurente. Vom vedea n continuare cum pot fi rezolvate astfel de recurente.
Cnd un algoritm conine o apelare recursiv la el nsui, timpul su de
execuie poate fi descris adesea printr-o recuren. O recuren este o
ecuaie sau o inegalitate care descrie ntregul timp de execuie al unei
probleme de dimensiune n cu ajutorul timpilor de execuie pentru date de
intrare de dimensiuni mici. Putem, apoi, folosi instrumente matematice
pentru a rezolva problema de recuren i pentru a obine margini ale
performanei algoritmului.
O recuren pentru timpul de execuie al unui algoritm de tipul divide
i stpnete se bazeaz pe cele trei etape definite n descrierea metodei. La
fel ca pn acum, vom nota cu T(n) timpul de execuie al unei probleme de
dimensiune n. Dac dimensiunea problemei este suficient de mic, de
exemplu n c pentru o anumit constant c, soluia direct ia un timp
constant de execuie, pe care l vom nota cu (1). S presupunem c
divizm problema n a subprobleme, fiecare dintre acestea avnd
dimensiunea de 1/b din dimensiunea problemei originale. Dac D(n) este
21
timpul necesar pentru a divide problema n suprobleme, iar C(n) este timpul
necesar pentru a combina soluiile subproblemelor n soluia problemei
originale, obinem recurena
nc
n ,
n
T n
aT
D n C n , n c
b
5.1 Metoda master
Metoda master furnizeaz o reet pentru rezolvarea recurenelor de
forma
T(n)= aT(n/b)+ f(n)
(5.1)
unde a 1 i b>1sunt constante, iar f(n) este o funcie asimptotic
pozitiv. Metoda master pretinde memorarea a trei cazuri, dar apoi soluia
multor recurene se poate determina destul de uor, de multe ori fr creion
i hrtie.
Recurena (1.4.1) descrie timpul de execuie al unui algoritm care
mparte o problem de dimensiune n n a subprobleme, fiecare de
dimensiune b/n, unde a i b sunt constante pozitive. Cele a subprobleme
sunt rezolvate recursiv, fiecare n timp T(n/b). Costul divizrii problemei i
al combinrii rezultatelor subproblemelor este descris de funcia f(n)
(Adic, utiliznd notaia f(n)=D(n) + C(n)).
Din punctul de vedere al
corectitudinii tehnice, recurena nu este, de fapt, bine definit, deoarece n/b
ar putea s nu fie ntreg. nlocuirea fiecruia dintre cei a termeni T(n/b) fie
cu T n b fie cu T n b nu afecteaz, totui, comportamentul
asimptotic al recurenei. n mod normal, ne va conveni, de aceea, s
omitem funciile parte ntreag inferioar i superioar cnd scriem
recurene divide i stpnete de aceast form.
Teorema master
Metoda master depinde de urmtoarea teorem.
Teorema 5.1.1. (teorema master) Fie a 1 i b>1 constante, fie f(n) o
funcie i fie T(n) definit pe ntregii nenegativi prin recuren
T(n)= aT(n/b) + f(n)
22
Dac
T n n
f n n log
a
b
log ba
2.
Dac
3.
Dac
a
b
log ba
T n n log
a
b
T n n log lg n f n lg n .
a
b
23
Exemplu 5.1.1.
T(n) = 9T(n/3) + n.
Pentru aceast recuren, avem a = 9, b = 3, f(n) = n i astfel nlog ba=
T(n)= nlog 39=(n2).
Deoarece f(n)= (nlog 39-), unde = 1, putem s aplicm cazul 1 al
teoremei master i s considerm c soluia este T(n)= (n2).
Exemplu 5.1.2.
T(n)=T(2n/3) + 1.
Pentru aceast recuren, avem a=1, b= 3/2, f(n)=1 i nlogba= nlog 3/21= n0
=1. Cazul 2 este cel care se aplic deoarece f(n)= (nlog ba)= (1) i astfel
soluia recurenei este
T(n)= (lg n).
Exemplu 5.1.3.
T(n) = 3T(n/4) + nlgn,
Pentru aceast recuren, avem a=3, b=4, f(n)= nlgn i nlogba=nlog34
=(n0,793). Deoarece f(n)=(nlog 43+), unde 0.2, cazul 3 se aplic dac
putem arta c pentru f(n) este verificat condiia de regularitate. Pentru n
suficient de mare,
af(n/b)=3(n/4)lg (n/4) (3/4)nlgn = cf(n) pentru c = 3/4.
n consecin, din cazul 3, soluia recurenei este T(n)= (nlgn).
Exemplu 5.1.4.
Metoda master nu se aplic recurenei
T(n)= 2T(n/2) + nlgn,
chiar dac are forma potrivit: a=2, b=2, f(n)= nlgn i nlogba = n. Se pare
c ar trebui s se aplice cazul 3, deoarece f(n)= nlgn este asimptotic mai
mare dect nlogba = n, dar nu polinomial mai mare. Raportul f(n)/nlogba =
(nlgn)/n este asimptotic mai mic dect n pentru orice constant pozitiv .
n consecin, recurena cade n golul dintre cazurile 2 i 3.
5.2. Metoda ecuaiilor caracteristice
5.2.1. Recurene liniare omogene
Exist tehnici care pot fi folosite aproape automat pentru a rezolva
anumite clase de recurene. Vom considera recurene liniare omogene, de
forma
24
t n ci rin
i 1
este o soluie a recurenei (5.2.1), unde constantele c1, c2, ..., ck sunt
determinate de condiiile iniiale. Este remarcabil c (1.4.2) are numai
soluii de aceasta form.
Exemplu 5.2.1.
Recurena care definete irul lui Fibonacci:
tn = tn-1 + tn-2 n 2
iar t0 = 0, t1 = 1. Putem s rescriem aceast recurena sub forma tn - tn-1 tn-2 = 0 care are ecuaia caracteristica x2 - x - 1 = 0 cu rdcinile r1,2 = (15
)/2. Soluia generala are forma
t n c1r1n c 2 r2n
t 1 5 rn rn
1
2 . Observam c r = = (1+5)/2, r = - -1 i
Deci, n
1
2
n
-n
obinem tn = 1/5( - (-) )
Putem s artm acum c timpul pentru algoritmul care determin irul
Fibonacci este n (n).
25
26
EXERCIII:
27
28
29
2 4 5
1 2
2 6
6
30
T ( n)
31
n 1
(1),
2T ( n / 2) ( n), n 1
T ( n)
Se poate arta c T(n) este (nlgn) unde lgn reprezint log2n. Pentru
numere suficient de mari, sortarea prin interclasare, are timpul de execuie
(nlgn).
2. TEHNICA GREEDY
Algoritmii greedy (greedy = lacom) sunt n general simpli i
sunt
folosii pentru rezolvarea problemelor de optimizare, cum ar fi: s se
gseasc cea mai bun ordine de executare a unor lucrri pe calculator, s
se gseasc cel mai scurt drum ntr-un graf etc. Algoritmii aplicai
problemelor de optimizare sunt compui dintr-o secven de pai, la fiecare
pas existnd mai multe alegeri posibile Un algoritm greedy va alege la
fiecare moment de timp soluia ce pare a fi cea mai bun la momentul
respectiv. Deci este vorba despre o alegere optim, fcut local, cu sperana
c ea va conduce la un optim global. Acest capitol trateaz probleme de
optimizare ce pot fi rezolvate cu ajutorul algoritmilor greedy.
Algoritmii greedy conduc n multe cazuri la soluii optime, dar nu
ntotdeauna.
2.1. O problem de selectare a activitilor
Primul exemplu pe care l vom considera este o problem de repartizare
a unei resurse mai multor activiti care concureaz pentru a obine resursa
respectiv. Vom vedea ca un algoritm de tip greedy reprezint o metod
simpl i elegant pentru selectarea unei mulimi maximale de activiti
mutual compatibile.
S presupunem c dispunem de o mulime S = 1,2,..., n de n activiti
care doresc sa foloseasc o aceeai resurs (de exemplu o sal de lectur).
Aceast resurs poate fi folosita de o singur activitate la un anumit
moment de timp. Fiecare activitate i are un timp de pornire si i un timp de
oprire fi, unde si fi . Dac este selecionat activitatea i, ea se desfoar
pe durata intervalului [si, fi). Spunem c activitile i i j sunt compatibile
dac intervalele [si, fi) i [sj, fj) nu se intersecteaz (adic i i j sunt
compatibile dac si fj sau sj fi). Problema selectrii activitilor const
din selectarea unei mulimi maximale de activiti mutual compatibile.
Un algoritm greedy pentru aceast problem este descris de urmtoarea
procedur, prezentat n pseudocod. Vom presupune c activitile (adic
datele de intrare) sunt ordonate cresctor dup timpul de terminare:
32
f1 f2 ... fn
(2.1)
n caz contrar aceast ordonare poate fi fcut n timp O(nlgn).
Algoritmul de mai jos presupune c datele de intrare s i f sunt reprezentate
ca vectori.
SELECTOR-ACTIVITI-GREEDY (s, f)
1: n lungime[s]
2: A {1}
3: j 1
4: for i 2 to n do
5:
if si fj then
6:
A A U {i}
7:
ji
8: returneaz A
Operaiile realizate de algoritm pot fi vizualizate n figura 2.1. n
mulimea A se introduc activitile selectate. Variabila j identific ultima
activitate introdus n A. Deoarece activitile sunt considerate n ordinea
nedescresctoare a timpilor lor de terminare, fj, va reprezenta ntotdeauna
timpul maxim de terminare a oricrei activiti din A. Aceasta nseamn c
fj = max{fk : A}
(2.2)
n liniile 2-3 din algoritm se selecteaz activitatea 1, se iniializeaz A
astfel nct s nu conin dect aceast activitate, iar variabila j ia ca
valoare aceast activitate. n continuare liniile 4-7 consider pe rnd fiecare
activitate i i o adaug mulimii A dac este compatibil cu toate celelalte
activiti deja selectate. Pentru a vedea dac activitatea i este compatibil
cu toate celelalte activiti existente la momentul curent n A, este suficient,
conform formulei (2.2), s fie ndeplinit condiia din linia 5 adic
momentul de pornire si, s nu fie mai devreme dect momentul de oprire fj,
al activitii cel mai recent adugate mulimii A. Dac activitatea i este
compatibil, atunci n liniile 6-7 ea este adugat mulimii A, iar variabila j
este actualizat. Procedura SELECTOR-ACTIVITI-GREEDY este
foarte eficient. Ea poate planifica o mulime S de n activiti n (n),
presupunnd c activitile au fost deja ordonate dup timpul lor de
terminare. Activitatea aleas de procedura SELECTOR-ACTIVITIGREEDY este ntotdeauna cea cu primul timp de terminare care poate fi
planificat legal. Activitatea astfel selectat este o alegere "greedy"
(lacom) n sensul c, intuitiv, ea las posibilitatea celorlalte activiti
33
2
1
3
1
4
1
5
1
9
2
1
3
1
4
8
4
9
8
10
8
11
11
timp
10 11 12 13 14
Figura 2.1. Operaiile algoritmului SELECTOR-ACTIVITIGREEDY asupra celor 11 activiti date n stnga. Fiecare linie a figurii
corespunde unei iteraii din ciclul pentru din liniile 4-7. Activitile care au
fost selectate pentru a fi incluse n mulimea A sunt haurate, iar activitatea
curent i este nehaurat. Dac timpul de pornire si, al activitii i este mai
34
mic dect timpul de terminare al activitii j (sgeata dintre ele este spre
stnga), activitatea este ignorat, n caz contrar (sgeata este ndreptat spre
dreapta), activitatea este acceptat i este adugat mulimii A.
2.1.1. Demonstrarea corectitudinii algoritmului greedy
Algoritmii de tip greedy nu furnizeaz ntotdeauna soluiile optime. Cu
toate
acestea,
algoritmul
SELECTOR-ACTIVITI-GREEDY
determin ntotdeauna o soluie optim pentru o instan a problemei
selectrii activitilor.
Teorema 2.1. Algoritmul SELECTOR-ACTIVITI-GREEDY
furnizeaz soluii de dimensiune maxim pentru problema selectrii
activitilor.
Demonstraie. Fie S = {1,2,..., n} mulimea activitilor care trebuie
planificate. Deoarece presupunem c activitile sunt ordonate dup timpul
de terminare, activitatea 1 se va termina cel mai devreme. Vrem s artm
c exist o soluie optim care ncepe cu activitatea 1, conform unei alegeri
greedy.
S presupunem c A S este o soluie optim pentru o instan dat a
problemei selectrii activitilor. Vom ordona activitile din A dup timpul
de terminare. Mai presupunem c prima activitate din A este activitatea k.
Dac k = 1, planificarea mulimii A ncepe cu o alegere greedy. Dac k 1
vrem s artm c exist o alt soluie optim B a lui S care ncepe conform
alegerii greedy, cu activitatea l. Fie B =A - {k} U {l}. Deoarece f1 fk,
activitile din B sunt distincte, i cum B are acelai numr de activiti ca
i A, B este de asemenea optim. Deci B este o soluie optim pentru S, care
conine alegerea greedy a activitii 1. Am artat astfel c exist
ntotdeauna o planificare optim care ncepe cu o alegere greedy.
Mai mult, o dat ce este fcut alegerea greedy a activitii 1, problema
se reduce la determinarea soluiei optime pentru problema selectrii acelor
activiti din S care sunt compatibile cu activitatea 1. Aceasta nseamn c
dac A este o soluie optim pentru problema iniial, atunci A' = A -{1}
este o soluie optim pentru problema selectrii activitilor
S' = {i S, si f1}. De ce? Dac am putea gsi o soluie B' pentru S' cu
mai multe activiti dect A', adugarea activitii 1 la B' va conduce la o
soluie B a lui S cu mai multe activiti dect A, contrazicndu-se astfel
optimalitatea mulimii A. n acest mod, dup ce este fcut fiecare alegere
greedy, ceea ce rmne este o problem de optimizare de aceeai form ca
35
Frecvena(n mii)
Cuvnt codificat; lungime fix
Cuvnt codificat; lungime
variabil
a
4
13
12
16
0
00
001
010
011
101
100
111
36
100
86
140
58
0
a:45
b:13
0
c:12
1
55
a:45
0
28
140
1
d:16
25
e:9
f:5
0
c:12
30
b:13
(a)
(b)
d:16
14
0
f:5
1
e:9
37
B (T ) f (c) dT (c)
cC
38
39
cC
40
f:5
e:9
(b)
14
c:12 b:13
0
f:5
(c)
14
0
f:5
25
d:16
1
a:45
e:9
(d)
c:12 b:13
e:9
25
0
d:16 a:
1
30
1
c:12 b:13
d:16
14
0
a:45
1
f:5
e:9
55
a:45
0
25
(e)
0
0
30
c:12 b:13
f:5
a:45
55
1
d:16
14
0
(f)
1
e:9
25
0
30
c:12 b:13
d:
14
0
f:5
41
1
e:9
B (T ) B (T ) f [ x] f [ y ].
42
astfel nct B(T") < B(T'). Cum z este tratat ca un caracter n C', el va apare
ca frunz n T". Dac adugm x i y ca fiind fiii lui z in T", atunci vom
obine o codificare prefix pentru C avnd costul B(T") + f[x + f[y] < B(T),
ceea ce intr n contradicie cu optimalitatea lui T. Deci T' trebuie s fie
optim pentru alfabetul C'.
T/
T
x
y
T//
@
'
b
y
x
y 2.5 O ilustrare a pasului cheie
x
cdin demonstraia lemei 2.1. n
Figura
x
y
arborele optim T, b i c sunt dou dintre frunzele aflate pe cel mai de jos
nivel n arbore; aceste noduri se consider frai. x i y sunt dou frunze pe
care algoritmul Huffman le interclaseaz primele; ele apar n poziii
arbitrare n T. Frunzele b i x sunt interschimbate pentru a obine arborele
T'. Apoi, frunzele c i y sunt interschimbate pentru a obine arborele T".
Cum cele dou interschimbri nu mresc costul, arborele rezultat T" este de
asemenea un arbore optim.
43
44
45
Pasul
Muchia
considerata
iniializare
1
{1, 2}
2
{2, 3}
3
{4, 5}
4
{6, 7}
5
{1, 4}
6
{2, 5}
7
{4, 7}
Componentele
conexe
subgrafului <V, A>
{1}, {2}, {3}, {4}, {5}, {6}, {7}
{1, 2}, {3}, {4}, {5}, {6}, {7}
{1, 2, 3}, {4}, {5}, {6}, {7}
{1, 2, 3}, {4, 5}, {6}, {7}
{1, 2, 3}, {4, 5}, {6, 7}
{1, 2, 3, 4, 5}, {6, 7}
respinsa (formeaz ciclu)
{1, 2, 3, 4, 5, 6, 7}
Figura 2.7 Algoritmul lui Kruskal aplicat grafului din Figura 2.6(a)
Mulimea A este iniial vida i se completeaz pe parcurs cu muchii
acceptate (care nu formeaz un ciclu cu muchiile deja existente in A). In
final, mulimea A va conine muchiile {1, 2}, {2, 3}, {4, 5}, {6, 7}, {1, 4},
{4, 7}. La fiecare pas, graful parial <V, A> formeaz o pdure de
componente conexe, obinut din pdurea precedenta unind dou
componente. Fiecare component conex este la rndul ei un arbore parial
de cost minim pentru vrfurile pe care le conecteaz. Iniial, fiecare vrf
formeaz o componenta conexa. La sfrit, vom avea o singur component
conex, care este arborele parial de cost minim cutat (Figura 2.6(b)).
Ceea ce am observat n acest caz particular este valabil i pentru cazul
general, din Proprietatea 2.1 rezultnd:
Proprietatea 2.2 n algoritmul lui Kruskal, la fiecare pas, graful parial
<V, A> formeaz o pdure de componente conexe, n care fiecare
component conex este la rndul ei un arbore parial de cost minim pentru
vrfurile pe care le conecteaz. In final, se obine arborele parial de cost
minim al grafului G.
Pentru a implementa algoritmul, trebuie s putem manipula submulimile
formate din vrfurile componentelor conexe. Folosim pentru aceasta o
structur de mulimi disjuncte si procedurile de tip find si merge (Vezi
disciplina Structuri de date i algoritmi). In acest caz, este preferabil s
reprezentam graful ca o list de muchii cu costul asociat lor, astfel nct s
putem ordona aceast list n funcie de cost. Iat algoritmul:
46
ale
47
48
Pasul
iniializare
1
2
3
4
5
6
Muchia considerata
{2, 1}
{3, 2}
{4, 1}
{5, 4}
{7, 4}
{6, 7}
U
{1}
{1, 2}
{1, 2, 3}
{1, 2, 3, 4}
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5, 6, 7}
Tabelul 5.2 Algoritmul lui Prim aplicat grafului din Figura 6.4a.
Proprietatea 5.4 In algoritmul lui Prim, la fiecare pas, <U, A> formeaz
un arbore parial de cost minim pentru subgraful <U, A> al lui G. In final,
se obine arborele parial de cost minim al grafului G.
Descrierea formala a algoritmului este data in continuare.
function Prim-formal(G = <V, M>)
{iniializare}
A {va conine muchiile arborelui parial de cost minim}
U {un vrf oarecare din V}
{bucla greedy}
while U V do
49
50
51
(6.1)
(A1((A2A3)A4),
((A1A2)(A3A4)),
((A1(A2A3))A4),
52
dac n 1,
P ( n)
n 1
P (k ) P(n k )
dac n 2.
k 1
C ( n)
1 2n
n
3/ 2
(4 / n )
n 1 n
53
54
0
min m i, k m k 1, j pi 1 p k p j
m i , j
i j
i j
(6.2)
n
2
2
satisfac 1 i j n, adic un total de + n= (n ) . Un algoritm
55
56
m
6
5
3
2
15,125
11,875 10,500
9,375
7,875
7,125
4,375
15,750 2,625
5,375
2,500
750
3,500
1,000
5,000
A1
A2
A3
A4
A5
A6
3
3
1
1
1
3
3
3
3
2
2
3
3
3
4
5
4
5
5
matrice
A1
A2
A3
A4
A5
A6
dimensiuni
30x35
35x15
15x5
5x10
10x20
20x25
57
valoare m[i,j] este calculat pe baza folosirii produselor pi-1pkpj pentru k=i,
i+1,... ,j 1 i a tuturor valorilor aflate pe direcia sud-est i sud-vest fa de
m[i,j.
O simpl examinare a structurii de ciclu imbricat din ORDINE-IRMATRICE conduce la constatarea c timpul de execuie a algoritmului este
O(n3). n fiecare dintre cele trei cicluri imbricate, indicii acestora (l, i i k)
iau cel mult n valori.
6.1.5. Construirea unei soluii optime
Dei algoritmul ORDINE-IR-MATRICE determin numrul optim de
nmuliri se necesare pentru calculul produsului irului de matrice, acesta
nu prezint n mod direct, trebuie fcut nmulirea. Pasul 4 al schemei
generale a metodei programrii dinamice urmeaz construirea unei soluii
optime din informaia disponibil.
n acest caz particular, vom folosi tabloul s[1..n,1..n] pentru a determina
modul optim de nmulire a matricelor. Fiecare element s[i,j] conine
valoarea lui k pentru care parantezarea optim a produsului AiAi+1...Aj
mparte produsul ntre Ak i Ak+1. Atunci tim c, n produsul final de calcul
al matricei A1..n, optimul este A1..s1,n As1,n+1..n. nmulirile anterioare
determinate recursiv, deoarece s1,s1,n determin ultima nmulire
matriceal din calculul lui A1..s1,n i s[s[1,n]+1,n determin ultima
nmulire matriceal din calculul lui As1,n - .Urmtoarea procedur recursiv
calculeaz produsul irului de matrice Ai..j, fiind date matricea A = (A1,A2,
...., An), tabloul s calculat de ORDINE-IR-MATRICE i indicii i i j. Apelul
este NMULIRE-IR-MATRICE (A,s,1,n).
(A,s,1,n)
if j > i then
X NMULIRE-IR-MATRICE (A, s, i, si,j)
Y NMULIRE-IR-MATRICE (A, s, si,j+1, j)
return NMULIRE-IR-MATRICE (X,Y)
else
return Ai
NMULIRE-IR-MATRICE
1:
2:
3:
4:
5:
6:
58
59
60
61
xm = yn. Prefixul Zk-1 este un subir comun de lungime k 1 pentru Xm-1 i Yn1. Dorim s demonstrm c este un CMLSC. S presupunem, prin absurd.
c exist un subir W comun pentru Xm-1 i Yn-1, a crui lungime este fie mai
mare dect k 1. Atunci, adugnd la W elementul xm = yn se va forma un
subir comun a lui X i Y a crui lungime este mai mare dect k, ceea ce
este o contradicie.
(2) Dac zk xm , atunci Z este un subir comun pentru Xm-1 i Y . Dac ar
exista un subir comun W al lui Xm-1 i Y , cu lungime mai mare dect k,
atunci W ar fi i un subir comun al lui Xm i Y, contrazicnd presupunerea
c Z este un CMLSC pentru X i Y.
(3) Demonstraia este simetric celei de la (2).
Caracterizarea din teorema 6.1 arat c un CMLSC al dou iruri
conine un CMLSC pentru prefixele celor dou iruri. Atunci, problema
CMLSC are proprietatea de substructur optimal. O soluie recursiv are,
de asemenea, proprietatea de suprapunere a problemelor, dup cum vom
arta n cele ce urmeaz.
6.3.2. O soluie recursiv a subproblemelor
Teorema 6.1 implic faptul c exist fie una, fie dou probleme care
trebuie examinate pentru gsirea unui CMLSC pentru X = (x1x2,... ,xm) i Y
= (y1,y2,...,yn). Dac xm = yn , trebuie gsit un CMLSC pentru Xm-1 i Yn-1.
Adugarea elementului xm = yn la acest CMLSC produce un CMLSC pentru
X i Y. Dac xm yn , atunci trebuie rezolvate dou subprobleme: gsirea
unui CMLSC pentru Xm-1 i Y i gsirea unui CMLSC pentru X i Yn-1. Cel
mai lung CMLSC dintre acestea dou va fi CMLSC pentru X i Y.
Se poate observa c problema CMLSC se descompune n subprobleme
suprapuse. Pentru a gsi un CMLSC al irurilor X i Y, va trebui, probabil,
calculat CMLSC pentru X i i Yn-1 respectiv, pentru Xm-1 i Y . Dar fiecare
dintre aceste subprobleme conine sub-subproblema gsirii CMLSC pentru
Xm-1 i Yn-1. Multe alte subprobleme au n comun sub-subprobleme.
Ca i problema nmulirii irului de matrice, soluia recursiv pentru
problema CMLSC implic stabilirea unei recurene pentru costul unei
soluii optime. S definim c[i,j ca lungimea unui CMLSC al irurilor Xi, i
Yj. Dac i=0 sau j=0, CMLSC are lungimea 0. Substructura optimal a
problemei CMLSC produce formula recursiv
i 0, j 0,
0,
c i, j c i 1, j 1 1,
i, j 0 and xi y j ,
max c i 1, c i 1, j , i, j 0 and xi y j .
(6.2)
62
63
64
j
i
0
y
1
B
2
D
3
C
4
A
5
B
6
A
x
i
A 0
B 0
C 0
B 0
D 0
A 0
xij zj
B 0
v3v6 vvi j
0
1
0
1
1
^
1
2
2
3
2
3
1
^
0
1
3
^
1
^
65
66