Documente Academic
Documente Profesional
Documente Cultură
P7. Metoda Greedy
P7. Metoda Greedy
Metode de programare
1. Problema rucsacului
• continuă
• întreagă
b) Dacă obiectele nu pot fi fracționate, problema este numită întreagă. În acest caz este
posibil ca soluția obținută să nu utilizeze întreaga capacitate de transport. De asemenea,
soluția obținută poate să nu fie optimă. În plus, este posibil să existe o soluție de utilizare a
întregii capacități de transport, dar aceasta să nu fie găsită prin algoritmul de tip Greedy.
Problema rucsacului – explicații
Cea mai bună soluție se obține dacă se folosește o valoare derivată: câștigul unitar. La
fiecare pas se ia în considerare următorul element al mulțimii sortate descrescător
(alegere).
Dacă acesta încape în mijlocul de transport (verificare), este adăugat la soluție
(adăugare) și se diminuează capacitatea de transport rămasă disponibilă.
Dacă nu încape, atunci:
dacă problema este continuă, se ia din obiectul curent atât cât încape (adăugare);
dacă problema este întreagă, se respinge obiectul curent.
a) Problema rucsacului – continuă
// I: capacitate totala (q), nr. obiecte (n), capacitate ocupata (c)
// E: solutia x (x[i]= raportul in care e incarcat obiectul i)
//c si v sunt vectori ordonați descrescător în funcție de câștigul specific asociat fiecărui obiect
void Rucsac_c(float q, int n, float* c, float* x)
{ float qr; int i,j;
qr=q; //capacitatea ramasa disponibila, initial capacitatea totala
for(i=0; i<n && qr>0; i++)
if(qr>c[i])
{ x[i]=1;
qr-=c[i]; //qr-=c[i]*x[i]
}
else
{ x[i]=qr/c[i];
qr=0; //qr-=c[i]*x[i]
for(j=i+1;j<n;j++)
x[j]=0;
}
}
b) Problema rucsacului- întreagă
//problema rucsacului, intreaga
// I: capacitate totala (q), nr. obiecte (n), capacitate ocupata (c)
// E: solutia x (x[i]= 0-obiectul i nu este incarcat, 1-obiectul i este incarcat)
//c si v sunt vectori ordonați descrescător în funcție de câștigul specific asociat fiecărui obiect
O sortare inițială descrescătoare a mulțimii date asigură un număr mai mic de pași la
aplicarea algoritmului Greedy (oprire la primul element nul/negativ), dar crește complexitatea
la nivel general, de aceea este preferabil (în acest caz) să nu se facă prelucrarea inițială și să se
analizeze toate elementele mulțimii inițiale.
Subprogramul următor rezolvă problema sumei maxime, fără sortarea prealabilă a mulțimii
inițiale, fiind astfel necesară parcurgerea întregii mulțimi.
Să se scrie subprogramul C care permite plata unei sume folosind cât mai puține
bancnote din tipurile (valorile) , știind că printre acestea se află și bancnota cu
valoare unitate. Sunt disponibile cantități nelimitate din fiecare tip de bancnotă.
Pentru a folosi cât mai puține bancnote, trebuie utilizate bancnote cu valori cât mai mari,
ceea ce duce la sortarea mulțimii date în ordine descrescătoare. Astfel, bancnotele cu
valorile cele mai mari vor fi primele luate în considerare. Soluția poate fi reprezentată ca
un vector , în care fiecare element arată câte bancnote de tipul trebuie utilizate.
Pornind de la valoarea inițială , se acoperă cât se poate de mult cu cel mai mare tip de
bancnotă, apoi se ajustează suma rămasă de plată. Se continuă cu fiecare tip de bancnotă,
până când suma rămasă este zero. Dacă mai rămân tipuri de bancnote neinvestigate, ele
rămân nefolosite.
Subprogramul următor constituie un exemplu de implementare a rezolvării. Parametrul
este un vector cu tipurile de bancnote, aranjate în ordinea descrescătoare a valorii
nominale.
3. Problema plății unei sume cu nr. minim de bancnote -
subprogram
// Plata unei sume, cu bancnota unitate, cu numar minim de bancnote
// I: suma (s), tipuri bancnote (t), numar tipuri (n)
// E: nr. din fiecare tip (sol)
void plata_unitate(int s, int* t, int n, int* sol)
{ int i, sr;
sr=s;
for(i=0;i<n;i++)
{ sol[i]=sr/t[i];
sr=sr%t[i];
}
}