Sunteți pe pagina 1din 4

METODE GENERALE DE ELABORARE A ALGORITMILOR (II)

1. Coninutul lucrrii
n lucrare sunt prezentate principiile metodei greedy, variantele de aplicare i exemple.

2. Consideraii teoretice
Metoda Greedy se aplic urmtoarelor tipuri de probleme:
Dintr-o mulime A de n elemente se cere determinarea unei submulimi B care s
ndeplineasc anumite condiii pentru a fi acceptat.
Numele metodei vine de la urmtorul fapt: se alege pe rnd cte un element din
mulimea A i eventual se introduce n soluie.
Se menioneaz faptul c o dat ce un element a fost ales el rmne n soluia final, iar
dac un element a fost exclus, el nu va mai putea fi reconsiderat pentru includere n soluie.
Metoda determin o singur soluie.
Exist dou variante de rezolvare a unei probleme cu ajutorul metodei Greedy:

a) Varianta I
Se pleac de la mulimea B vid. Se alege din mulimea A un element neales n paii
precedeni. Se cerceteaz dac adugarea la soluia parial B conduce la o soluie posibil. n
caz afirmativ se adaug elementul respectiv la B.
Descrierea variantei este urmtoarea:
#define max ...
GREEDY1(int A[max], int n, int B[max], int *k)
/* A este mulimea de n elemente date;
B este mulimea extras de k elemente */
{
int x, v, i;
*k = 0; /* Mulimea B este vid */
for(i = 0; i<n; i++)
{
ALEGE (A, n, i, x);
/* se alege elementul x dintre elementele A[i], A[i+1], ... A[n-1] i se aduce pe
poziia i prin interschimbare */
POSIBIL (B, x, v);
/* v=1 dac x prin adugare la B conduce la soluie posibil i
v=0 n caz contrar */
if(v==1) ADAUGA(B, x, *k);
/* se adaug x la B, k indicnd numrul de elemente din B */
}
}

n varianta I a metodei, funcia ALEGE stabilete criteriul care duce la soluia final.
b) Varianta II

k
0
U[i]
Se stabilete de la nceput ordinea n care trebuie considerate elementele mulimii A.
Apoi se ia pe rnd cte un element n ordinea stabilit i se verific dac prin adugare la soluia
parial B anterior construit, se ajunge la o soluie posibil. n caz afirmativ se face adugarea.
Descrierea variantei este urmtoarea:
#define max ...
GREEDY2(int A[max], int n, int B[max], int *k)
/* A este mulimea de n elemente date;
B este mulimea extras de k elemente */
{
int x, v, i;
*k = 0; /* soluia vid */
PRELUCRARE(A, n); /* rearanjare vector A */
for(i = 0; i<n; i++)
{
x=A[i];
POSIBIL (B, x, v);
/* v=1 dac prin adugarea lui x la B se ajunge la o soluie posibil i
v=0 n caz contrar */
if(v==1) then ADAUGA(B, x, *k);
/* se adaug x la mulimea B */
}
}

Dificultatea elaborrii funciei PRELUCRARE este identic cu cea a funciei ALEGE din
varianta precedent.
Exemplu: Determinarea arborelui de acoperire de cost minim prin algoritmul lui Prim.
Problema a fost enunat n cadrul lucrrii nr.7 paragraful 2.3.
Algoritmul const n urmtoarele:
a) Iniial se ia arborele ce conine un singur vrf. S-a demonstrat c nu are
importan cu care vrf se ncepe; ca urmare se ia vrful 1. Mulimea arcelor este vid.
b) Se alege arcul de cost minim, care are un vrf n arborele deja construit, iar
cellalt vrf nu aparine arborelui. Se repet n total acest pas de n-1 ori.
Pentru evitarea parcurgerii tuturor arcelor grafului la fiecare pas, se ia vectorul v avnd
n componente definit astfel:
dac vrful i aparine arborelui deja construit

dac vrful i nu aparine arborelui deja construit; k este vrful arborelui
deja construit a. . muchia (i, k) este de cost minim.
Iniial v[1]=0 i v[2]=v[3]=...=v[n]=1, adic iniial arborele este A =({1}, ).

/*Algoritmul lui Prim */
#include <stdio.h>
#include <conio.h>
#define nmax 10
#define MAX 0x7fff
void prim(int n,int c[nmax][nmax],
int muchii[nmax][2],int *cost)
/* n -numrul nodurilor;
c - matricea costurilor;
muchii-muchiile arborelui de acoperire de cost minim;
cost-costul arborelui de acoperire de cost minim */
{
int v[nmax]; /* v[i]=0 dac i aparine arborelui;
v[i]=j dac i nu aparine arborelui.
j este nodul din arbore a.i.
muchia (i,j) este de cost minim */
int i,j,k,minim;
*cost=0;
v[1]=0;
for(i=2;i<=n;i++) v[i]=1; /*arborele este ({1},{}) */
/* determinarea celor n-1 muchii */
for(i=1;i<=n-1;i++)
{
/*determinarea muchiei care se adaug arborelui
Se calculeaza cea mai mica muchie care pleaca din fiecare nod care nu a fost
adaugat in arbore
Se adauga muchia in arbore
Se actualizeaza costul
Se actualizeaza v */
}
}
void main()
{
int n;/*nr. nodurilor */
int c[nmax][nmax]; /*matricea costurilor */
int muchii[nmax][2];/*muchiile arborelui*/
int i,j,k,cost;
printf("\nNr. nodurilor=");
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
c[i][j]=MAX;
/*citirea costurilor(numere ntregi) */
for(i=1;i<=n;i++)
{
do
{
printf("\nIntroducei 0 pentru terminare sau nodul adiacent\n");
printf(" cu %2d > ca el =",i);
scanf("%d",&j);
if(j>0)
{
printf("\nCostul c[%d][%d]=",i,j);
scanf("%d",&c[i][j]);
c[j][i]=c[i][j]; /*matricea este simetrica */
}
}
while(j>0);
}
prim(n,c,muchii,&cost);
printf("\nCOSTUL ARBORELUI = %d",cost);
printf("\nMUCHIILE ARBORELUI COSTUL MUCHIEI\n");
for(i=1;i<=n-1;i++)
printf(" %2d - %2d %10d\n",muchii[i][0],muchii[i][1],
c[muchii[i][0]][muchii[i][1]]);
getch();
}
3. Mersul lucrrii
3.1 Problema rucsacului. Greutatea maxim care poate fi transportat cu un rucsac este G.
Dndu-se n materiale, fiecare avnd greutatea m i costul C pe unitatea de greutate, s se
gseasc ce cantitate din fiecare material s fie introdus n rucsac pentru ca s se obin ctigul
maxim. Se vor deosebi dou cazuri:
a) un material poate fi luat numai n ntregime;
b) se poate lua o fraciune din material.

3.3 Problema activitilor. Exist o mulime S=1, 2, 3, ..., n de n activiti care doresc s
foloseasc o aceeai resurs (de exemplu o sal de clas). Aceast resurs poate fi folosit de o
singur activitate la un anumit moment de timp. Fiecare activitate i are un timp de pornire tp
i
i
un timp de terminare tf
i
(tp
i
< tf
i
). Dac este selectat activitatea i, ea se desfoar pe durata [tp
i
,
tf
i
]. Spunem c activitile i i j sunt compatibile dac duratele lor nu se intersecteaz. S se
selecteze o mulime maximal de activiti mutual compatibile.