Sunteți pe pagina 1din 13

Algoritmi si structuri de date

Curs 12

Metode si tehnici de programare


Metoda Greedy
Metoda Greedy (greedy = lacom) se aplica, n general, pentru rezolvarea problemelor n care se
cere sa se determine o submultime B a unei multimi A cu n elemente, cu respectarea anumitor
restrictii specifice problemei. B se numeste solutie posibila. Se cere apoi sa se determine o
solutie posibila care sa optimizeze (maximizeze sau minimizeze) o anumita functie obiectiv data.
Aceasta solutie se numeste solutie optima.
Metoda Greedy furnizeaza o modalitate de rezolvare a problemelor de optim n care se poate
obtine optimul global prin alegeri succesive ale optimului local. Astfel problema este rezolvata
fara a se reveni la deciziile luate deja. Din acest motiv, metoda Greedy se mai numeste tehnica
alegerii local optimale. Ideea de baza a tehnicii Greedy este urmatoarea: multimea B este
construita succesiv, ncepand cu primul element, la fiecare pas fiind selectat un nou element
din A (cel care pare a fi cel mai potrivit conform criteriului de optim) si adaugat n B. Odata
ce s-a facut o alegere, aceasta nu mai poate fi schimbata nu se mai poate reveni si nlocui
un element al lui B cu o alta valoare din A. Tehnica Greedy nu conduce ntotdeauna la o
solutie optima ceea ce pare optim la un anumit pas (local), poate fi dezastruos la nivel global.
Uneori solutiile obtinute cu aceasta tehnica sunt sub-optimale, adica aproximeaza suficient de
bine solutia optima. Algoritmii de tip greedy sunt simpli, intuitivi si eficienti. In practica, exista
situatii cand o solutie aproximativa a unei probleme poate fi multumitoare, ntrucat algoritmul
greedy care furnizeaza solutia poate fi usor de implementat si este eficient. Cealalta varianta, a
generarii prin tehnica Backtracking a tuturor solutiilor si apoi a selectarii solutiei optime, poate fi
extrem de ineficienta datorita complexitatii foarte mari. Intrucat tehnica Greedy nu garanteaza
determinarea solutiei optime, pentru fiecare algoritm n parte trebuie demonstrata corectitudinea
acestuia.
Desi atat metoda Greedy cat si metoda Backtracking ofera solutii sub forma de vector, cele doua
metode se deosebesc esential prin:
tehnica Backtracking ofera toate solutiile problemei, n timp ce metoda Greedy ofera o
singura solutie;
tehnica Greedy nu dispune de mecanismul ntoarcerii, specific metodei Backtracking.
Aplicatia 1. Minimizarea timpului mediu de asteptare. O singura statie de servire (procesor,
pompa de benzina, frizer etc.) trebuie sa satisfaca cererile a n clienti. Cunoscand timpul de
servire necesar fiecarui client (pentru clientul i este necesar un timp ti , i = 1, n), sa se determine
o ordine a servirii clientilor astfel ncat timpul total de asteptare sa fie minim.
Timpul total de asteptare este suma timpilor de asteptare pentru fiecare client n parte. Daca
notam cu wi , timpul de asteptare pentru clientul i, i = 1, n si timpul total de asteptare cu T ,
n
X
atunci T =
wi .
i=1

A minimiza timpul total de asteptare este acelasi lucru cu a minimiza timpul mediu de asteptare,
care este T /n.
1

Algoritmi si structuri de date

Curs 12

Clientii sunt indentificati prin numere de la 1 la n.


Problema poate fi rezolvata folosind tehnica backtracking, generand astfel toate solutiile posibile
si alegand apoi pe cea optima, adica pe cea care minimizeaza timpul total de asteptare. De fapt,
prin aceasta metoda se vor generara toate permutarile multimii {1, 2, 3, ..., n} si pentru fiecare
solutie n parte se va calcula timpul total de asteptare. Se va alege solutia pentru care T este
minim. De exemplu, presupunem ca sunt 3 clienti avand timpii de servire t1 = 3, t2 = 7 si t3 = 2.
Sunt posibile 3! = 6 modalitati de servire. Acestea sunt:
(1, 2, 3),
(1, 3, 2),
(2, 1, 3),
(2, 3, 1),
(3, 1, 2),
(3, 2, 1),

T
T
T
T
T
T

= 3 + (3 + 7) + (3 + 7 + 2) = 25
= 3 + (3 + 2) + (3 + 2 + 7) = 20
= 7 + (7 + 3) + (7 + 3 + 2) = 29
= 7 + (7 + 2) + (7 + 3 + 5) = 28
= 2 + (2 + 3) + (2 + 3 + 7) = 19
= 2 + (2 + 7) + (2 + 7 + 3) = 23

In prima solutie generata cu algoritmul backtracking, clientul 1 este servit primul, deci w1 = 3,
timpul de asteptare incluzand si timpul de servire. Clientul 2 asteapta pana este servit clientul
1 si apoi este servit si el, deci w2 = 3 + 7 = 10. Clientul 3 asteapta pana sunt serviti clientii 1
si 2 si apoi este servit si el, deci w3 = 3 + 7 + 2 = 12. Asadar, timpul total de asteptare a celor
trei clienti este T = 3 + 10 + 12 = 25. Observam ca timpul cel mai mic de asteptare este 19 si
este oferit de solutia (3, 1, 2). Asadar aceasta este solutia optima: mai ntai va fi servit clientul
3, apoi clientul 1 si la final, clientul 2.
Tehnica Greedy este mai eficienta din punctul de vedere al timpului de executie si al simplitatii.
Algoritmul bazat pe aceasta tehnica este foarte simplu: la fiecare pas se selecteaza clientul cu
timpul minim de servire din multimea de clienti ramasa. Complexitatea acestui algoritm este
logaritmica. In scopul obtinerii solutiei optime, vom sorta crescator sirul timpilor de servire. Se
poate demonstra ca acest algoritm conduce ntotdeauna la solutia optima.
Datele de intrare vor fi citite dintr-un fisier text timpi.txt. Pe prima linie a fisierului se afla
numarul n al clientilor. Linia a doua a fisierului contine n numere naturale, separate prin spatii,
reprezentand timpii de servire a clientilor, ti , i = 1, n .
Datele de iesire (ordinea optima de servire a clientilor si timpul total de asteptare) vor fi scrise
la sfarsitul aceluiasi fisier.
#include<i o s t r e a m >
#include<f s t r e a m >
#define dim 100
using namespace s t d ;
struct C l i e n t
{
// t = t i m p u l de s e r v i r e
// nr = numarul de o r d i n e
int t , nr ;
};

Algoritmi si structuri de date

Curs 12

void s o r t I n s e r a r e D i r e c t a ( C l i e n t v e c t o r [ ] , int n )
{
int i , j ;
C l i e n t aux ;
for ( i = 1 ; i < n ; i ++)
{
aux = v e c t o r [ i ] ;
j = i 1;
while ( ( j >= 0 ) && ( aux . t < v e c t o r [ j ] . t ) )
{
v e c t o r [ j +1] = v e c t o r [ j ] ;
j = j 1;
}
v e c t o r [ j +1] = aux ;
}
}
void timp ( C l i e n t c [ ] , int n , o f s t r e a m &f o u t )
{
// c l i e n t i i s u n t i n o r d i n e c r e s c a t o a r e , dupa t i m p i i de s e r v i r e
int i , j ;
int T = 0 ;
for ( i = 0 ; i < n ; i ++)
{
f o u t <<c [ i ] . nr<< ;
for ( j = 0 ; j <= i ; j ++)
T += c [ j ] . t ;
}
f o u t <<endl<< Timpul t o t a l de a s t e p t a r e e s t e <<T<<e n d l ;
}
int main ( )
{
int n ;
C l i e n t c [ dim ] ;
ifstream f i n ( timpi . txt ) ;
if (! fin )
{
cout<< Eroare l a d e s c h i d e r e a f i s i e r u l u i . <<e n d l ;
exit (1);
}
f i n >>n ;
for ( int i = 0 ; i < n ; i++ )
{
f i n >>c [ i ] . t ;
c [ i ] . nr = i + 1 ;
3

Algoritmi si structuri de date

Curs 12

}
fin . close ();
sortInserareDirecta (c , n );
o f s t r e a m f o u t ( t i m p i . t x t , i o s : : app ) ;
timp ( c , n , f o u t ) ;
fout . close ( ) ;
return 0 ;
}
Aplicatia 2. Problema spectacolelor. In singura sala de spectacole a unui teatru trebuie sa fie
programate cat mai multe spectacole dintre cele n posibile. Pentru fiecare spectacol i, i = 1, n,
se cunoaste intervalul n care se poate desfasura [si , fi ) (si reprezinta ora si minutul de nceput,
iar fi ora si minutul de final al spectacolului i). Sa se determine un program care sa permita
spectatorilor participarea la un numar cat mai mare de spectacole.
Spectacolele le vom identifica prin numere de la 1 la n. Vom sorta spectacolele crescator dupa
momentul de ncheiere a acestora. Algoritmul greedy va fi urmatorul: mai ntai selectam spectacol
care se termina cel mai devreme. La fiecare pas selectam primul spectacol disponibil, care nu se
suprapune cu cele deja selectate, deci care ncepe dupa ce se termina ultimul spectacol selectat.
Datele de intrare se vor citi dintr-un fisier text spectacole.txt n care, pe prima linie, se afla numarul de spectacole n. Pe urmatoarele n linii se vor afla cate 4 valori, primele doua reprezentand
ora si minutul nceperii spectacolului curent, iar ultimele doua reprezentand ora si minutul terminarii spectacolului.
Datele de iesire, numerele de ordine ale spectacolelor care ndeplinesc restrictiile problemei, vor
fi afisate la sfarsitul aceluiasi fisier, separate prin spatii.
#include<i o s t r e a m >
#include<f s t r e a m >
#define dim 100
using namespace s t d ;
struct S p e c t a c o l
{
// s = momentul i n c e p e r i i s p e c t a c o l u l u i
// f = momentul i n c h e i e r i i s p e c a t c o l u l u i
// nr = numarul c u r e n t
int s , f , nr ;
};
void s o r t I n s e r a r e D i r e c t a ( S p e c t a c o l v e c t o r [ ] , int n )
{
int i , j ;
S p e c t a c o l aux ;
for ( i = 1 ; i < n ; i ++)
{
aux = v e c t o r [ i ] ;
j = i 1;
4

Algoritmi si structuri de date

Curs 12

while ( ( j >= 0 ) && ( aux . f < v e c t o r [ j ] . f ) )


{
v e c t o r [ j +1] = v e c t o r [ j ] ;
j = j 1;
}
v e c t o r [ j +1] = aux ;
}
}
void program ( S p e c t a c o l v [ ] , int n , o f s t r e a m &f o u t )
{
f o u t <<endl<<v [ 0 ] . nr<< ;
//u = i n d e x u l u l t i m u l u i s p e c t a c o l a d a u g a t i n program
int i , u = 0 ;
for ( i = 1 ; i < n ; i ++)
i f ( v [ i ] . s >= v [ u ] . f )
{
f o u t <<v [ i ] . nr<< ;
u = i;
}
f o u t <<e n d l ;
}
int main ( )
{
int n ;
int h , m;
S p e c t a c o l v [ dim ] ;
ifstream f i n ( spectacole . txt ) ;
if (! fin )
{
cout<< Eroare l a d e s c h i d e r e a f i s i e r u l u i . <<e n d l ;
exit (1);
}
f i n >>n ;
for ( int i = 0 ; i < n ; i++ )
{
v [ i ] . nr = i + 1 ;
f i n >>h>>m;
// transformam o r e l e i n minute
v [ i ] . s = h 60 + m;
f i n >>h>>m;
v [ i ] . f = h 60 + m;
}
fin . close ();
sortInserareDirecta (v , n ) ;
5

Algoritmi si structuri de date

Curs 12

o f s t r e a m f o u t ( s p e c t a c o l e . t x t , i o s : : app ) ;
program ( v , n , f o u t ) ;
fout . close ( ) ;
return 0 ;
}
Aplicatia 3. Problema rucsacului. O persoana are un rucsac n care se poate ncarca o greutate
maxima G. Persoana are la dispozitie n obiecte. Pentru fiecare obiect se cunoaste greutatea sa si
castigul care s-ar obtine daca obiectul ar fi transportat n ntregime. Sa se determine ce obiecte
ar trebui sa aleaga persoana pentru a le transporta astfel ncat castigul total sa fie maxim, fara
a se depasi greutatea maxima a rucsacului.
Facem urmatoarele notatii pentru fiecare obiect i, i = 1, n:
gi greutatea obiectului;
ci castigul ce s-ar obtine daca obiectul ar fi transportat n ntregime;
ci
castigul unitar.
si =
gi
Vom considera urmatoarele doua cazuri:
1. toate obiectele pot fi fractionate (se poate lua orice parte din obiectul i);
2. obiectele nu pot fi fractionate (orice obiect i poate fi transportat sau n ntregime sau deloc).
Vom nota cu xi cantitatea din obiectul i ce este ncarcata n rucsac pentru a fi transportata.
Notam cu x = (x1 , x2 , ..., xn ) vectorul solutiei. Solutia optima va trebui sa satisfaca urmatoarele
conditii, n functie de cazul considerat:
1.

n
X

gi xi = G, unde xi [0, 1], i = 1, n (se permite fractionarea obiectelor);

i=1

2.

n
X

gi xi G, unde xi {0, 1}, i = 1, n (nu se permite fractionarea obiectelor).

i=1

Pentru ambele cazuri, solutia optima trebuie sa maximizeze castigul total, Ct =

n
X

ci x i .

i=1

Vom sorta obiectele n ordinea descrescatoare a castigurilor unitare.


Pentru primul caz, n care se permite fractionarea obiectelor, se vor ncarca obiectele pe cat
posibil n ntregime, ncepand cu obiectul de castig unitar maxim, continuand apoi cu urmatorul,
respectand ordinea considerata, pana se ajunge la greutatea maxima a rucsacului. In acest caz
se poate demonstra ca algoritmul Greedy conduce la solutia optima a problemei.
Pentru al doilea caz, se adauga n rucsac obiectele dupa aceasi regula, doar ca nu se permite
fractionarea acestora. Incarcarea n rucsac a obiectelor are loc fie pana cand greutatea totala
6

Algoritmi si structuri de date

Curs 12

a obiectelor alese este egala cu capacitatea maxima a rucsacului (solutia este optima), fie mai
exista loc n rucsac, dar nu mai pot fi ncarcate alte obiecte, deoarece greutatea individuala a acestora depaseste capacitatea ramasa disponibila a rucsacului (solutia obtinuta nu este ntotdeauna
optima).
Obiectele sunt indentificate prin numere de la 1 la n.
Datele de intrare vor fi citite dintr-un fisier rucsac.txt. Pe prima linie a fisierului se afla numarul
n al obiectelor disponibile si numarul real G, reprezentand capacitatea maxima a rucsacului.
Linia a doua a fisierului contine n numere reale, separate prin spatii, reprezentand greutatile gi
ale obiectelor. Linia a treia are, separate prin spatii, n numere reale, corespunzatoare castigurilor
ci oferite de transportul obiectelor.
Datele de iesire vor fi scrise, pentru ambele cazuri studiate, la sfarsitul aceluiasi fisier, astfel: mai
ntai sunt listate obiectele ce vor fi ncarcate n rucsac, identificate prin numarul lor de ordine si
este afisat, de asemenea, castigul total obtinut ca urmare a transportului acestora.
#include<i o s t r e a m >
#include<f s t r e a m >
#define dim 100
using namespace s t d ;
struct Obiect
{
int nr ; // numarul c u r e n t a l o b i e c t u l u i
double g , c , s ;
};
void s o r t I n s e r a r e D i r e c t a ( Obiect v e c t o r [ ] , int n )
{
int i , j ;
Obiect aux ;
for ( i = 1 ; i < n ; i ++)
{
aux = v e c t o r [ i ] ;
j = i 1;
while ( ( j >= 0 ) && ( aux . s > v e c t o r [ j ] . s ) )
{
v e c t o r [ j +1] = v e c t o r [ j ] ;
j = j 1;
}
v e c t o r [ j +1] = aux ;
}
}
void r u c s a c 1 ( double G, Obiect v [ ] , int n , o f s t r e a m &f o u t )
{
double C = 0 , p a r t ;
int i = 0 ;
7

Algoritmi si structuri de date

Curs 12

f o u t << Cazul 1 . Este permisa f r a c t i o n a r e a o b i e c t e l o r . <<e n d l ;


while (G > 0 && i < n )
{
i f (G >= v [ i ] . g )
{
// incarcam i n t e g r a l o b i e c t u l v [ i ]
G = v [ i ] . g ;
C += v [ i ] . c ;
f o u t << O b i e c t u l <<v [ i ] . nr<< complet <<e n d l ;
}
else
{
// incarcam p a r t i a l o b i e c t u l v [ i ]
part = G / v [ i ] . g ;
C += v [ i ] . c p a r t ;
f o u t << O b i e c t u l <<v [ i ] . nr<< p a r t i a l
<<100part<< %<<e n d l ;
G = 0 ;
}
i++ ;
}
f o u t << C a s t i g u l t o t a l : <<C<<e n d l ;
}
void r u c s a c 2 ( double G, Obiect v [ ] , int n , o f s t r e a m &f o u t )
{
double C = 0 , G1 = 0 ;
f o u t << Cazul 2 . Nu e s t e permisa f r a c t i o n a r e a o b i e c t e l o r . <<e n d l ;
for ( int i = 0 ; i < n ; i ++)
{
i f (G1 + v [ i ] . g <= G)
{
// incarcam i n t e g r a l o b i e c t u l v [ i ]
G1 += v [ i ] . g ;
C += v [ i ] . c ;
f o u t << O b i e c t u l <<v [ i ] . nr<<e n d l ;
}
}
f o u t << C a s t i g u l t o t a l : <<C<<e n d l ;
}
int main ( )
{
double G;
int n ;
Obiect vec [ dim ] ;
8

Algoritmi si structuri de date

Curs 12

ifstream f i n ( rucsac . txt ) ;


if (! fin )
{
cout<< Eroare l a d e s c h i d e r e a f i s i e r u l u i . <<e n d l ;
exit (1);
}
f i n >>n ;
f i n >>G ;
for ( int i = 0 ; i < n ; i++ )
f i n >>vec [ i ] . g ;
for ( int i = 0 ; i < n ; i++ )
{
f i n >>vec [ i ] . c ;
vec [ i ] . s = vec [ i ] . c / vec [ i ] . g ;
vec [ i ] . nr = i + 1 ;
}
fin . close ();
s o r t I n s e r a r e D i r e c t a ( vec , n ) ;
o f s t r e a m f o u t ( r u c s a c . t x t , i o s : : app ) ;
r u c s a c 1 (G, vec , n , f o u t ) ;
f o u t <<e n d l ;
r u c s a c 2 (G, vec , n , f o u t ) ;
fout . close ( ) ;
return 0 ;
}
Exemplul 1.
rucsac.txt
5 10
1 4 3 5 2
2 9 10 15 1
Cazul 1.
Obiectul
Obiectul
Obiectul
Castigul

Este permisa fractionarea obiectelor.


3 complet
4 complet
2 partial 50 %
total: 29.5

Cazul 2.
Obiectul
Obiectul
Obiectul
Castigul

Nu este permisa fractionarea obiectelor.


3
4
1
total: 27

Exemplul 2.
rucsac.txt
9

Algoritmi si structuri de date

Curs 12

3 7
5 3 4
6 3 4
Cazul 1.
Obiectul
Obiectul
Castigul

Este permisa fractionarea obiectelor.


1 complet
2 partial 66.6667 %
total: 8

Cazul 2. Nu este permisa fractionarea obiectelor.


Obiectul 1
Castigul total: 6
Solutia returnata de algoritm, pentru cazul n care nu este permisa fractionarea obiectelor, nu
este optima. Optim ar fi sa se aleaga obiectele 2 si 3, care ar da un castig total egal cu 7, mai
mare decat cel furnizat de algoritm.
Aplicatia 4. Un vanzator trebuie sa dea rest unui client o suma de bani S, avand la dispozitie
bancnote de valori b1 , b2 , ..., bn n numar nelimitat. Stiind ca vanzatorul intentioneaza sa foloseasca
un numar cat mai mic de bancnote, sa se afiseze o modalitate de plata a restului.
Cum vanzatorul vrea sa folosesca un numar cat mai mic de bancnote, strategia lui ar trebui sa
fie urmatoarea: mai ntai, sa aleaga, pe cat posibil, bancnota cea mai mare, n numar maxim
posibil. In acest fel va acoperi o mare parte a sumei cu bancnote putine. Apoi, la fiecare pas,
pentru plata sumei ramase ar trebui sa urmeze aceeasi regula: sa aleaga bancnota de valoare cea
mai mare posibila, n numar maxim.
Vom ordona sirul bancnotelor n ordinea descrescatoare a valorilor acestora. Notam cu xi numarul
n
X
de bancnote de valoare bi folosite pentru plata restului, atunci S =
xi bi . Daca Sr este suma
i=1

ramasa de plata la un moment dat si cea mai mare bancnota disponibila este de valoare bi
(bi Sr ), atunci vor fi folosite un numar de [Sr /bi ] bancnote de acest fel.
Problema nu are ntotdeauna solutie. De exemplu, daca restul de plata este S = 19 si sunt
disponibile bancnote de valoare 5 si 10, atunci nu se poate gasi nici o combinatie de bancnote
pentru plata restului.
Datele de intrare vor fi citite din fisierul text rest.txt. Pe prima linie a fisierului se afla numarul
n al bancnotelor disponibile si suma de plata S, separate prin spatii. Linia a doua a fisierului
contine n numere naturale, separate prin spatii, reprezentand valorile bi ale bancnotelor.
Datele de iesire, numarul de bancnote din fiecare tip folosit la plata restului, vor fi scrise la
sfarsitul aceluiasi fisier.
#include<i o s t r e a m >
#include<f s t r e a m >
#define dim 100
using namespace s t d ;
struct Bancnota
10

Algoritmi si structuri de date

Curs 12

{
// x = numarul de b a n c n o t e ce s u n t f o l o s i t e
int v a l o a r e , x ;
};
void s o r t I n s e r a r e D i r e c t a ( Bancnota v e c t o r [ ] , int n )
{
int i , j ;
Bancnota aux ;
for ( i = 1 ; i < n ; i ++)
{
aux = v e c t o r [ i ] ;
j = i 1;
while ( ( j >= 0 ) && ( aux . v a l o a r e > v e c t o r [ j ] . v a l o a r e ) )
{
v e c t o r [ j +1] = v e c t o r [ j ] ;
j = j 1;
}
v e c t o r [ j +1] = aux ;
}
}
void p l a t a R e s t ( int S , Bancnota b [ ] , int n , o f s t r e a m &f o u t )
{
int i = 0 ;
while ( S > 0 && i < n )
{
i f ( b [ i ] . v a l o a r e <= S )
{
// f o l o s i m bancnota b [ i ]
b [ i ] . x = S / b [ i ] . valoare ;
S = S b [ i ] . x b [ i ] . valoare ;
}
i++ ;
}
i f ( S == 0 )
{
f o u t << Pentru p l a t a r e s t u l u i sau f o l o s i t : <<e n d l ;
for ( int i = 0 ; i < n ; i ++)
i f ( b [ i ] . x != 0 )
f o u t <<b [ i ] . x<< bancnote de v a l o a r e
<<b [ i ] . v a l o a r e <<e n d l ;
}
else
f o u t << Fara s o l u t i e ! <<e n d l ;
}
11

Algoritmi si structuri de date

Curs 12

int main ( )
{
int n , S ;
Bancnota b [ dim ] ;
ifstream f i n ( rest . txt ) ;
if (! fin )
{
cout<< Eroare l a d e s c h i d e r e a f i s i e r u l u i . <<e n d l ;
exit (1);
}
f i n >>n ;
f i n >>S ;
for ( int i = 0 ; i < n ; i++ )
{
f i n >>b [ i ] . v a l o a r e ;
b [ i ] . x = 0;
}
fin . close ();
sortInserareDirecta (b , n ) ;
o f s t r e a m f o u t ( r e s t . t x t , i o s : : app ) ;
plataRest (S , b , n , fout ) ;
fout . close ( ) ;
return 0 ;
}
Exemplul 1.
rest.txt
2 65
10 25
Fara solutie!
Acest algoritm de tip greedy nu furnizeaza o solutie corespunzatoare datelor de intare de mai
sus. Observam ca totusi aceasta exista: plata sumei cu un numar minim de bancnote se face
folosind o bancnota de valoare 25 si 4 de valoare 10. In schimb, algoritmul selecteaza 2 bancnote
de 25 (acesta e numarul maxim: 65/25) si ramane fara nicio posibilitate de a plati suma ramasa
(= 15).
Daca printre bancnote exista si unele de valoare 1, atunci acest algoritm furnizeaza ntotdeauna
o solutie.
Exemplul 2.
rest.txt
3 65
12

Algoritmi si structuri de date

Curs 12

10 25 1
Pentru plata restului
2 bancnote de valoare
1 bancnote de valoare
5 bancnote de valoare

s-au folosit:
25
10
1

Pe de alta parte, chiar daca suma S poate fi platita cu bancnotele disponibile, aceasta metoda
nu asigura obtinerea optimului global. Rezolvarea exacta a problemei se face folosind tehnica
Backtracking, cautand astfel toate solutiile posibile ale problemei si alegand-o apoi pe cea optima.
Exemplul 3.
rest.txt
4 129
12 5 1 25
Pentru plata restului s-au folosit:
5 bancnote de valoare 25
4 bancnote de valoare 1
Algoritmul furnizeaza o solutie de plata a restului cu 9 bancnote. Dar suma poate fi platita cu
7 bancnote (solutia optima): 129 = 4 25 + 2 12 + 1 5.
Daca bancnotele disponibile sunt de valori egale cu puterile unui numar natural k 2, k 0 , k 1 , k 2 ,
..., k n1 , disponibile n numar nelimitat, atunci algoritmul de tip greedy furnizeaza solutia optima
a problemei.
Exemplul 4.
rest.txt
6 139
1 4 2 16 8 32
Pentru plata restului
4 bancnote de valoare
1 bancnote de valoare
1 bancnote de valoare
1 bancnote de valoare

s-au folosit:
32
8
2
1

Asadar, un algoritm greedy nu conduce ntotdeauna la solutia optima si, n unele cazuri, nici
macar la o solutie a problemei. Este doar o tehnica generala, urmand ca pentru fiecare caz n
parte sa determinam daca obtinem sau nu solutia optima.

13

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