Sunteți pe pagina 1din 20

Referat la tema :

“Metoda trierii. Metoda Greedy. Metoda reluării.


Rezolvare de probleme”
Metoda trierii
Definiție
Se numește metoda trierii metoda ce identifică toate soluțiile unei probleme in dependență de
mulțimea soluțiilor posibile. Toate soluțiile se indentifică prin valori, ce aparțin tipurilor de date
studiate: integer, boolean, enumerare sau subdomeniu. În probleme mai complicate este nevoie
de a reprezenta aceste elemente prin tablouri, articole sau mulțimi.
Schema de aplicare a metodei trierii este reprezentată mai jos:

Probleme din viață rezolvabile prin metoda trierii

Metoda trierii poate fi folosită pentru rezolvarea următoarelor probleme din viață:

● aflarea numărului minim de monede care pot fi date drept plată sau rest;
● medicii deseori se confruntă cu necesitatea aplicării metodei trierii cazurilor, când
numărul răniților sau bolnavilor este foarte mare, medicul fiind suprasolicitat, în cazul
unui război, sau când își periclitează propria viață în cazul unei epidemii periculoase;
● aflarea ariei maxime a unui lot de teren, avînd la dispoziție o anumită lungime de sîrmă
ghimpată, spre exemplu (ca perimetru dat);
● generarea submulțimilor unei mulțimi (aflarea tuturor combinațiilor posibile), ceea ce ne
poate fi foarte util în viața de zi cu zi;
● afișarea coordonatelor a două puncte date ce au distanță minimă sau maximă, ceea ce va
fi foarte folositor dacă plănuim o călătorie;
● calcularea șanselor de a lua premiul mare la loterie etc.
Exemplu de problemă

1.Se consideră numerele naturale din mulţimea {0, 1, 2, …, n}. Elaboraţi


un program care determină pentru cîte numere K din această mulţime
suma cifrelor fiecărui număr este egală cu m. În particular, pentru n=100
si m=2, în mulţimea{0, 1, 2, …, 100} există 3 numere care satisfac
condiţiile problemei: 2, 11 si 20.Prin urmare, K=3.
Rezolvare:

Program Pex;
Type Natural=0..MaxInt;
Var I, k, m, n : Natural;
Function SumaCifrelor(i:Natural): Natural;
Var suma: Natural;
Begin
Suma:=0;
Repeat
Suma:=suma+(I mod 10);
i:=i div 10;
until i=0;
SumaCifrelor:=suma;
End;
Function SolutiePosibila(i:Natural):Boolean;
Begin
If SumaCifrelor(i)=m then SolutiaPosibila:=true
Else SolutiePosibila:=false;
End;
Procedure PrelucrareaSolutiei(i:Natural);
Begin
Writeln(‘i=’, i);
K:=k+1;
End;
Begin
Write(‘Dati n=’);
readln(n);
Write(‘Dati m=’);
readln(m);
K:=0;
For i:=0 to n do
If SolutiePosibila(i) then PrelucrareaSolutiei(i);
Writeln(‘K=’, K);
Readln;
End.
2.Se consideră mulţimea P = {P1, P2, …, Pn} formată din n puncte (3 ≤
n ≤30) pe un plan euclidian. Fiecare punct Pj este defi nit prin
coordonatele sale xj, yj. Elaboraţi un program ce determină trei puncte
din mulţimea P pentru care aria triunghiului respectiv este maximă.
Estimaţi timpul de execuţie a programului elaborat.
Rezolvare:

Program P1;
const nmax=30;
type Punct= record x,y:real;
end;
Indice=1..nmax;
var P:array[Indice] of Punct;
j,m,k,n:Indice;
max:real;
PA, PB, PC : Punct;
function Dis(A, B :Punct):real;
begin
Dis:=sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));
end;
function Aria(L1,L2,L3:real):real;
var sp:real;
begin
sp:=(L1+L2+L3)/2;
Aria:=sqrt(sp*(sp-L1)*(sp-L2)*(sp-L3));
end;
function SolutiePosibila(j,m,k:Indice):boolean;
beginif (j<>m) and (m<>k) then SolutiePosibila:=true else SolutiePosibila:=false;
end;
procedure PrelucrareaSolutiei(A,B,C:Punct);
begin
if Aria(Dis(A,B),Dis(B,C),Dis(A,C))>max then
begin
max:=Aria(Dis(A,B),Dis(B,C),Dis(A,C));
PA:=A;
PB:=B;
PC:=C;
end;
end;
begin
write('Dati n= '); readln(n);
writeln('Dati coordonatele x,y ale punctelor');
for j:=1 to n do
begin
write('P[',j,']: ');
readln(P[j].x, P[j].y);
end;
max:=0;
for j:=1 to n do
for m:=1 to n do
for k:=1 to n do
if SolutiePosibila(j,m,k) then
PrelucrareaSolutiei(P[j],P[m],P[k]);writeln('Aria max: ',max:0:2);
writeln('1: ',PA.x:5:2,' ',PA.y:5:2);
writeln('1: ',PB.x:5:2,' ',PB.y:5:2);
writeln('1: ',PC.x:5:2,' ',PC.y:5:2);
readln;
end.

3. Rezolvare:

program p3;
type Pere=array [byte] of byte;
var N,i,j:byte;
X:Pere;
Yes:boolean;
procedure Next(var X:Pere;var Yes:boolean);
var i:byte;
procedure Swap(var a,b:byte);
var c:byte;
begin c:=a;a:=b;b:=c
end;
begin
i:=N-1;
while (i>0)and(X[i]>X[i+1]) do dec(i);
if i>0 then
begin
j:=i+1;
while (j<N)and(X[j+1]>X[i]) do inc(j);
Swap(X[i],X[j]);
for j:=i+1 to (N+i) div 2 do Swap(X[j],X[N-j+i+1]);
Yes:=true
end
else Yes:=false
end;
begin
write('N=');readln(N);
for i:=1 to N do X[i]:=i;
repeat
for i:=1 to N do write(X[i]);writeln;
Next(X,Yes)
until not Yes
end.
4. Determinarea daca numarul n este prim:

Rezolvare:
Program P13;

Var N,i:1..Maxlnt;

T:boolean;

r:real;

begin

writeln(;Introduceti numarul N=’); readln(N);

T:=true;

R:=sqr(N);

i:=2;

while(i<=r) and t do

begin

If N mod i=0 then T:=False;

i:=i+1;

end;

write(‘raspuns’);

if T then writeln (‘Numarul’,N,’este prim’);

else writeln(‘Numarul’,N,’nu este prim);

end.

5. Rezolvare:

Program Triere;

const nmax=20;

type secventa01= array[1..nmax] of 0..1;

var b:secventa01;
r,i,n,k:integer;

f:text;

function numara1:integer;

var s,j:integer;

begin

s:=0;

for j:=1 to n do s:=s+b[j];

numara1:=s;

end;

procedure scrie;

var j: integer;

begin

for j:=1 to n do write (f,b[j]);

writeln(f);

end;

procedure urmator (var x:secventa01);

var j:integer;

begin j:=n;

while x[j]=1 do begin x[j]:=0; j:=j-1; end; x[j]:=1; end;


begin readln(n,k);

assign(f,'OUT.TXT');

rewrite(f);

for i:=1 to n do b[i]:=0;

repeat r:= numara1;

if r >= k then scrie;

if r < n then urmator(b);

until r=n;
close(f);

end.

Tehnica Greedy

Această metoda presupune ca problemele pe care trebuie să le rezolvam au


următoarea structura:
-se da o mulţime A = {a1, a2, … ,a n} formată din n elemente;
-se cere să determinăm o submulţime B, B∈A, care îndeplineşte anumite condiţii
pentru a fi acceptată ca soluţie.
În principiu, problemele de acest tip pot fi rezolvate prin metoda trierii, generînd
consecutiv cele 2ª(n) submulţimi Ai ale mulţimii A. Dezavantajul metodei trierii
constă în faptul că timpul cerut de algoritmii respectivi este foarte mare.Pentru a
evita trierea tuturor submulţimilor Ai, Ai∈A, în metoda Greedy se utilizează un
criteriu (o regula) care asigură alegerea directă a elementelor necesare în mulţimea
A. De obicei, criteriile sau regulile de selecţie nu sîntindicate explicit în enunţul
problemei şi formularea lor cade în sarcina programatorului. Evident, în absenţa
unor astfel de criterii metoda Greedy nu poate fi aplicată.

Exemplu de problemă

1.Problema continuă a rucsacului. Se consideră n obiecte. Pentru fi ecare obiect i


(i=1,2, ..., n) se cunoaște greutatea gi și cîștigul ci care se obţine în urma
transportului său la destinaţie. O persoană are un rucsac cu care pot fi transportate
unul sau mai multe obiecte greutatea sumară a cărora nu depășește valoarea Gmax.
Elaboraţi un program care determină ce obiecte trebuie să transporte persoana în
așa fel încît cîștigul să fi e maxim. În caz de necesitate, unele obiecte pot fi tăiate în
fragmente mai mici.

Rezolvare:

Program Rucsac01;
Const max=10;
Var CMax, CC, GG: integer;
C, G, X, Iau: array [1..max] of integer;
N, k, i: integer;
cont: Boolean;
Function PotContinua( k: integer): Boolean;
Var i: 1..max; Greut: integer;
BeginGreut:=0;
For i:=1 to k do
if x[i[=1 then Greut:=Greut+G[i];
PotContinua:=Greut<=GG
End;
Procedure BackTrack;
Begin
K:=1;
x[k]:=-1;
CMax:=0;
While k>0 do
Begin
Cont:=False;
While (x[k]<1) and (not cont) do
Begin
x[k]:=x[k]+1;
cont:=PotContinua(k)
End;
If cont
then
If k=n then
Begin
CC:=0;
For i:=1 to n do
if x[i]=1 then CC:=CC+C[i];
If CC>=Cmax then
Begin
CMax:=CC;
for i:=1 to n do Iau[i]:=x[i] end
End
Else begin k:=k+1;
x[k]:=-1
end
Else k:=k-1
End
End;
Begin
Write(‘n=’); readln(n);
For i:=1 to n do
Begin
Write(‘C[‘,i,’]=’);
readln(C[i]); write(‘G[‘,i,’]=’);
Readln(G[i]);
End;
Write(‘GG=’);
readln(GG);
BackTrack;
Writeln(‘O sol. Cu cistig maxim:’);
For i:=1 to n do
if Iau[i]=1 then writeln(‘Se ia obiectul ‘,i);
Writeln(‘Cistig = ‘,Cmax); readln;
End.

2.Program Teatru

Rezolvare:

Program P3;
type teatru=record
ins, sfs:integer; {ora de inceput si de sfarsit a unui spectacol calculata in minute
scurse fata de miezul noptii}
ord:integer; {numarul de ordin al spectacolului}
end;
Var v:array [1..30] of teatru;
n, ultim, nr:integer; {n=numarul de spectacole, in variabila ultim avem in
permanenta ultimul spectacol selectat, nr=numarul maxim de spectacole}
Procedure sortare_piese;
Var i,j:integer;
temp:teatru;
Begin
For i:=1 to n-1 do
for j:=i+1 to n do
if v[j].sfs<v[i].sfs then
begin
temp:=v[i];
v[i]:=v[j];
v[j]:=temp;
end;
Procedure citire_piese;
Var hh,mm,i:integer;
begin
Write (‘Numarul de piese de teatru n= ‘); Readln (n);
for i:=1 to n do begin
Write (‘Piesa cu nr ‘,i, cand incepe? {ora si minutul}’);
Readln (hh,mm);
v[i].ins:=hh*60+mm;
Write (‘Piesa cu nr ‘,i, cand se termina? {ora si minutul}’);
Readln (hh,mm);
v[i].ins:=hh*60+mm;
v[i].ord:=i;
end; end;
Procedure afis_piese;
Var i:integer;
Begin
Write (‘Inceputurile si sfarsiturile pieselor in minute scurse de la miezul noptii: ‘);
for i:=1 to n do
write (‘(‘,v[i].ins,’,’,v[i].sfs,’,’,v[i].ord,’)’);
writeln;
end;
Procedure algo_greedy;
Var i:integer;
Begin
Write (‘Piesele posibile, in ordine: ‘);
ultim:=1; nr:=1;
write (v[i], ‘ ‘);
for i:=2 to n do
If (v[i].ins>v[ultim].sfs) then
Begin
Write (v[i].ord, ‘ ‘);
ultim:=i;
nr:=nr+1; end;
Writeln (‘In total se pot alege maxim’,nr,’ piese’);
end;
Begin
citire_piese;
afis_piese;
sortare_piese;
afis_piese;
algo_greedy;
end.

3. Program maxim
Rezolvare:

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.
4.Program Benzinarie

Rezolvare:

Program p2;
Type benz=record
ins, sfs:integer;
ord:integer; end;
Var v:array [1..100] of benz;
n, ultim, nr:integer;
Procedure citire_clienti;
Var hh, mm, i:integer;
begin
Write (‘n= ‘); Readln (n);
for i:=1 to n do begin
Write (‘Clientul cu nr. ‘,i,’cand este servit? {ora si minutul}’);
Readln (hh, mm);
v[i].ins:=hh*60+mm;
Write (‘clientul cu nr ‘, i, ‘ cand a terminat alimentarea ? ‘);
Readln (hh, mm);
v[i].sfs:=hh*60+mm;
v[i].ord:=i; end; end;
Procedure afisare_clienti;
Var i:integer;
Begin
Write (‘ cand incepe sa fie servit si cand a terminat alimentarea: ‘);
for i:=1 to n Do
Write (‘(‘v[i].ins,’,’,v[i].sfs, ‘,’,v[i].ord’)’);
Writeln; end;
Procedure sortare_clienti;
Var i,j:integer;
t:benz;
Begin
for i:=1 to n-1 Do
for j:=i+1 to n Do
if (v[j].sfs<v[i].sfs) then
Begin
t:=v[i]; v[i]:=v[j];
v[j]:=t; end; end;
Procedure alg_greedy;
var i:integer;
Begin
Write (‘posibilii clienti, in ordine: ‘);
ultim:=1;
nr:=1;
Write (v[i].ord, ‘ ‘);
for i:=2 to n do
if (v[i].ins>v[ultim].sfs) then
begin
Write (v[i].ord, ‘ ‘);
ultim:=i;
nr:=nr+1;
end;
Writeln (‘in total se pot alege maxim’,nr, ‘clienti’);
begin
citire_clienti;
afisare_clienti;
sortare_clienti;
afisare_clienti;
alg_greedy;
END.

5.Se consideră mulţimea A = {a1, a2, …, ai, …, an} elementele căreia


sînt numere reale, iar cel puţin unul din ele satisface condiţia ai>0.
Elaboraţi un program caredetermină o submulţime B, B ∈ A, astfel încît
suma elementelor din B să fie maximă.
De exemplu, pentru A = {21,5; -3,4; 0; -12,3; 83,6} avem B = {21,5;
83,6}.

Rezolvare:

Program P153;
Const nmax=1000;
Var A : array [1..nmax] of real;
N : 1..nmax;
B : array [1..nmax] of real;
M : 0..nmax;
X : real;
I : 1..nmax;
Function ExistaElemente : Boolean;
Var i: integer;
Begin
ExistaElemente:=false;
For i:=1 to n do
If A[i]>0 then ExistaElemente:=true;
End;
Procedure AlegeUnElement(var x:real);
Var i: integer;
Begin
I:=1;
While A[i]<=0 do i:=i+1;
X:=A[i];
A[i]:=0;
End;
Procedure IncudeElementul (x:real);
Begin
M:=m+1;
B[m]:=x;
End;
Begin
Write(‘Dati n=’); readln(n);
Writeln(‘Dati elementele multimii A:’);
For i:=1 to n do read(a[i]);
Writeln;
M:=0;
While ExistaElemente do
Begin
AlegeUnElement (x);
IncludeElementul (x);
End;
Writeln(‘Elementele multimii B:’);
For i:=1 to m do writeln(B[i]);
Readln;
End.

Metoda reluării
Se numeşte metoda trierii o metodă ce indentifică toate soluţiile unei probleme în dependenţă de
mulţimea soluţiilor posibile. Toate soluţiile se identifică prin valori, ce aparţin tipurilor de date
studiate: integer, boolean, enumerare, char, subdomeniu, tablouri unidimensionale.
Fie P o problemă, soluţia căreia se află printre elementele mulţimii S cu un număr finit de
elemente. S={s1, s2 , s3 , ... , sn} . Soluţia se determină prin analiza fiecărui element si din
mulţimea S. SCHEMA GENERALĂ for i:=1 to k do if SolutiePosibila (si)
then PrelucrareaSolutiei (si) (SolutiePosibila este o funcţie booleana care
returneaza valoarea true dacă elementul si satisface condiţiile problemei şi false în caz contrar,
iar PrelucrareaSolutiei este o procedură care efectuează prelucrarea elementului selectat. De
obicei, în această procedură soluţia si este afişată la ecran.)

Exemplu de problemă

1.Se dau n cuburi numerotate 1,2,...,n, de laturi Li si culori Ci, i=1,2,...,n


(fiecare culoare este codificata printr-un caracter). Sa se afişeze toate
turnurile care se pot forma luând k cuburi din cele n disponibile, astfel
încât:
-laturile cuburilor din turn sa fie in ordine crescătoare;
-culorile a oricare doua cuburi alăturate din turn sa fie diferite.

Rezolvare:

program cuburi;
type stiva=array [1..100] of integer;
var st:stiva;
i,n,p,k:integer;
as,ev:boolean;
L:array [1..10] of integer;
C:array [1..10] of char;
procedure init(k:integer;var st:stiva);
begin
st[k]:=0;
end;
procedure succesor(var as:boolean;var st:stiva;k:integer);
begin
if st[k]<n then
begin
st[k]:=st[k]+1;
as:=true;
end
else as:=false;
end;
procedure valid(var ev:boolean;st:stiva;k:integer);
var i:integer;
begin
ev:=true;
for i:=1 to k-1 do if L[st[k]]<=L[st[i]] then ev:=false;
if C[st[k]]=C[st[k-1]] then ev:=false;
end;
function solutie(k:integer):boolean;
begin
solutie:=(k=p);
end;
procedure tipar;
var i:integer;
begin
for i:=1 to p do write(st[i],' ');
writeln;
end;
begin
write('n= ');read(n);
write('p= ');read(p);
for i:=1 to n do
begin
write('L[',i,']=');readln(L[i]);
write('C[',i,']=');readln(C[i]);
end;
k:=1;init(k,st);
while k>0 do
begin
repeat
succesor(as,st,k);
if as then valid(ev,st,k);
until (not as) or (as and ev);
if as then if solutie(k) then tipar
else begin
k:=k+1;
init(k,st);
end
else k:=k-1;
end;
end.

2.Dintr-un nr. de 6 cursuri opţionale un elev trebuie să aleagă 3. Să se


afişeze toate posibilităţile de alegere precum şi nr. lor.
Rezolvare:
program cursuri;
const n=6;
p=3;
type stiva=array [1..10] of integer;
var st:stiva;
ev,as:boolean;
k:integer;
procedure init(k:integer;var st:stiva);
begin
if k>1 then st[k]:=st[k-1]
else if k=1 then st[k]:=0;
end;
procedure succesor(var as:boolean;var st:stiva;k:integer);
begin
if st[k]<n-p+k then begin st[k]:=st[k]+1;
as:=true;
end
else as:=false;
end;
procedure valid(var ev:boolean;var st:stiva;k:integer);
var i:integer;
begin
ev:=true;
for i:=1 to k-1 do if st[i]=st[k] then ev:=false;
end;
function solutie(k:integer):boolean;
begin
solutie:=(k=p);
end;
procedure tipar;
var i:integer;
begin
for i:=1 to p do write (st[i]);
writeln;
end;
begin;
k:=1;init(k,st);
while k>0 do
begin
repeat
succesor (as,st,k);
if as then valid(ev,st,k);
until (not as) or (as and ev);
if as then
if solutie(k) then tipar
else begin
k:=k+1;
init(k,st)
end
else k:=k-1;
end;
readln;
end.

3.Aranjarea reginelor. Dându-se o tablă de şah de dimensiune nxn


(n>3) să se aranjeze pe ea n regine fără ca ele să se atace.
Rezolvare:

Program P1;
var x:array[1..100] of byte;
n:byte;
nrsol:word;
procedure scriesol;
var i,j:byte;
begin
inc(nrsol);
writeln('Solutia a',nrsol,'este');
for i:=1 to n do begin
writeln;
for j:=1 to n do
if x[j]=i then write('X',' ')
else write('O',' ');
end;
end;
function potcont(k:byte):boolean;
var i:byte;
atac:boolean;
begin
atac:=false;
for i:=1 to k-1 do
if(x[i]=x[k]) or (k-i=abs(x[k]-x[i])) then atac:=true;
potcont:=not atac;
end;
procedure back(k:byte);
var i:byte;
begin
for i:=1 to n do
begin
x[k]:=i;
if potcont(k) then
if k=n then scriesol
else back(k+1);
end;
end;
begin
read(n);
nrsol:=0;
back(1);
writeln(nrsol,'solutii');
end.

4.Partiţiile unui număr natural. Fie n>0, natural. Să se scrie un


program care să afişeze toate partiţile unui număr natural n.

Rezolvare:

program Partitii_nr_natural;
var n, ns: byte;
sol: array[1..20] of byte;
procedure afis(l: byte);
var i: byte;
begin
inc(ns);
write 'Solutia ', ns, ' : ');
for i:=1 to l do
write(sol[i]:3);
writeln;
end;
procedure back(i, sp: byte);
var j: byte;
begin
if sp = n then afis(i-1)
else for j:=1 to n-sp do
if (j>=sol[i-1])
then begin
sol[i]:=j;
back(i+1, sp+j) end;
end;
begin
read(n);
ns:=0;
back(1,0);
writeln(ns,'solutii');
end.

5.Săritura calului. Fiind dată o tablă de şah de dimensiunea nxn şi un


cal în colţul stânga sus al acesteia, se cere să se afişeze toate
posibilităţile de mutare a acestei piese de şah astfel încât să treacă o
singură dată prin fiecare pătrat al tablei.
Rezolvare:

Program P2;
const dx:array[1..8] of -2..2=(-1,1,2,2,1,-1,-2,-2);
dy:array[1..8] of -2..2=(-2,-2,-1,1,2,2,1,-1);
var a:array[1..10,1..10] of integer;
n:integer;
f:text;
procedure cit;
var i,j :integer;
begin
readln(n);
for i:=1 to n do
for j:=1 to n do a[i,j]:=0;
end;
procedure afis;
var i,j:integer;
begin
for i:=1 to n do begin
for j:=1 to n do write(f,a[i,j]:3);
writeln(f);
end;
writeln(f);
end;
function inside (i,j:integer):boolean;
begin
inside:=(i in [1..n])and (j in [1..n])
end;
procedure back(i,j,pas:integer);
var k,inou,jnou:integer;
begin
a[i,j]:=pas;
if pas=n*n then afis
else for k:=1 to 8 do begin
inou:=i+dx[k];
jnou:=j+dy[k];
if inside(inou,jnou) and (a[inou,jnou]=0)
then back(inou,jnou,pas+1);
end;
a[i,j]:=0;
end;
begin
assign(f,'cal.txt');
rewrite(f);
cit;
back(1,1,1);
close(f);
end.

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