Sunteți pe pagina 1din 2

Descrierea tehnicii Backtracking recursiva.

n varianta recursiv, soluiile finale x=(x[1], x[2], ... , x[n] ) sunt generate n cadrul proceduri
recursive {back(i:integer)}, unde i reprezint nivelul pn la care s-a ajuns pe stiv. Cu alte cuvinte, la
fiecare execuie din lanul de autoapeluri, procedura back trateaz nivelul i al stivei. De fapt, aceast
procedur implementeaz algoritmul recursiv de backtracking, pe care l descriem n continuare n
pseudocod:

procedure back(i:integer);
begin
daca sunt_indeplinite_conditiile atunci
afisare
altfel
pentru k=v1 pana la vn
begin
x[i]=k
daca se_poate_ajunge_la_o_solutie_valida
atunci back(i+1)
end;
end;
ntr-un ciclu prin variabila k vor trece pe rnd toate valorile care ar putea fi ncercate pe nivelul i al
stivei. Plecm de la presupunerea c aceste valori sunt succesive ntr-un interval delimitat de capetele v1
i vn. La fiecare pas al ciclului, pentru fiecare dintre valorile variabilei k:

o memoram respectiva valuare pe nivelul i, prin atribuirea x[i]=k. Obinem astfel soluia
(x[1], x[2], ..., x[p] ), care momentan nu are dect statutul de soluie parial;
o verificam daca aceasta solutie este valida; in caz afirmativ trebuie sa verificam daca
respectiva soluie este si finala (de obicei conditia de solutie finala este una singura si
poate fi testat intr-un if, dar putem folosi si o functie pentru aceasta) si in caz afirmativ
afisam solutia;
o in caz contrar, avem de-a face cu o soluie valida (ne aflam pe ramura daca
se_poate_ajunge_la_o_solutie_valida ), dar care nu este si finala. Fiind vorba de o
soluie pariala, trecem la nivelul urmtor pentru a o completa. Cum anume? Trebuie
incrementat i-ul, lucru care se realizeaz prin auto-apelul back(i+1). Astfel, se va relua de
la capt algoritmul, dar cu i+1 n loc de i i.

Generarea tuturor permutarilor

01.#include<cstdio>
02.int a[10],b[10];
03.
04.void back(int k,int len)
05.{
06.if(k-1 == len) //afisam solutia
07.{
08.for(int i = 1; i <= len;i++)
09.printf("%d ",a[i]);
10.printf("\n");
11.}
12.else
13.{
14.for(int i = 1; i <= len; i++)
15.if(!b[i]) //daca valoarea nu-i folosita
16.{
17.a[k] = i;
18.b[i] = 1; //o folosim
19.back(k+1,len); //trecem la pasul urmator
20.b[i] = 0; //o eliberam
21.}
22.}
23.}
24.
25.int main()
26.{
27.freopen("permutari.in","r",stdin);
28.freopen("permutari.out","w",stdout);
29.int n;
30.scanf("%d",&n);
31.back(1,n);
32.fclose(stdin); fclose(stdout);
33.return 0;
34.}

Generarea tuturor combinarilor:

01.#include<cstdio>
02.int a[19],b[19];
03.
04.void back(int k,int len,int max)
05.{
06.if(k-1 == max) //afisam solutia
07.{
08.for(int i = 1; i <= max;i++)
09.printf("%d ",a[i]);
10.printf("\n");
11.}
12.else
13.{
14.for(int i = 1; i <= len; i++)
15.if(!b[i] && a[k-1] < i) //ne asiguram ca generam solutiile crescatoare si unice
16.{
17.a[k] = i;
18.b[i] = 1; //o folosim
19.back(k+1,len,max); //trecem la pasul urmator
20.b[i] = 0; //o eliberam
21.}
22.}
23.}
24.
25.int main()
26.{
27.freopen("combinari.in","r",stdin);
28.freopen("combinari.out","w",stdout);
29.int n,k;
30.scanf("%d %d",&n,&k);
31.back(1,n,k);
32.fclose(stdin); fclose(stdout);
33.return 0;
34.}

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