Documente noi - cercetari, esee, comentariu, compunere, document
Documente categorii

Metoda backtracking

Metoda backtracking



Este o tehnica de programare aplicabila algoritmilor care ofera mai multe solutii si are ca rezultat obtinerea tuturor solutiilor problemei. Fiecare solutie se memoreaza intr-o structura de date de tip stiva implementata cu ajutorul unui vector. Deci fiecare solutie poate fi pusa sub forma unui vector.

Intr-un algoritm backtracking ne intereseaza toate solutiile posibile. Pentru a obtine fiecare solutie finala se completeaza stiva nivel cu nivel trecand astfel prin niste solutii partiale. Astfel solutiile finale cat si cele partiale pentru a fi luate in considerare trebuie sa indeplineasca anumite conditii numite conditii de validare. O solutie care indeplineste o astfel de conditie se numeste solutie valida.



Toate configuratiile stivei ce reprezinta solutii finale sunt alcatuite din elementele aceleiasi multimi bine definite pe care o numim multimea solutiilor. Fiecare noua solutie partiala se obtine prin completarea solutiei partiale precedente cu inca o nivel pe stiva. La fiecare nivel se pun valori din multimea solutiilor care nu au fost incercate pana cand se obtine o solutie valida. In acest moment se trece la nivelul urmator in stiva pentru a completa mai departe solutia reluand incercarile pe noul nivel.

La un moment dat pe un anumit nivel nu mai exista nici o valoare neincercata din multimea valorilor problemei. In acest caz se face un pas inapoi in stiva la nivelul anterior si se reia cautarea cu valorile ramase neincercate pe acest nivel anterior.

Respectivul nivel a mai fost vizitat dar l-am abandonat dupa ce am pus o valoare care a generat o solutie valida. Deci este posibil sa fi ramas aici valori neincercate. Daca nici pe acest nivel nu mai avem valori neincercate mai facem un pas inapoi in stiva. Mecanismul revenirilor a determinat denumirea de metoda backtracking.

Plecand de la nivelul 1 si repetand algoritmul pana cand pe toate nivelele au fost incercate toate valorile din multimea valorilor se obtin solutii finale care se tiparesc.

Vom implementa metoda backtracking iterativ folosind o rutina unica aplicabila oricarei probleme. Rutina va apela proceduri si functii care au intotdeauna acelasi nume si parametri si care din punct de vedere al metodei realizeaza acelasi lucru.

Sarcina rezolvatorului este sa scrie explicit - pentru fiecare problema - procedurile si functiile aplicate pe rutina. Astfel gasirea urmatorului element netestat de pe un nivel k al stivei St se face cu procedura succesor (as,St,k)

Odata ales un element testarea conditiilor de validare se face cu procedura valid (ev,St,k).

Testul daca s-a ajuns sau nu la o solutie finala se face cu functia solutie (k)

Solutia se tipareste cu procedura tipar.

De asemenea fiecare nivel al stivei trebuie initializat cu o valoare aflata inaintea tuturor valorilor posibile din multimea solutiilor. Aceasta afisare se face cu procedura init (k,St).


Rutina Backtracking



K:=1; init (1,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;



Probleme rezolvate


Backtracking iterativ



1.  Generarea permutarilor.


program permutari;

type stiva=array [1..10] of integer;

var st:stiva;

ev,as:boolean;

n,k:integer;

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

if (st[k]<0) and (st[k-1]<0) then ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write (st[i]);

writeln;

end;

begin;

write ('n:=');readln (n);

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.



2.  Generarea aranjamentelor.


program aranjamente;

type stiva=array [1..10] of integer;

var st:stiva;

ev,as:boolean;

n,k,p:integer;

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

if (st[k]<0) and (st[k-1]<0) 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:=');readln (n);

write ('p:=');readln (p);

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.  Generarea combinarilor


program combinari;

type stiva=array [1..10] of integer;

var st:stiva;

ev,as:boolean;

n,k,p: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;

if (k=>2) and (st[k-1]>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;

write ('n:=');readln (n);

write ('p:=');readln (p);

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.


4.  Dintr-un nr. de 6 cursuri optionale un elev trebuie sa aleaga 3. Sa se afiseze toate posibilitatile de alegere precum si nr. lor.


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.



5.  Numerele care ii plac lui Gigel


Lui Gigel ii plac nr. formate numai din cifre pare cifre aflate in ordine descrescatoare. Sa se determine si sa se afiseze pe ecran toate nr. de n cifre (0<n<10) care ii plac lui Gigel. Valoarea lui n este un nr. natural care se citeste de la tastatura.


program nr_lui_gigel;

type stiva=array[1..100] of integer;

var st:stiva;

i,n,k:integer;

as,ev:boolean;

procedure init(k:integer;var st:stiva);

begin

st[k]:=-1;

end;

procedure succesor(var as:boolean;var st:stiva;k:integer);

begin

if st[k]<9 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 st[i] mod 2 <> 0 then ev:=false;

for i:=1 to k-1 do

if st[i]<st[i+1] then ev:=false;


end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write(st[i]);

writeln;

end;

begin

write('n= ');readln(n);



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.


6.  La un concurs sportiv s-au inscris n concurenti avand numerele de concurs 1,2,,n. Pentru fiecare sportiv se cunoaste tara de origine (sir de caractere). In prima zi vor intra in concurs m concurenti. Afisati toate posibilitatile de a stabili ordinea intrarii in concurs a celor m concurenti respectand urmatoarele conditii:

2 sportivi din aceeasi tara nu pot evolua unul dupa altul

trebuie respectata ordinea crescatoare a numerelor de concurs ale sportivilor.


program comcurs_sportiv;

type stiva=array[1..100] of integer;

var st:stiva;

tara:array[1..50] of string;

m,i,n,k:integer;

as,ev:boolean;

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 st[k]=st[i] then ev:=false;

if (k>1) and (tara[st[k-1]]=tara[st[k]]) then ev:=false;

if (k>1) and (st[k]<st[k-1]) then ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=m);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to m do write(st[i],' ');

writeln;

end;

begin

write('n= '); read(n);

write('m= '); read(m);

for i :=1 to n do

begin

write('concurentul',i,'=');readln(tara[i]);

end;

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.


7.  Sa se afiseze toate modurile posibile de a descompune un numar natural n in suma de k numere naturale diferite(n si k sunt cunoscute).



program desc;

type stiva=array[1..100] of integer;

var st:stiva;

s,n,k,p:integer;

as,ev:boolean;

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-p+k 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

s:=0;

ev:=true;

for i:=1 to k-1 do if st[k]=st[i] then ev:=false;

if (k>=2) and (st[k]<st[k-1]) then ev:=false;

for i:=1 to k do s:=s+st[i];

if s>n then ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=p);

end;

procedure tipar;

var i:integer;

begin

if s=n then

for i:=1 to p do write(st[i],' ');

writeln;

end;

begin

write ('n:=');readln (n);

write ('p:=');readln (p);

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.


8.  La un festival de muzica s-au inscris n melodii codificate 1,2,3,,n (n>=4). Sa se afiseze toate posibilitatile de a stabili ordinea intrarii in concurs a melodiilor stiind ca melodiile cu codurile C1 si C2 trebuie obligatoriu sa evolueze a doua respectiv penultima. Valorile lui C1 si C2 se citesc de la tastatura C1,C2 apartin .


program festival;

type stiva=array[1..100] of integer;

var st:stiva;

k,n,C1,C2:integer;

as,ev:boolean;

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 st[k]=st[i] then ev:=false;

if (k=2) and (st[k]<>C1) then ev:=false;

if (k=n-1) and (st[k]<>C2) then ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write(st[i]);

writeln;

end;

begin

write('n=');readln(n);

write('melodia a II-a este: ');readln(C1);

write('penultima melodie este: ');readln(C2);

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.



9.  Se da un numar natural par. Sa se afiseze toate sirurile de n paranteze care se inchid corect.


program paranteze;

type stiva=array[1..100] of integer;

var st:stiva;

npd,npi,n,k:integer;

as,ev:boolean;

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]<2 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

npd:=0;

npi:=0;

for i:=1 to k do

if st[i]=1 then npd:=npd+1

else npi:=npi+1;

if (npd>=npi) and (npd<=n div 2) then ev:=true

else ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

if npd=npi then

for I:=1 to k do

if st[i]=1 then write('(')

else write(')');

writeln;

begin

write('n= ');read(n);

st[1]=1;

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.


10.          Problema celor n dame.


Fiind data o tabla de sah n x n se cer toate solutiile de aranjare a n dame astfel incat sa nu se afle 2 dame pe aceeasi linie, coloana sau diagonala.


program dame;

type stiva=array[1..100] of integer;

var st:stiva;

n,k:integer;

as,ev:boolean;

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;var st:stiva;k:integer);

var i:integer;

begin

ev:=true;

for i:=1 to k-1 do if (st[k]=st[i]) or (abs(st[k]-st[i])=abs(k-i)) then ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write(st[i]);

writeln;

end;

begin

write('n:');readln(n);

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.


11.          Se citesc n numere naturale si n multimi A1,A2,,An. Sa se calculeze produsul cartezian al multimilor date.


program pcartez;

type stiva=array[1..100] of integer;

var st:stiva;

i,n,k:integer;

as,ev:boolean;

a:array [1..100] of integer;

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]<a[k] 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;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write(st[i]);

writeln;

end;

begin

write('Numarul de multimi= ');readln(n);

for i:=1 to n do begin

write('a[',i,']=');readln(a[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.



12.          Se citeste un numar natural n. Se cere sa se tipareasca toate modurile de descompunere a lui n ca suma de numere naturale.


program desc2;

type stiva=array[1..100] of integer;

var st:stiva;

s,n,k:integer;

as,ev:boolean;

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

s:=0;

ev:=true;

for i:=1 to k do s:=s+st[i];

if s<=n then ev:=true

else ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(s=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to k do write(st[i]);

writeln;

end;

begin

write('n=');readln(n);

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.


13.          Problema Comis-voiajor


Un comis-voiajor trebuie sa viziteze un numar n de orase. Initial, acesta se afla intr-unul dintre ele, notat 1. Comis-voiajorul doreste sa nu treaca de doua ori prin acelasi oras, iar la intoarcere sa revina in orasul 1. Cunoscand legaturile existente intre orase, se cere sa se tipareasca toate drumurile posibile pe care le poate efectua comis-voiajorul.



program comisv;

type stiva=array[1..100] of integer;

var st:stiva;

i,j,n,k:integer;

as,ev:boolean;

a:array[1..20,1..20] of integer;

procedure init(k:integer;var st:stiva);

begin

st[k]:=1;

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;

if a[st[k-1],st[k]]=0 then ev:=false

else

for i:=1 to k-1 do if st[i]=st[k] then ev:=false;

if (k=n) and (a[1,st[k]]=0) then ev:=false

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n)

end

procedure tipar;

var i:integer;

begin

for i:=1 to n do

write('nodul=',st[i]);

writeln('------');

end;

begin

write('nr. de noduri=');readln(n);

for i:= 1 to n do

for j:=1 to i-1 do begin

write('a[',i,',',j,']='); readln(a[i,j]);

a[j,i]:=a[j,i];

end;

end;

st[1]:=1; k:=2;

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.



14.          Scrieti un program care, folosind metoda backtracking, afiseaza toate modurile de a aranja elementele unui sir dat de numere intregi astfel incat in sirul rezultat sa nu existe doua elemente negative alaturate.


program sir;

type stiva=array[1..100] of integer;

vector=array[1..100] of integer;

var st:stiva;

n,k,i:integer;

as,ev:boolean;

a:vector;

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 st[k]=st[i] then ev:=false;

if (a[st[k]]<0) and (a[st[k-1]]<0) then ev:=false;

end;


function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write(a[st[i]],' ');

writeln;

end;

begin

write('n=');readln(n);

for i:=1 to n do

begin

write('a[',i,']=');readln(a[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.



15.          Turnuri de cuburi


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 afiseze toate turnurile care se pot forma luand k cuburi din cele n disponibile, astfel incat:

-laturile cuburilor din turn sa fie in ordine crescatoare;

-culorile a oricare doua cuburi alaturate din turn sa fie diferite.


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.


16.          Generarea partitiilor unui nr.


Se citeste un nr. natural n .Se cere sa sa tipareasca toate modurile de descompunere a lui n ca suma de nr. naturale.


program partitii_ale_unui_nr;

type stiva=array [1..10] of integer;

var st:stiva;

ev,as:boolean;

n,k:integer;

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;var st:stiva;k:integer);

var i,s:integer;

begin s:=0;   

for i:=1 to k do

s:=s+st[i];

if s<=n then ev:=true

else ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write (st[i]);

writeln;

end;

begin;

write ('n:=');readln (n);



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.


17.          Drapele


Se dau 7 culori, codificate prin nr. 1, 2, ., 7. Afisati toate posibilitatile de alcatuire a unor drapele tricolore care sa contina numai culori dintre cele date, astfel incat culoarea din mijloc sa apartina unui set dat de patru culori din randul celor 7 disponibile; a treia culoare nu poate sa fie c unde c este un nr. intreg cuprins intre 1 si 3; cele trei culori de pe drapel sa fie distincte.


program drapele;

const n=7;

type stiva=array [1..10] of integer;

var st:stiva;

ev,as:boolean;

n,k:integer;

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

if (st[3]=1) or (st[3]=3) or (st[3]=2) then ev:=false;

if st[3]=(1,2,3) then ev:=false;

for i:=1 to 4 do if st[2]<>st[i] then ev:=false;

end;

function solutie(k:integer):boolean;

begin

solutie:=(k=n);

end;


procedure tipar;

var i:integer;

begin

for i:=1 to n 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.



Backtracking recursiv(dupa schema)



18.          Generarea permutarilor.


program permutari;

type stiva=array [1..10] of integer;

var st:stiva;

ev:boolean;

n,k:integer;

procedure init(k:integer;var st:stiva);

begin st[k]:=0;

end;

function succesor(var st:stiva;k:integer);

begin

if st[k]<n then begin

st[k]:=st[k]+1;

succesor:=true;

end

else succesor:=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;

if (st[k]<0) and (st[k-1]<0) then ev:=false;

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write (st[i]);

writeln; end;

procedure back(k:integer)

begin

if k=n then tipar

else begin

init(k,st);

while succesor(st,k) do

begin

valid(ev,st,k);

if ev then back(k+1);

end;

end;

end;

begin

write('n= ');read(n);

back(1);readln;

end.


19.          Generarea aranjamentelor.


program aranjamente;

type stiva=array [1..10] of integer;

var st:stiva;

ev:boolean;

n,k:integer;

procedure init(k:integer;var st:stiva);

begin st[k]:=0;

end;


function succesor(var st:stiva;k:integer);

begin

if st[k]<n then begin

st[k]:=st[k]+1;

succesor:=true;

end

else succesor:=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;

if (st[k]<0) and (st[k-1]<0) then ev:=false

end;

procedure tipar;

var i:integer;

begin

for i:=1 to p do write (st[i]);

writeln;

end;

procedure back(k:integer)

begin

if k=p then tipar

else begin

init(k,st);

while succesor(st,k) do

begin

valid(ev,st,k);

if ev then back(k+1);

end;

end;

end;

begin

write('n= ');read(n);

write('p= ');read(p);

back(1);readln;

end.


20.          Generarea combinarilor.


program combinarilor;

type stiva=array [1..10] of integer;

var st:stiva;

ev:boolean;

n,k:integer;

procedure init(k:integer;var st:stiva);

begin st[k]:=0;

end;

function succesor(var st:stiva;k:integer);

begin

if st[k]<n-p+k then begin

st[k]:=st[k]+1;

succesor:=true;

end

else succesor:=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;

if (k=>2) and (st[k-1]>st[k]) then ev:=false;

end;

procedure tipar;

var i:integer;

begin

for i:=1 to p do write (st[i]);

writeln; end;

procedure back(k:integer)

begin

if k=p then tipar

else begin

init(k,st);

while succesor(st,k) do

begin

valid(ev,st,k);

if ev then back(k+1);

end;

end;

end;

begin

write('n= ');read(n);

write('p= ');read(p);

back(1);readln;

end.



Backtracking recursiv(fara schema)



21.          Generarea permutarilor


program permutari;

type stiva=array [1..10] of integer;

var st:stiva;

n,k:integer;

procedure init(k:integer;var st:stiva);

begin st[k]:=0;

end;

function valid(k:integer):boolean;

var i:integer;

ok:boolean;

begin

ok=true;

for i:=1 to k-1 do

if st[i]=st[k] then ok=false;


valid:=ok

end;

procedure tipar;

var i:integer;

begin

for i:=1 to n do write (st[i]);

writeln;

end;

procedure back(k:integer)

var val:integer;

begin

for val :=1 to n do

begin

st[k]:=val;

if valid(k) then

if k=n then tipar

else back(k+1);

end;

begin

write('n= ');read(n);

init(k);

back(1);

end.



22.          Generarea aranjamentelor.


program aranjamente;

type stiva=array [1..10] of integer;

var st:stiva;

n,k:integer;

procedure init(k:integer;);

begin st[k]:=0;

end;

function valid(k:integer):boolean;

var i:integer;

ok:boolean;

begin

ok=true;

for i:=1 to k-1 do

if st[i]=st[k] then ok:=false;

if (st[k]<0) and (st[k-1]<0) then ok:=false;

valid:=ok;

end;

procedure tipar;

var i:integer;

begin

for i:=1 to p do write (st[i]);

writeln;

end;

procedure back(k:integer)

var val:integer;

begin

for val :=1 to n do

begin

st[k]:=val;

if valid(k) then

if k=p then tipar

else back(k+1);

end;

begin

write('n= ');read(n);

write('p= ');read(p);

init(k);

back(1);

end.

23.          Generarea combinarilor.


program combinarilor;

type stiva=array [1..10] of integer;

var st:stiva;

n,k:integer;

procedure init(k:integer);

begin st[k]:=0;

end;

function valid(k:integer):boolean;

var i:integer;

ok:boolean;

begin

ok:=true;

for i:=1 to k-1 do

if st[i]=st[k] then ok:=false;

if (k=>2) and (st[k-1]>st[k]) then ok:=false;

valid:=ok;

end;

procedure tipar;

var i:integer;

begin

for i:=1 to p do write (st[i]);

writeln;

end;

procedure back(k:integer)

var val:integer;

begin

for val :=1 to n-p+k do

begin

st[k]:=val;

if valid(k) then

if k=p then tipar

else back(k+1);

end;

begin

write('n= ');read(n);

write('p= ');read(p);

init(k);

back(1);

end.