Sunteți pe pagina 1din 16

Partea a II-a.

Metode de programare

1. a) Subprograme recursive; Metoda Divide et Impera (probleme


clasice);
b) Analiza complexității algoritmilor. Metode de sortare
2. Căutare în spațiul soluțiilor. Metoda Greedy
3. Metoda backtracking
Spațiul soluțiilor
Metoda Greedy – Metoda optimului local
Metoda Greedy – exemplu
Metoda Greedy
Metoda Greedy – operații
Metoda Greedy – algoritm
Metoda Greedy – exemple
Exemple de probleme rezolvate prin algoritmi de tip Greedy:

1. Problema rucsacului
• continuă
• întreagă

2. Problema sumei maxime (dintr-o mulțime de numere)

3. Problema plății unei sume cu nr. minim de bancnote (include bancnota


unitate)

4. Determinarea arborelui parțial de cost minim


• Algoritmul lui Kruskal
• Algoritmul lui Prim

5. Algoritmul lui Dijkstra

Exemplele 4 și 5 vor fi discutate la partea de grafuri


1. Problema rucsacului
Să se scrie subprogramul C pentru rezolvarea problemei rucsacului. Se consideră un
mijloc de transport cu o capacitate dată (). Cu acesta trebuie transportate obiecte
dintr-o mulțime . Fiecare obiect ocupă o capacitate specifică și aduce un câștig
specific – fiecare obiect luat separat încape în mijlocul de transport. Se cere să se
determine o modalitate de încărcare care să maximizeze câștigul obținut la un
transport.
Se va oferi și un exemplu de apel.
a) Dacă obiectele transportate pot fi fracționate, problema este numită continuă. În acest caz
se va utiliza întotdeauna întreaga capacitate de transport.

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

void Rucsac_i(float q, int n, float* c, int* x)


{ float qr; int i,j;
  qr=q; //capacitatea ramasa disponibila, initial cea totala
for(i=0; i<n; i++)
if(qr>=c[i])
{ x[i]=1;
qr-=c[i];
}
else
x[i]=0;
}

Discuții și exemplu de apel


2. Problema sumei maxime
Se dă o mulțime de elemente reale . Se cere să se scrie funcția care determină o
submulțime astfel încât suma elementelor submulțimii să fie cea mai mare posibilă
(problema sumei maxime).

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.

Discuții și exemplu de apel

Ce se întâmplă dacă toate elementele mulțimii sunt negative???


2. Problema sumei maxime – subprogram
// Submultimea care da suma maxima: se iau doar elementele (strict) pozitive
// I: multimea (a), numar de elemente (n)
// E: submultimea (b), numar de elemente (nr)

void suma_maxima(float* a, int n, float *b, int *nr)


{ int i;
*nr=0;
for(i=0;i<n;i++)
if(a[i]>=0) // = pentru zero, care nu afecteaza suma.
b[(*nr)++]=a[i];
}
3. Problema plății unei sume cu nr. minim de bancnote

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];
}
}

Discuții și exemplu de apel

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