Documente Academic
Documente Profesional
Documente Cultură
Curs 12
A minimiza timpul total de asteptare este acelasi lucru cu a minimiza timpul mediu de asteptare,
care este T /n.
1
Curs 12
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 ;
};
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
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
Curs 12
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
i=1
2.
n
X
i=1
n
X
ci x i .
i=1
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
Curs 12
Curs 12
Cazul 2.
Obiectul
Obiectul
Obiectul
Castigul
Exemplul 2.
rucsac.txt
9
Curs 12
3 7
5 3 4
6 3 4
Cazul 1.
Obiectul
Obiectul
Castigul
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
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
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
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