Documente Academic
Documente Profesional
Documente Cultură
Metoda reluării
De exemplu, pentru mulţimile A1, A2, ..., An formate numai din cîte două elemente,
timpul necesar este O(2n
), deci exponenţial.
Pentru evitarea trierii tuturor elementelor produsului cartezian A1A2 ... An, în
metoda reluării componentele vectorului X primesc valori pe rînd, în sensul că lui
xk
i se atribuie o valoare numai dacă au fost deja atribuite valori lui x1, x2 , ...,
xk-1 . Mai
mult, odată o valoare pentru xk stabilită, nu se trece direct la atribuirea de
valori lui
xk+1, ci se verifi că anumite condiţii de continuare referitoare la x1, x2 , ...,
xk. Aceste
127
condiţii stabilesc situaţiile în care are sens să trecem la calculul lui xk+1. Dacă
aceste
condiţii nu sînt satisfăcute, va trebui să facem o altă alegere pentru xk sau, dacă
ele-
mentele din mulţimea Ak s-au epuizat, să micşorăm pe k cu o unitate încercînd să
Pentru exemplifi care, în fi gura 5.4 este prezentată ordinea în care sînt
examinate
A1
A2
A3
k:=1
k:=k+1
0
0
k:=k+1 k:=k–1
k:=k+1
Din fi gura 5.4 se observă că primul element a11 din mulţimea A1 nu satisface con-
diţiile de continuare şi, în consecinţă, se trece la elementul al doilea a12 din
aceeaşi
mulţime. Mai departe în vectorul X se include primul element a21 din mulţimea A2,
element care satisface condiţiile de continuare, şi se trece la examinarea
elementelor
din mulţimea A3.
Întrucît niciunul din elementele a31 , a32 , a33 nu satisface condiţiile de
continuare,
se revine la mulţimea A2 din care se alege elementul al doilea, şi anume, a22. După
aceasta se testează din nou elementele mulţimii A3, elementul a32 satisfăcînd
condiţi-
ile de continuare.
Schema generală a unui algoritm recursiv bazat pe metoda reluării este redată cu
ajutorul procedurii ce urmează:
procedure Reluare(k:integer);
begin
if k<=n then
128
begin
X[k]:=PrimulElement(k);
if Continuare(k) then Reluare(k+1);
while ExistaSuccesor(k) do
begin
X[k]:=Succesor(k);
if Continuare(k) then Reluare(k+1)
end; { while }
end { then }
else PrelucrareaSolutiei;
end; {Reluare}
Pentru o înţelegere mai clară a procesului recursiv, vom urmări execuţia procedu-
rii Reluare în cazul mulţimilor A1, A2, şi A3 din fi gura 5.3.
X=(a11).
X=(a12).
De data aceasta apelul Continuare(1) returnează valoarea true şi, prin urma-
re, se trece la execuţia recursivă a apelului Reluare(2). Evident, în componenta x2
X=(a12, a21).
Pentru acest vector funcţia Continuare returnează valoarea true, fapt ce de-
clanşează execuţia recursivă a apelului Reluare(3).
129
însă nici unul din aceşti vectori nu satisface condiţiile de continuare. După
exami-
narea ultimului element din mulţimea A3, funcţia ExistaSuccesor returnează va-
loarea false şi, în consecinţă, se revine în contextul apelului Reluare(2). În
acest
X=(a12, a22).
din nou se execută apelul recursiv Reluare(3). Însă, spre deosebire de apelul pre-
cedent, în acest caz vectorul
Rezolvare. Vom reprezenta mulţimile A1, A2, ..., An prin liniile tabloului
bidimensi-
onal (matricei) A = ||akj||. Numărul de elemente mk al fi ecărei mulţimi Ak va fi
reţinut
q : Natural;
k, j : integer;
Indicator : boolean;
function PrimulElement(k : integer) : Natural;
begin
PrimulElement:=1;
end; {PrimulElement }
130
function Continuare(k : integer) : boolean;
var j : integer;
suma : Natural;
begin
suma:=0;
for j:=1 to k do suma:=suma+A[j, X[j]];
if ((k<n) and (suma<q)) or ((k=n) and (suma=q))
then Continuare:=true
else Continuare:=false;
end; { Continuare }
function ExistaSuccesor(k : integer) : boolean;
begin
ExistaSuccesor:=(X[k]<M[k]);
end; { ExistaSuccesor }
function Succesor(k : integer) : integer;
begin
Succesor:=X[k]+1;
end; { Succesor }
procedure PrelucrareaSolutiei;
var k : integer;
begin
write(’Soluţia: ’);
for k:=1 to n do write(A[k, X[k]], ’ ’);
writeln;
Indicator:=true;
end; { PrelucrareaSolutiei }
procedure Reluare(k : integer);
{ Metoda reluarii - varianta recursiva }
begin
if k<=n then
begin
X[k]:=PrimulElement(k);
if Continuare(k) then Reluare(k+1);
while ExistaSuccesor(k) do
begin
X[k]:=Succesor(k);
if Continuare(k) then Reluare(k+1);
end { while }
end { then }
else PrelucrareaSolutiei;
end; { Reluare }
131
begin
write(’Daţi cardinalul A[’, k, ’]=’); readln(M[k]);
write(’Daţi elementele mulţimii A[’, k, ’]: ’);
for j:=1 to M[k] do read(A[k, j]);
writeln;
end;
Write(’Daţi q=’); readln(q);
Indicator:=false;
Reluare(1);
if Indicator=false then writeln(’Nu există soluţii’);
readln;
end.
), unde