Este o metodă generală de elaborare a algoritmilor. În esenţă ea se aplică problemelor în care se dă o
mulţime A conţinând n date de intrare cerându-se să se determine o submulţime B a sa care să îndeplinească anumite condiţii pentru a fi acceptată. Cum în general există mai multe astfel de mulţimi, se dă şi un criteriu conform căruia, dintre submulţimile acceptabile (numite soluţii posibile), se alege una singură (numită soluţie optimă) ca rezultat final. Soluţiile posibile au următoarea proprietate: dacă submulţimea BA este o soluţie posibilă şi CB, atunci şi C este o soluţie posibilă. Vom presupune că mulţimea vidă este întotdeauna o soluţie posibilă. Metoda Greedy tratează acest tip de probleme în două moduri care urmează aceeaşi metodă dar diferă doar prin ordinea de efectuare a unor operaţii • APLICARE Exemplu: Se dă o mulţime A cu N elemente şi se cere să se determine o submulţime A sau B care satisfaceanumite restricţii. Această submulţime se numeşte soluţie posibilă. Se cere să se determine o soluţie posibilă care fie să maximizeze fie să minimizeze o anumită funcţie obiectivdată. Această soluţie posibilă se numeşte soluţie optimă. MetodaGreedylucrează în paşi astfel: 1.se iniţializează mulţimea soluţiilor (B) la mulţimea vidă (B=Φ) 2.la fiecare pas se alege un anumit elementx ∈A(cel mai promiţător element la momentulrespectiv) care poate conduce la o solutie optimă la pasul i ; 3.se verifică dacă elementul ales poate fi adăugat la mulţimea soluţiilor; dacă da atunci va fiadăugat şi mulţimea soluţiilor devine B=B∪{x } . Dacă un element se introduce în mulţimeaB , el nu va finiciodată eliminat de acolo. Dacă se alege un element dinAcare nu se poate adăuga mulţimiiB, el nu semai testează ulterior; 4.procedeul continuă astfel, repetitiv, până când au fost determinate toate elementele dinmulţimea soluţiilor În rezolvarea problemelor, de multe ori este utilă ordonarea mulţimiiAînainte ca algoritmul propriu-zis să fie aplicat. • TIPURI DE PROBLEME
TIPURI DE PROBLEME PENTRU ALGORITMII GREEDY SUNT:
-CELE MAI MARI 2 NUMERE RESPECTIV CELE MAI MICI DINTR-UN SIR DE NUMERE INTREGI PANA LA INTALNIREA VALORII 0. -PLATA UNEI SUME IN MONEDE DE MAI MULTE TIPURI -PROBLEMA MENIURILOR -PROBLEMA RESTAURANTULUI -PROBLEMA RUCSACURI (TRANSPORTUL UNEI GREUTATI IN FUNCTIE DE UN ANUMIT COST) • PROBLEME Program P1; Var n, a1, a2, c:Integer; Begin a1:=-MAXINT; (initializam primele 2 numere si n cu o constanta predefinita) a2:=-MAXINT; n:=-MAXINT; While n<>0 Do Begin If (n>a1) Then a1:=n; (daca numarul n este mai mare decat primul cel mai mare numar atunci maximul este n) If (a2<a1) Then Begin c:=a1; a1:=a2; a2:=c; end; (interschimbare) Readln (n); end; Writeln (‘a1, ‘ ‘,a2’); . end. Program p2; Write (‘ cand incepe sa fie servit si cand Begin Type benz=record a terminat alimentarea: ‘); Write (‘posibilii clienti, in ordine: ‘); ins, sfs:integer; for i:=1 to n Do ultim:=1; ord:integer; end; Write (‘(‘v[i].ins,’,’,v[i].sfs, ‘,’,v[i].ord’)’); nr:=1; Var v:array [1..100] of benz; Writeln; end; Write (v[i].ord, ‘ ‘); n, ultim, nr:integer; Procedure sortare_clienti; for i:=2 to n do Procedure citire_clienti; Var i,j:integer; if (v[i].ins>v[ultim].sfs) then Var hh, mm, i:integer; t:benz; begin begin Begin Write (v[i].ord, ‘ ‘); Write (‘n= ‘); Readln (n); for i:=1 to n-1 Do ultim:=i; for i:=1 to n do begin for j:=i+1 to n Do nr:=nr+1; Write (‘Clientul cu nr. ‘,i,’cand este if (v[j].sfs<v[i].sfs) then end; servit? (ora si minutul)’); Begin Writeln (‘in total se pot alege Readln (hh, mm); t:=v[i]; v[i]:=v[j]; maxim’,nr, ‘clienti’); v[i].ins:=hh*60+mm; for j:=i+1 to n Do begin Write (‘clientul cu nr ‘, i, ‘ cand a if (v[j].sfs<v[i].sfs) then citire_clienti; terminat alimentarea ? ‘); Begin afisare_clienti; Readln (hh, mm); t:=v[i]; v[i]:=v[j]; sortare_clienti; v[i].sfs:=hh*60+mm; v[j]:=t; end; end; afisare_clienti; v[i].ord:=i; end; end; Procedure alg_greedy; alg_greedy; Procedure afisare_clienti; var i:integer; END. Var i:integer; Begin Program P3; v[j]:=temp; for i:=1 to n do type teatru=record end; write (‘(‘,v[i].ins,’,’,v[i].sfs,’,’,v[i].ord,’)’); ins, sfs:integer; (ora de inceput si de sfarsit a Procedure citire_piese; writeln; unui spectacol calculata in minute scurse fata de Var hh,mm,i:integer; end; miezul noptii) begin Procedure algo_greedy; ord:integer; (numarul de ordin al spectacolului) Write (‘Numarul de piese de teatru n= ‘); Readln Var i:integer; end; (n); Begin Var v:array [1..30] of teatru; for i:=1 to n do begin Write (‘Piesele posibile, in ordine: ‘); n, ultim, nr:integer; (n=numarul de spectacole, Write (‘Piesa cu nr ‘,i, cand incepe? (ora si ultim:=1; nr:=1; in variabila ultim avem in permanenta ultimul minutul)’); write (v[i], ‘ ‘); spectacol selectat, nr=numarul maxim de Readln (hh,mm); for i:=2 to n do spectacole) v[i].ins:=hh*60+mm; If (v[i].ins>v[ultim].sfs) then Procedure sortare_piese; Write (‘Piesa cu nr ‘,i, cand se termina? (ora si Begin Var i,j:integer; minutul)’); Write (v[i].ord, ‘ ‘); temp:teatru; Readln (hh,mm); ultim:=i; Begin v[i].ins:=hh*60+mm; nr:=nr+1; end; For i:=1 to n-1 do v[i].ord:=i; Writeln (‘In total se pot alege maxim’,nr,’ piese’); for j:=i+1 to n do end; end; end; if v[j].sfs<v[i].sfs then Procedure afis_piese; Begin begin Var i:integer; citire_piese; temp:=v[i]; Begin afis_piese; v[i]:=v[j]; Write (‘Inceputurile si sfarsiturile pieselor in minute sortare_piese; scurse de la miezul noptii: ‘); afis_piese; algo_greedy; end. program Rucsac; WriteLN('Am ordonat . . .'); const max=5; for i:=1 to n do var C,G,X: array [1..max] of Real; WriteLN('C[',i,']=',C[i] :5:2, n,i,j:Integer; GG,GGr,aux:Real; 'G[',i,]=' G[i] :5:2, begin ' ‘,C[i]/G[i] :5:2); Write(Nr. obiecte = '); GGr:=GG; i:=1; ReadLn (n); While (i<=n) do For i:=1 to n do if GGr > G[i] then begin begin Write ('C[',i,']='); X[i]:=1; ReadLN (c[i]); GGr:=GGr-G[i]; i:=i+1 Write ('G[',i,']='); end ReadLn (G[i]); else end; begin Write('Greut. max. = '); X[i]:=GGr/G[i]; ReadLn (GG); For j:=i+1 to n do X[j]:=0 for i:=1 to n-1 do I:=n+1 for j:=i+1 to n do end; if C[j]/G[j]>C[i]/G[i] then for i:=1 to n do begin WriteLn (‘X[‘,I,’]=’X[i] :5:2); aux:=C[j]; C[j]:=C[i]; ReadLn C[i]:=aux; aux:=G[j]; end. G[j]:=G[i]; G[i]:=aux; • Program V3P7_02; var nb:integer; type tablou=array[1..3,1..7] of integer; begin var s,ss,i : integer; a:tablou; f:text; i:=7; {In primul rind al tabelului vom pastra nominalul while (i>=1) and (sa>0) do bancnotelor} begin nb:=sa div a[1,i]; {In al doilea rind - numarul bancnotelor citite din if nb<>0 then if nb>= a[2,i] fisier} then a[3,i]:=a[2,i] {In al treilea rind - numarul bancnotelor obtinute la else a[3,i]:=nb; schimb} sa:=sa-a[3,i]*a[1,i]; Procedure Afisare(sa:integer); i:=i-1; begin writeln('suma ',s); end; if sa<>0 end; { calcul } then writeln('nu poate fi transformata cu bancnotele begin date ') a[1,1]:=1; a[1,2]:=5; a[1,3]:=10; a[1,4]:=50; else a[1,5]:=100; a[1,6]:=200; a[1,7]:=500; begin writeln('se plateste cu urmatoarele bancnote'); assign (f,'bani.in'); reset(f); for i:=1 to 7 do for i:=1 to 7 do readln(f,a[2,i]); if a[3,i]<>0 write ('introduceti suma de lei S ');readln(s); then writeln('bancnote de ',a[1,i]:6,' sau folosit ss:=s; calcul(ss); Afisare(ss); ',a[3,i]); end. end end; { Afisare } Procedure calcul(var sa:integer); CONCLUZII:
UN ALGORITM GREEDY VA FUNCŢIONA ASEMĂNĂTOR MODULUI DE GÂNDIRE
AL UNUI OM LACOM: VA CONSUMA ELEMENTE DINTR-O ANUMITĂ SECVENŢĂ, DE FIECARE DATĂ LUÂND ACEL ELEMENT, CE SE POTRIVEȘTE CEL MAI BINE CU UN ANUMIT CRITERIU, FĂRĂ A PRIVI ÎN PERSPECTIVĂ. DEȘI PRIMA IMPRESIE AR FI CĂ ACEASTĂ ABORDARE ESTE UNA GREȘITĂ, DATORITĂ CONOTAŢIEI CUVÂNTULUI LACOM, TOTUȘI UNEORI ALGORITMII DE ACEST TIP POT DUCE LA SOLUŢII SIMPLE ȘI EFICIENTE.