Sunteți pe pagina 1din 17

METODA BACKTRACKING (cutare cu revenire)

1. NECESITATE Deseori n practic trebuie s rezolvm probleme care au un numr foarte mare de soluii posibile. De cele mai multe ori ns, nu ne intereseaz toate soluiile, ci numai o parte dintre ele, care ndeplinesc anumite condiii specifice problemei. Pentru astfel de probleme este indicat folosirea metodei backtracking care evit generarea soluilor inutile. Desigur c o persoan cu o gndire simplist ar putea spune : generm toate soluiile, apoi le alegem pe cele care ndeplinesc condiiile cerute. Foarte simplu, dar... oare i eficient ? Ce rost ar avea s se genereze nite soluii care oricum nu convin? Din punctul de vedere al timpului necesar calculatorului pentru a obine toate soluiile, ct de realist este o astfel de abordare? 2. APLICABILITATE
a. Se aplic n cadrul problemelor a cror soluie este de tip vector. b. Deoarece are un timp de execuie exponenial, se aplic numai

atunci cnd nu exist o alt cale de rezolvare a problemei respective. 3. DESCRIERE - Metoda utilizeaz structura de tip stiv i poate fi programat att iterativ ct i recursiv. Stiva este acea form de organizare a datelor (structur de date) cu proprietatea c operaiile de introducere i scoatere a datelor se fac n vrful ei. Stivele se pot simula utiliznd vectori. Prima idee pe care trebuie s o reinem ar fi: nu se genereaz toate soluiile posibile, ci numai acelea care ndeplinesc anumite condiii specifice problemei, numite condiii de validare (n unele lucrrii de specialitate acestea mai sunt numite i condiii interne).

Varianta iterativ a metodei backtracking Forma soluiei:

X = ( x1 , x2 ,...xn ) S

S = S1 xS2 x...xSn ) card (S ) = s i i - x1 , x 2 , x n pot fi la rndul lor vectori, - S1 , S2 , Sn pot coincide.

- Componentele vectorului X satisfac anumite relaii, numite condiii interne. Exemplu: Fie:

S1 = {a, b, c} S 2 = {m, n}
condiii interne

x1 S1 (x1, x2 ) = ? cu cu proprietatea c : dac x1 = a sau x1 = b x2 n x2 S 2


Soluiile din spaiul soluiilor posibile S, care satisfac condiiile interne, se numesc soluii rezultat. (a,m), (b,m), (c,m), (c,n) Construirea soluiei: 1) P.p. c x1, ,xk-1 au primit valori i satisfac condiiile de continuare 2) Atribuim o valoare lui xk Sk 3) Verificm condiiile de continuare referitoare la x1,x2, ,xk -dac sunt ndeplinite condiiile de continuare atunci se trece la atribuirea unei valori pentru xk+1 Sk+1
2

- dac nu sunt ndeplinite condiiile de continuare: - oricum vom alege xk+1, , xn nu se va ajunge la o soluie rezultat - se va face o nou alegere pentru xk Sk - dac S k s-a epuizat k=k-1 i se face o nou alegere pentru xk-1 Sk-1 Obs: 1. Condiiile de continuare trebuie s fie necesare i suficiente pentru obinerea unui rezultat 2. Cnd k=n condiiile interne = condiii de continuare (se refer la vectorul soluie) 3. Condiia k=n+1 este utilizat pentru a sesiza obinerea unei soluii 4. Condiia k=0 este utilizat pentru a sesiza sfritul procesului de construire a soluiilor ... xk

st

x2 x1 Aplicaii 1. Utiliznd metoda backtracking se genereaz n ordine lexicografic cuvintele de cte patru litere din mulimea A={a,b,c,d,e}, cuvinte care nu conin dou vocale alturate. Primele opt cuvinte generate sunt, n ordine: abab, abac, abad, abba, abbb, abbc, abbd, abbe. Cte dintre cuvintele generate ncep cu litera b i se termin cu litera e? a. 9 b. 15 c. 12 d. 20

2. Utiliznd metoda backtracking se genereaz n ordine lexicografic cuvintele de cte patru litere din mulimea A={a,b,c,d,e}, cuvinte care nu conin dou vocale alturate. Primele

opt cuvinte generate sunt, n ordine: abab, abac, abad, abba, abbb, abbc, abbd, abbe. Care este ultimul cuvnt generat? a. edcb b. eeee c. edde d. eded

3. Utiliznd metoda backtracking se genereaz n ordine lexicografic cuvintele de cte patru litere din mulimea A={a,b,c,d,e}, cuvinte care nu conin dou vocale alturate. Primele opt cuvinte generate sunt, n ordine: abab, abac, abad, abba, abbb, abbc, abbd, abbe. Care este penultimul cuvnt generat? a. edec b. eded c. edde d. edcb

4. Utiliznd metoda backtracking se genereaz n ordine lexicografic cuvintele de cte patru litere din mulimea A={a,b,c,d,e}, cuvinte care nu conin dou vocale alturate. Primele opt cuvinte generate sunt, n ordine: abab, abac, abad, abba, abbb, abbc, abbd, abbe. Care este antepenultimul cuvnt generat? a. edde b. eddb c. edeb d. edcb

5. Folosind modelul combinrilor se genereaz numerele naturale cu cte trei cifre distincte din mulimea {1,2,3,7}, numere cu cifrele n ordine strict cresctoare, obinndu-se, n ordine: 123, 127, 137, 237. Dac se utilizeaz exact aceeai metod pentru a genera numerele naturale cu patru cifre distincte din mulimea {1,2,3,4,5,6,7,8}, cte dintre numerele generate au prima cifr 2 i ultima cifr 7? a. 8 b. 3 c. 4 d. 6

6. Utiliznd metoda backtracking sunt generate numerele de 3 cifre, avnd toate cifrele distincte i cu proprietatea c cifrele aflate pe poziii consecutive sunt de paritate diferit. tiind c primele ase soluii generate sunt, n aceast ordine, 103, 105, 107, 109, 123, 125, care este a zecea soluie generat? a. 145 b. 147 c. 230 d. 149
4

7. Folosind tehnica bactracking un elev a scris un program care genereaz toate numerele de cte n cifre (0<n9), cifrele fiind n ordine strict cresctoare. Dac n este egal cu 5, scriei n ordine cresctoare toate numerele avnd cifra unitilor 6, care vor fi generate de program. C95 =126 numere 8. Utiliznd metoda backtracking sunt generate numerele de 3 cifre care au cifrele n ordine cresctoare, iar cifrele aflate pe poziii consecutive sunt de paritate diferit. tiind c primele cinci soluii generate sunt, n aceast ordine, 123, 125, 127, 129, 145, care este cel de al 8-lea numr generat? a. 169 b. 149 c. 167 d. 147 9. Utiliznd metoda backtracking, sunt generate n ordine cresctoare toate numerele de 3 cifre, astfel nct cifrele sunt n ordine cresctoare, iar cifrele aflate pe poziii consecutive sunt de paritate diferit. tiind c primele trei soluii generate sunt, n aceast ordine, 123, 125, 127, scriei toate numerele generate care au suma cifrelor egal cu 12. 1 10. Un algoritm de tip backtracking genereaz, n ordine lexicografic, toate irurile de 5 cifre 0 i 1 cu proprietatea c nu exist mai mult de dou cifre 0 pe poziii consecutive. Primele 7 soluii generate sunt: 00100, 00101, 00110, 00111, 01001, 01010, 01011. Care este a 8-a soluie generat de acest algoritm? a. 01110 b. 01100 c. 01011 d. 01101

11. Utiliznd metoda backtracking se genereaz permutrile cuvntului info. Dac primele trei soluii generate sunt: fino, fion, fnio care este cea de-a cincea soluie? (4p.) a. foin b. fnoi c. foni d. ifon 12. Cte numere cu exact dou cifre pot fi construite folosind doar cifre pare distincte? (4p.) a. 12 b. 16 c. 20 d. 25

13. Un algoritm genereaz n ordine cresctoare toate numerele de n cifre, folosind doar cifrele 3, 5 i 7. Dac pentru n=5, primele cinci soluii generate sunt 33333, 33335, 33337, 33353, 33355, precizai care sunt ultimele trei soluii generate, n ordinea generrii. (7,7,7,7,3) (7,7,7,7,5) (7,7,7,7,7) 14. Un algoritm genereaz n ordine descresctoare toate numerele de 5 cifre, fiecare dintre ele avnd cifrele n ordine strict cresctoare. tiind c primele cinci soluii generate sunt 56789, 46789, 45789, 45689, 45679, precizai care sunt ultimele trei soluii generate, n ordinea generrii. 12347, 12346, 12345 18 Algoritm n pseudocod (soluii cu acelai numr de componente = n) k=1; st[k]=0; // iniializare stiv while (k>0) if (k= =n+1) // configuraia e de tip soluie tipar(); k--; else if (exist valori neconsumate n Sk) {se atribuie o valoare pentru xk Sk! if (valid(k)) // valoarea aleas satisface condiiile de continuare { k++; st[k]=0; } } else {st[k]=0; k--; } Aplicaii

Generarea permutrilor mulimii {1, 2, , n} Exp: {1, 2, 3} X=(x1,x2.x3) S={1, 2, 3}x{1, 2, 3}x{1, 2, 3} Nr. sol: 3! = 6 123 132 213 231 312 321 Condiii interne: st[i]!=st[k] #include<iostream.h> int st[10],k,n,nrsol=0; void init() {for (i=1;i<=p;i++) st[i]=0; } void tipar() {for (int i=1;i<=n;i++) cout<<st[i]<< ; } int valid(int k) { for (int i=1;i<k;i++) if (st[i]==st[k]) return 0; return 1; } void back() {k=1; while (k>0) if (k==n+1) {nrsol++; cout<<"Solutia cu nr: "<<nrsol<<endl;
7

i k

tipar(); cout<<endl; k--; } else if (st[k]<n) {st[k]++; if (valid(k)) k++; } else {st[k]=0; k--; } } void main() {cout<<"n="; cin>>n; back(); cout<<endl; cout<<"nrsol="<<nrsol; } Generarea aranjamentelor Anp
Anp = n! ( n p )!

Exp: {1,2,3} p=2


2 A3 =

3! =6 1!

1,2 1,3 2,1 2,3 3,1 3,2 Dim. sol: p Condiii interne: st[i]!=st[k] i k #include<iostream.h> int st[10],n,i,k, nrsol=0, p;

void init() {for (i=1;i<=p;i++) st[i]=0; } void tipar() {for (i=1;i<=p;i++) cout<<st[i]<<" "; cout<<endl; } int valid (int k) { for (i=1;i<k;i++) if (st[i]==st[k]) return 0; return 1; } void back() { k=1; while (k>0) if (k==p+1) {nrsol++; cout<<"Solutia cu nr. "<<nrsol<<" este:"<<endl; tipar(); k--; } else if (st[k]<n) {st[k]++; if (valid(k)) k++; } else {st[k]=0; k--; } } void main() {cout<<"n="; cin>>n;
9

cout<<"p=";cin>>p; init(); back(); cout<<endl; cout<<"Nr. sol ="<<nrsol<<endl; } Generarea combinrilor Cnk
C np = n! ( n p )! p!

Exp: {1,2,3} p=2


2 C3 =

3! =3 1 !2!

1,2 1,3 2,3 Dim. sol: p Condiii interne: st[k]>st[k-1] #include<iostream.h> int st[10],n,i,k,nrsol=0,p; void init() {for (i=1;i<=p;i++) st[i]=0; } void tipar() {for (i=1;i<=p;i++) cout<<st[i]<<" "; cout<<endl; } int valid (int k) { if (k==1) return 1; if (st[k]>st[k-1]) return 1;
k >1

10

else return 0; } void back() { k=1; while (k>0) if (k==p+1) {nrsol++; cout<<"Solutia cu nr. "<<nrsol<<" este:"<<endl; tipar(); k--; } else if (st[k]<n) {st[k]++; if (valid(k)) k++; } else {st[k]=0; k--; } } void main() {cout<<"n="; cin>>n; cout<<"p=";cin>>p; init(); back(); cout<<endl; cout<<"Nr. sol ="<<nrsol<<endl; } Problema celor n dame pe o tabl de ah Fiind dat o tabl de ah, de dimensiune n, xn, se cer toate soluiile de aranjare a n dame, astfel nct s nu se afle dou dame pe aceeai linie, coloan sau diagonal (dame s nu se atace reciproc). Exemplu: Presupunnd c dispunem de o tabl de dimensiune 4x4, o soluie ar fi urmtoarea:

11

D D D D

Observm c o dam trebuie s fie plasat singur pe linie. Plasm prima dam pe linia 1, coloana 1. D

A doua dam nu poate fi aezat dect n coloana 3. D D

Observm c a treia dam nu poate fi plasat n linia 3. ncercm atunci plasarea celei de-a doua dame n coloana 4. D D

12

A treia dam nu poate fi plasat dect n coloana 2. D D D

n aceast situaie dama a patra nu mai poate fi aezat. ncercnd s avansm cu dama a treia, observm c nu este posibil s o plasm nici n coloana 3, nici n coloana 4, deci o vom scoate de pe tabl. Dama a doua nu mai poate avansa, deci i ea este scoas de pe tabl. Avansm cu prima dam n coloana 2. D

A doua dam nu poate fi aezat dect n coloana 4. D D

Dama a treia se aeaz n prima coloan.

13

D D D

Acum este posibil s plasm a patra dam n coloana 3 si astfel am obinut o soluie a problemei. D D D D

Algoritmul continu n acest mod pn cnd trebuie scoas de pe tabl prima dam. Pentru reprezentarea unei soluii putem folosi un vector cu n componente (avnd n vedere c pe fiecare linie se gsete o singur dam). Exemplu pentru soluia gsit avem vectorul ST ce poate fi asimilat unei stive. Dou dame se gsesc pe aceeai diagonal dac si numai dac este ndeplinit condiia: |st(i)-st(j)|=|i-j| ( diferena, n modul, ntre linii si coloane este aceeai). 3 ST(4) 1 4 2 ST(3) n general ST(i)=k semnific faptul c pe linia i dama ocup poziia k. ST(2) ST(1) Exemplu: n tabla 4 x4 avem situaia:

14

D D D

st(1)= 1 i = 1

D st(3)= 3 j = 3 |st(1) - st(3)| = |1 3| = 2 |i j| = |1 3| = 2 sau situaia D D D D st(3) = 1 j = 3 |st(i) - st(j)| = |3 1| = 2 |i j| = |1 3| = 2 ntruct doua dame nu se pot gsi n aceeai coloan, rezult c o soluie este sub form de permutare. O prim idee ne conduce la generarea tuturor permutrilor si la extragerea soluiilor pentru problema ca dou dame s nu fie plasate n aceeai diagonal. A proceda astfel, nseamn c lucrm conform strategiei backtracking. Aceasta presupune ca imediat ce am gsit dou dame care se atac, s relum cutarea. lat algoritmul, conform strategiei generate de backtracking: - n prima poziie a stivei se ncarc valoarea 1, cu semnificaia c n linia unu se aeaz prima dam n coloan. - Linia 2 se ncearc aezarea damei n coloana 1, acest lucru nefiind posibil ntruct avem doua dame pe aceeai coloan. - n linia 2 se ncearc aezarea damei n coloana 2 , ns acest lucru nu este posibil, pentru c damele se gsesc pe aceiai diagonal (|st(1)-st(2)|=|1-2|); - Aezarea damei 2 n coloana 3 este posibil. - Nu se poate plasa dama 3 n coloana 1, ntruct n liniile 1-3 damele ocupa acelai coloan. - i aceast ncercare eueaz ntruct damele de pe 2 i 3 sunt pe aceeai diagonal. - Damele de pe 2-3 se gsesc pe aceeai coloan. - Damele de pe 2-3 se gsesc pe aceeai diagonal. - Am cobort n stiv mutnd dama de pe linia 2 i coloana 3 n coloana 4. Algoritmul se ncheie atunci cnd stiva este vid.
15

st(1) = 3 i = 1

Conditii interne:
st[i ] { 1,2,..., n} st[i ] st[ j ], i j , i, j = 1, nDamele nu pot fi plasate pe aceeasi coloana i j st[i ] st[ j ] , i j , i, j = 1, n

Damele nu pot fi plasate pe aceeasi diagonala

#include<iostream.h> #include<math.h> int st[10],n,i,k,nrsol=0,j; void init() {for (i=1;i<=n;i++) st[i]=0; } void tipar() {for (i=1;i<=n;i++) {for (j=1;j<=n;j++) if (st[i]==j) cout<<" R "; else cout<<" * "; cout<<endl; } } int valid (int k) { for (i=1;i<k;i++) if (st[i]==st[k] || abs(i-k)==abs(st[i]-st[k])) return 0; return 1; } void back() {

16

k=1; while (k>0) if (k==n+1) {nrsol++; cout<<"Solutia cu nr. "<<nrsol<<" este:"<<endl; tipar(); k--; } else if (st[k]<n) {st[k]++; if (valid(k)) k++; } else {st[k]=0; k--; } } void main() {cout<<"n="; cin>>n; init(); back(); cout<<endl; cout<<"Nr. sol ="<<nrsol<<endl; }

17