Documente Academic
Documente Profesional
Documente Cultură
Tehnica Greedy
Tehnica Greedy
Prezentare
Un algoritm greedy va funciona asemntor modului de gndire al unui om lacom: va consuma
elemente dintr-o anumit secven, de fiecare dat lund acel element, ce se potrivete cel mai bine cu
un anumit criteriu, fr a privi n perspectiv. Dei prima impresie ar fi c aceast abordare este una
greit, datorit conotaiei cuvntului lacom, totui uneori algoritmii de acest tip pot duce la soluii
simple i eficiente.
Un algoritm greedy este potrivit atunci cnd trebuie s lum o serie de decizii, i anume pe cea
mai convenient la un moment dat. Aceast alegere este un optim local, iar sperana este ca, ntr-un
final s fie obinut soluia global, ns nu se ntmpl aa ntotdeauna. Pentru un algoritm dat, va
trebui s determinm dac soluia este sau nu optim.
n cele mai multe situaii avem:
-
O funcie care verific dac o mulime de candidai constituie o soluie posibil, nu neaprat
optim, a problemei
O funcie care verific dac o mulime de candidai este fezabil, adic dac este posibil s
completm aceast mulime astfel nct s obineam o soluie posibil (nu neaprat
optim).
O funcie de selecie ce indic ntr-un anumit moment care este cel mai potrivit dintre
candidaii nefolosii.
O funcie obiectiv care d valoarea unei soluii (timpul necesar executrii tuturor lucrrilor
ntr-o anumit ordine), lungimea drumului pe care l-am gsit etc).
Iat un exemplu simplu ce ilustreaz tehnica greedy. Atunci cnd facem cumprturi, i
efectum plata, nu dorim s primim rest foarte mrunt. Soluia pentru a gsi cea mai bun
soluie la plata restului ( n monede ) permite reformularea problemei, conform celor
afirmate mai sus. Iat elementele problemei:
Funcia ce verific soluia posibil: valoarea total a unei astfel de mulimi s fie exact
valoarea ce trebuie returnat ca rest.
O mulime fezabil: valoarea total a unei astfel de mulimi nu este mai mare dect suma
de returnat ca rest.
Funcia de selecie: se alege cea mai mare moned din mulimea de candidai. Motivul este
acela c dorim s pltim folosind ct mai puine monede.
Evident soluia optim se poate gsi ncercnd toate combinrile posibile de monede, i
abordarea se mai numete brute force. Acest lucru necesit foarte mult timp. Din cele deduse mai sus
rezult urmtorul algoritm formulat ntr-un limbaj descriptiv:
(
1.
2.
3.
4.
5.
6.
7.
8.
Iat un mic exemplu pentru a demonstra acest algoritm. Se d suma de returnat 36. Se va prelua
o moned de 25 de uniti, se verific s fie mai mic sau egal cu 36 i este, ceea ce duce la adugarea
ei n soluia provizorie. Apoi se ncearc adugarea unei monede de 25, ceea ce va depi suma de 36
deci moneda va fi respins. Apoi se va ncerca adugarea unei monede de 5, suma devine 30, apoi nc o
moned de 5, suma devine 35 i ncercarea adugrii nc unei monede de 5 eueaz. Apoi se ncearc
adugarea unei monede de 1 i suma este atins. Algoritmul se ncheie.
Pe de alt parte dac am introduce monezi de 18 sau de 12 algoritmul va gsi un numr mai
mare dect 2 monede de 18 sau 3 de 12, ceea ce dovedete c atingerea numrului optim de monede
nu este ndeplinit n toate cazurile, deci algoritmul nu funcioneaz pentru orice caz.
Pornind de la problema de mai sus, i mai exact de la paii folosii pentru a rezolva algoritmul,
putem generaliza rezolvarea problemei astfel:
1.
2.
3.
( )
4.
5.
6.
7.
8.
( )
( { })
"
care minimalizeaz
\{ }
( )
( )
{ }
"
Este de neles acum de ce un astfel de algoritm se numete lacom: la fiecare pas, procedura
alege cel mai bun candidat la momentul respectiv, fr s i pese de viitor i fr a se rzgndi (a reveni
asupra deciziei). Dac un candidat este inclus n soluie el va rmne acolo. Dac n schimb, acel
candidat este exclus, el nu va mai putea niciodat fi reconsiderat.
Asemenea unui ntreprinztor rudimentar, care urmrete ctigul imediat, n dauna celui din
perspectiv, un algoritm greedy acioneaz simplist. Totui, ca i n afaceri, o astfel de metod se
dovedete util, tocmai datorit simplitii ei.
Funcia
este de obicei derivat din funcia obiectiv, uneori aceste funcii sunt identice.
S presupunem c exist trei sarcini care trebuie ndeplinite i timpii pentru le a ndeplini sunt:
= 5,
= 10
=4
Unitile de timp nu sunt relevante. Dac ordonm cronologic cele trei sarcini obinem urmtoarea
secvene de aciuni:
Sarcin
Timp n sistem
1
2
3
5(timp de servire)
5(timp ateptare dup 1) + 10(timp de servire)
5(timp ateptare dup 1) + 10(timp de ateptare dup 2) +4(timp de servire)
Aceeai metod de calcul va duce la urmtoarele posibiliti de a servi cele trei cereri:
Mod de a servi
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
5+(5+10)+(5+10+4) = 39
5+(5+4)+(5+4+10) = 33
10+(10+5)+(10+5+4) = 44
10+(10+4)+(10+4+5) = 43
4+(4+5)+(4+5+10) = 32
4+(4+10)+(4+10+5) = 37
Se observ c cel mai bun mod de a servi cererile este [3, 1, 2] cu un timp total de 32.
Exist clar un algoritm care poate verifica toate permutrile posibile. Ordinul de timp al acestui algoritm
este ns factorial. Aceast soluie, numit i brute force poate fi nlocuit cu un algoritm de tip greedy
mult mai simplist i mai eficient. Se observ c soluia cea mai bun conine timpii sortai cresctor.
Intuitiv, un algoritm pe care l dezvoltm va ncerca s serveasc sarcina care dureaz cel mai puin:
1.
2.
3.
4.
5.
)
)
Evident c algoritmul poate fi adaptat dup sensul problemei, i n cazul de fa putem nlocui pasul 3 cu
adugarea timpului sarcinii urmtoare la timpul total.
Complexitatea acestui algoritm este : ( log ).
4
Teorema 4.1
Singurul mod de a aranja astfel ca timpul total s fie minim, este acela n care sarcinile sunt ordonate
cresctor dup timpul de servire.
Demonstraie
Pentru 1
1 fie
total este minim. Va trebui s art, c este necesar ca sarcinile s fie ordonate dup timpul lor de
execuie. Vom demonstra acest lucru prin reducere la absurd. Dac nu sunt ordonate dup timpul lor de
execuie, atunci exist una i anume unde 1
1, pentru care
>
Putem rearanja ordinea iniial, interschimbnd aceste sarcini i anume cu + 1. Realiznd aceasta,
am luat
uniti de timp din sarcina + 1, care anterior erau calculate pentru timpul acesteia. Motivul
pentru acelai motiv. Totui timpul total din sistem nu se modific. Dac
atunci
=
Deoarece
>
putem spune c
<
Se poate deduce cum generalizm algoritmul pentru ca acesta s trateze o problem de programare
multi-server. Fie m servere. S se ordoneze aceste servere arbitrar. S se ordoneze sarcinile dup timp,
n ordine cresctoare. Fie ca primul server s deserveasc prima sarcin, cu cel mai mic timp, i al m-lea
server s deserveasc a m-a sarcin. Primul server va termina la un moment dat, primul, deoarece are si
cel mai mic timp de executat. Apoi primul server va deservi a (m+1) sarcin. Apoi al doilea server va
efectua a (m+2) sarcin. Schema de servire are loc dup cum urmeaz:
1
1, (1 +
, (1 +
), (2 +
2, (2 +
), (
,( +
,(
+
+
), (1 + 2 ),
), (2 + 2 ),
), ( + 2 ),
), (
+ 2 ),
), (1 + 2 ),
n aceast problem de programare, fiecare sarcin va avea nevoie de o unitate de timp pentru
a termina i are un termen limit i un profit. Adic, dac operaia ncepe mai devreme de termenul
limit, se obine un profit. Scopul este de a programa operaia ca profitul s fie maxim. Nu toate
sarcinile trebuie s fie executate. Iat un exemplu pentru a ilustra mai bine problema:
Fie urmtoarele sarcini, timpi limit, profituri:
Sarcin
1
2
3
4
Timp limit
2
1
2
1
Profit
30
35
25
40
Atunci cnd spunem c o sarcin 1 are un termen limit de 2, nseamn c sarcina 1 poate
ncepe la timpul 1 sau timpul 2. Nu exist timp 0. Deoarece sarcina 2 are timpul limit 1, aceast sarcin
poate porni doar la timpul 1. Iat posibilele profituri.
Programare
[1, 3]
[2, 1]
[2, 3]
[3, 1]
[4, 1]
[4, 3]
Profit total
30+25 = 55
35+30 = 65
35+25 = 60
25+30 = 55
40+30 = 70
40+25 = 65
Alte programri imposibile (de exemplu [1,2]), nu au mai fost listate. Pe de alt parte,
programri ca [1,3] sunt posibile, deoarece sarcina 1 a pornit naintea termenului limit, iar sarcina 3, a
pornit exact la termenul limit. Se poate vedea c programarea [1,4] este optim i are cel mai mare
profit. Se poate modifica algoritmul de mai sus pentru a obine un algoritm mai bun dect cel de ordin
factorial pentru a rezolva aceast problem.
interclasarea lor, irul ordonat cresctor ce conine elementele din ambele iruri. Dac interclasarea are
loc prin deplasarea elementelor din cele dou iruri, atunci evident numrul deplasrilor este #
# .
iruri
,,
unde fiecare ir
lui
,1
interclasri succesive de cte dou iruri. Problema const n determinarea ordinii optime n care
trebuie efectuare aceste interclasri, astfel ca numrul total de deplasri s fie minim. Exemplul de mai
jos ne arat c problema nu este una banal.
Fie irurile
, 3 de lungimi
rezultatul l interclasm cu
Dac interclasm pe
cu
= 30,
= 20,
cu
, iar
cu
, atunci
Atam fiecrei strategii de interclasare un arbore binar n care valoarea fiecrui vrf este dat
de lungimea irului pe care l reprezint.
De exemplu, dac irurile
50,
,,
au lungimile
= 30,
= 10,
= 20,
= 30,
= 10, dou dintre strategiile de interclasare sunt reprezentai prin arborii din figura de mai jos:
Observm c fiecare arbore are 6 vrfuri terminale, corespunznd celor 6 iruri iniiale i 5 vrfuri
neterminale, adic cele 5 interclasri care definesc strategia. Numerotm vrfurile astfel: vrful terminal
i, 1 6 va corespunde irului
Strategia greedy apare n figura 1b, i const n a interclasa mereu cele mai scurte iruri
disponibile la momentul curent.
Interclasnd irurile
cte un arbore binar cu
numerotate de la
ponderat ca fiind
unde,
,,
de lungimile
,,
1 vrfuri neterminale,
strategia corespunztoare lui A este chiar ( ). Soluia optim este deci arborele pentru care lungimea
Proprietatea 1
Prin metoda greedy se obine ntotdeauna interclasarea optim a
iruri ordonate.
Demonstraie
Demonstrm prin inducie. Pentru
adevrat pentru
1 iruri. Fie
. Fie
iruri de lungime
iruri. n subarborele
apare arborele
reprezentnd prima interclasare fcut conform strategiei greedy. n arborele , fie un vrf neterminal,
de adncime maxim. Ceio doi fii ai acestui nod, sunt
interschimbnd vrfurile
cu
respectiv,
cu
. Fie
. Evident c ( ) ( ). Deoarece
obinem un arbore
cu
1 vrfuri terminale
ponderat minim i ( ) = (
)+(
,,
). Rezult c i
9
. Arborele
vrfurile
are
,
) = ( ) unde
a irurilor de lungime
. Cum
,,
se obine din
atand nodului
, fii
, iar
La scrierea algoritmului care genereaz arborele strategiei greedy de interclasare, vom folosi un
min-heap. Fiecare element al min-heap-ului este o pereche ( , ) unde este numrul unui vrf din
Algoritmul interopt va construi arborele strategiei greedy. Un vrf al arborelui va fi memorat n trei
locaii diferite coninnd:
[ ] = lungimea irului reprezentat de vrf
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
( [ ], )
[ ] [ ]
[]=
,1
[]0
[ ]0
+1
( , )
( , )
[]
2 1
[]
[] +
10
:01
:11
acest caracter folosind 0. Totodat, nu mai poate fi codificat ca 00, deoarece nu mai putem distinge
ntre un
i doi de succesivi. Dac am codifica pe cu 01, apare confuzia interpretrii: primul 0 este
un nceput de
:0
:11
Dat fiind aceast codificare, irul de mai sus poate fi reprezentat ca:
1001001100011
11
Un tip aparte de coduri variabile ca lungime este codul prefixat. ntr-u cod prefixat, nici un cuvnt
codificat pentru un caracter are voie s constituie nceputul unui cuvnt codificat al altui caracter. De
exemplu, dac 01 este cuvntul codificat pentru
Codul de 13 bii de mai sus este un astfel de exemplu. Fiecare cod prefixat poate fi reprezentat ca un
arbore binar a cror frunze sunt caracterele ce trebuie codificate. Arborele binar corespunztor codului
de mai sus este:
:0
:11
indicat n tabelul de mai jos. Acest tabel prezint diferena ntre diversele coduri folosite.
Caracter Frecven C1(Lungime fix) C2 (o codificare)
C3(Huffman)
a
16
000
10
00
b
5
001
11110
1110
c
12
010
1110
110
d
17
011
110
01
e
10
100
11111
1111
f
25
101
0
10
Se poate calcula numrul de bii folosii pentru a codifica acest fiier:
( 1) = 16(3) + 5(3) + 12(3) + 17(3) + 10(3) + 25(3) = 255
Se poate observa c 2 aduce o mbuntire, dar Huffman este mai bun dect acesta. n figura 4 mai
jos, avem reprezentrile arborilor ce conin codificrile 2 i 3.
De aici se poate deduce urmtoarea formul de calcul a numrului de bii necesari reprezentrii acestor
caractere, dat fiind un arbore binar
Unde
( )=
( )
13
( )
este o mulime de
O coad de prioriti, , construit pe , este folosit pentru a identifica cele dou mai puin
frecvente obiecte pentru a le compune. Rezultatul compunerii celor dou obiecte este un nou obiect a
crei frecven este suma frecvenelor celor 2 obiecte.
1.
2.
3.
4.
5.
6.
7.
8.
( )
| |
1
[ ]
()
[ ]
[ ] [ ]+ [ ]
( , )
9.
( )
( )
( )
Caractere a b c d e f
Frecvene 45 13 12 16 9 5
Pentru exemplul nostru algoritmul va funciona astfel. Din moment ce sunt 6 litere, mrimea iniial a
cozii i a mulimii va fi =6, vor fi necesari 5 pai de combinare a frecvenelor. Cuvntul codificat pentru
o liter este secvena de etichete de pe muchii parcurs de la rdcin la liter.
Linia 2 iniializeaz coada de prioriti
extragerea ultimelor noduri din heap-ul , ultimele avnd cele mai mici frecvene, i va insera un nou
nod ( ) ce are ca valoare suma frecvenelor lor. Nodul are pe drept copil stnga iar pe
drept copil
dreapta. Dup 1 operaii de acest fel, obinem un singur nod n , rdcina arborelui ce conine codul,
iar acest nod este returnat la linia 9.
14
de
este implementat ca un
heap necesit un timp (log( )), deci bucla va produce un timp ( log( )). De aceea acesta va fi timpul