metoda backtracking

87
Metoda Backtracking 1. Aspecte teoretice 2. Exemplu pentru înţelegerea metodei 3. Permut ări 4. Aranjamente 5. Combin ări 6. Problema celor n dame 7. Problema color ării hărţilor 8. Problema comis voiajorului 9. Problema pla ţii unei sume s utilizând m tipuri de mone de 10. Backtracking recursiv 11. Aranjamente si permutari rezolvate recursiv

Upload: lulu

Post on 06-Feb-2016

177 views

Category:

Documents


1 download

DESCRIPTION

Metoda Backtracking. Aspecte teoretice Exemplu pentru înţelegerea metodei Permut ări Aranjamente Combin ări Problema celor n dame Problema color ării hărţilor Problema comis voiajorului Problema pla ţii unei sume s utilizând m tipuri de monede Backtracking recursiv - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Metoda Backtracking

Metoda BacktrackingMetoda Backtracking

1. Aspecte teoretice2. Exemplu pentru înţelegerea metodei3. Permutări4. Aranjamente5. Combinări6. Problema celor n dame7. Problema colorării hărţilor8. Problema comis voiajorului9. Problema pla

ţii unei sume s utilizând m tipuri de monede10. Backtracking recursiv11. Aranjamente si permutari rezolvate recursiv

1. Aspecte teoretice2. Exemplu pentru înţelegerea metodei3. Permutări4. Aranjamente5. Combinări6. Problema celor n dame7. Problema colorării hărţilor8. Problema comis voiajorului9. Problema pla

ţii unei sume s utilizând m tipuri de monede10. Backtracking recursiv11. Aranjamente si permutari rezolvate recursiv

Page 2: Metoda Backtracking

1. Aspecte teoretice1. Aspecte teoretice

Metoda Backtracking este o metodă de elaborare a algoritmilor. Ea se aplică problemelor în care soluţia se poate reprezenta sub forma unui vector, X=(x1,x2,...xm), care aparţine lui S=S1xS2x...Sm

- S=S1xS2x...Sm se numeşte spaţiul soluţiilor posibile

- Pentru fiecare problemă în parte se dau anumite condiţii între componentele vectorului soluţie care se numesc condiţii interne

- Soluţiile posibile care verifică condiţiile interne se numesc soluţii rezultat

- Metoda Backtracking îşi propune să genereze toate soluţiile rezultat

Metoda Backtracking este o metodă de elaborare a algoritmilor. Ea se aplică problemelor în care soluţia se poate reprezenta sub forma unui vector, X=(x1,x2,...xm), care aparţine lui S=S1xS2x...Sm

- S=S1xS2x...Sm se numeşte spaţiul soluţiilor posibile

- Pentru fiecare problemă în parte se dau anumite condiţii între componentele vectorului soluţie care se numesc condiţii interne

- Soluţiile posibile care verifică condiţiile interne se numesc soluţii rezultat

- Metoda Backtracking îşi propune să genereze toate soluţiile rezultat

Page 3: Metoda Backtracking

O metodă simplă de a genera soluţiile rezultat constă în a genera într-un mod oarecare toate soluţiile posibile şi de a alege dintre acestea doar pe cele care verifică condiţiile interne. Dezavantajul constă în faptul că timpul cerut este foarte mare.

O metodă simplă de a genera soluţiile rezultat constă în a genera într-un mod oarecare toate soluţiile posibile şi de a alege dintre acestea doar pe cele care verifică condiţiile interne. Dezavantajul constă în faptul că timpul cerut este foarte mare.

Page 4: Metoda Backtracking

Metoda Backtracking urmăreşte să evite generarea tuturor soluţiilor posibile. Pentru aceasta elementele vectorului x primesc pe rând valori în sensul că lui xk i se atribuie o valoare doar dacă componentele din faţa sa x1, x2,...xk-1 au primit valori.

Dacă lui xk i s-a atribuit o valoare, nu se trece direct la atribuirea de valori lui xk+1, ci se verifică nişte condiţii de continuare, referitoare la x1, x2,...xk-1 xk. Dacă condiţiile de continuare au fost satisfăcute, se trece la calculul lui xk+1. Neîndeplinirea lor exprimă faptul că oricum s-ar alege xk+1,...,xn, nu se va ajunge la o soluţie rezultat. Evident, ca în cazul neîndeplinirii condiţiilor de continuare va trebui să se facă o altă alegere pentru xk. Sau dacă Sk a fost epuizat, să se micşoreze k cu o unitate, încercând să se facă o nouă alegere pentru xk.

Metoda Backtracking urmăreşte să evite generarea tuturor soluţiilor posibile. Pentru aceasta elementele vectorului x primesc pe rând valori în sensul că lui xk i se atribuie o valoare doar dacă componentele din faţa sa x1, x2,...xk-1 au primit valori.

Dacă lui xk i s-a atribuit o valoare, nu se trece direct la atribuirea de valori lui xk+1, ci se verifică nişte condiţii de continuare, referitoare la x1, x2,...xk-1 xk. Dacă condiţiile de continuare au fost satisfăcute, se trece la calculul lui xk+1. Neîndeplinirea lor exprimă faptul că oricum s-ar alege xk+1,...,xn, nu se va ajunge la o soluţie rezultat. Evident, ca în cazul neîndeplinirii condiţiilor de continuare va trebui să se facă o altă alegere pentru xk. Sau dacă Sk a fost epuizat, să se micşoreze k cu o unitate, încercând să se facă o nouă alegere pentru xk.

Page 5: Metoda Backtracking

2. Exemplu pentru înţelegerea metodei

2. Exemplu pentru înţelegerea metodei

Pentru a înţelege mai uşor prezentăm următorul exemplu:

Presupunem că dorim să ne îmbrăcăm de la un magazin pentru o festivitate şi dorim să cumpărăm: pantofi, ciorapi, pantaloni, cămaşă şi cravata astfel încât acestea să se asorteze între ele, să se genereze toate modalităţile de a ne îmbrăca.

Magazinul are:5 etajeLa etajul 1 are 10 raioane cu pantofiLa etajul 2 are 10 raioane cu ciorapiLa etajul 3 are 10 raioane cu pantaloniLa etajul 4 are 10 raioane cu cămăşiLa etajul 5 are 10 raioane cu cravate

Pentru a înţelege mai uşor prezentăm următorul exemplu:

Presupunem că dorim să ne îmbrăcăm de la un magazin pentru o festivitate şi dorim să cumpărăm: pantofi, ciorapi, pantaloni, cămaşă şi cravata astfel încât acestea să se asorteze între ele, să se genereze toate modalităţile de a ne îmbrăca.

Magazinul are:5 etajeLa etajul 1 are 10 raioane cu pantofiLa etajul 2 are 10 raioane cu ciorapiLa etajul 3 are 10 raioane cu pantaloniLa etajul 4 are 10 raioane cu cămăşiLa etajul 5 are 10 raioane cu cravate

Page 6: Metoda Backtracking

Deoarece soluţia are mai multe componente, 5 – câte etaje are magazinul, putem folosi metoda Backtracking. Pentru rezolvare vom folosi:

k : variabilă întreagă care reprezintă etajul pe care ne găsim

x : vector care are 5 componente întregi, adică exact câte etaje are magazinul cu proprietatea că xk reprezintă numărul raionului de la care s-a cumpărat pe etajul k. În cazul de faţă xk {1,...,10} unde k{1,...,5}

as este o variabilă întreagă care primeşte valoarea 1 dacă pe etajul k mai sunt raioane nevizitate şi primeşte valoarea 0 dacă pe etajul k nu mai sunt raioane nevizitate.

ev este o variabilă întreagă care primeşte valoarea 1 dacă ce este la raionul xk convine şi primeşte valoarea 0 dacă ce este la raionul xk nu convine.

Deoarece soluţia are mai multe componente, 5 – câte etaje are magazinul, putem folosi metoda Backtracking. Pentru rezolvare vom folosi:

k : variabilă întreagă care reprezintă etajul pe care ne găsim

x : vector care are 5 componente întregi, adică exact câte etaje are magazinul cu proprietatea că xk reprezintă numărul raionului de la care s-a cumpărat pe etajul k. În cazul de faţă xk {1,...,10} unde k{1,...,5}

as este o variabilă întreagă care primeşte valoarea 1 dacă pe etajul k mai sunt raioane nevizitate şi primeşte valoarea 0 dacă pe etajul k nu mai sunt raioane nevizitate.

ev este o variabilă întreagă care primeşte valoarea 1 dacă ce este la raionul xk convine şi primeşte valoarea 0 dacă ce este la raionul xk nu convine.

Page 7: Metoda Backtracking

se pleacă de la primul etajdin faţa uşiiatâta timp cât încă ne aflăm la un etaj , k

repetămne întrebăm dacă mai sunt raioane pe etajul kdacă da, atunci

se verifică dacă ne convine ce conţine raionul care urmeazăatâta timp cât mai sunt raioane şi nu am găsit ce ne place.dacă am găsit atunci

dacă le-am luat pe toate atunci

se afişeazăaltfel

se merge la etajul următor în faţa uşiialtfel

se coboară la etajul de jos

se pleacă de la primul etajdin faţa uşiiatâta timp cât încă ne aflăm la un etaj , k

repetămne întrebăm dacă mai sunt raioane pe etajul kdacă da, atunci

se verifică dacă ne convine ce conţine raionul care urmeazăatâta timp cât mai sunt raioane şi nu am găsit ce ne place.dacă am găsit atunci

dacă le-am luat pe toate atunci

se afişeazăaltfel

se merge la etajul următor în faţa uşiialtfel

se coboară la etajul de jos

Cum se procedează:

Page 8: Metoda Backtracking

k=1; (se pleacă de la primul etaj)x[k]=0; (din faţa uşii)while (k>0) (atâta timp cât încă ne aflăm la un etaj , k)

{do (repetăm)

{succ(x,k,as); (ne întrebăm dacă mai sunt raioane pe etajul k)if(as) (dacă da, atunci)

valid(x,k,ev); (se verifică dacă ne convine ce conţine raionul care urmează)

}while(as&&!ev); (atâta timp cât mai sunt raioane şi nu am gasit ce ne

place.)if (as) (dacă am găsit atunci)

if(k==5) (dacă le-am luat pe toate atunci)afis(x,k) (se afişează)

else (altfel){

k=k+1; (se merge la etajul următor)x[k]=0; (în faţa uşii)

}else (altfel)

k=k-1; (se coboară la etajul de jos)}

k=1; (se pleacă de la primul etaj)x[k]=0; (din faţa uşii)while (k>0) (atâta timp cât încă ne aflăm la un etaj , k)

{do (repetăm)

{succ(x,k,as); (ne întrebăm dacă mai sunt raioane pe etajul k)if(as) (dacă da, atunci)

valid(x,k,ev); (se verifică dacă ne convine ce conţine raionul care urmează)

}while(as&&!ev); (atâta timp cât mai sunt raioane şi nu am gasit ce ne

place.)if (as) (dacă am găsit atunci)

if(k==5) (dacă le-am luat pe toate atunci)afis(x,k) (se afişează)

else (altfel){

k=k+1; (se merge la etajul următor)x[k]=0; (în faţa uşii)

}else (altfel)

k=k-1; (se coboară la etajul de jos)}

Reprezentarea a ceea ce s-a spus mai sus este:

Page 9: Metoda Backtracking

Cum ne dăm seama dacă mai sunt raioane la etajul

k?

Cum ne dăm seama dacă mai sunt raioane la etajul

k?dacă numărul raionului de la etajul k este mai mic decât 10

atuncimai sunt raioane pe etajul kşi mergem la raionul următor

altfelnu mai sunt raioane pe etajul k

dacă numărul raionului de la etajul k este mai mic decât 10

atuncimai sunt raioane pe etajul kşi mergem la raionul următor

altfelnu mai sunt raioane pe etajul k

Page 10: Metoda Backtracking

void succ(sir x,int k,int &as) (funcţia care determină dacă mai sunt raioane la etajul k){

if(x[k]<10) (dacă numărul raionului de la etajul k este mai mic decât 10)

{ (atunci)as=1; (mai sunt raioane pe etajul k)x[k]=x[k]+1 (şi mergem la raionul

următor)}

else (altfel)as=0; (nu mai sunt raioane pe etajul k)}

void succ(sir x,int k,int &as) (funcţia care determină dacă mai sunt raioane la etajul k){

if(x[k]<10) (dacă numărul raionului de la etajul k este mai mic decât 10)

{ (atunci)as=1; (mai sunt raioane pe etajul k)x[k]=x[k]+1 (şi mergem la raionul

următor)}

else (altfel)as=0; (nu mai sunt raioane pe etajul k)}

Page 11: Metoda Backtracking

Cum se realizează afişarea

Cum se realizează afişarea

pentru i de la 1 la kse afişează x[i]

cursorul trece la linia următoare

pentru i de la 1 la kse afişează x[i]

cursorul trece la linia următoare

Page 12: Metoda Backtracking

void afis(sir x, int k){int i;

for(i=1;i<=k;i++) (pentru i de la 1 la k)cout<<x[i]<<” ”; (se afişează x[i])

cout<<endl; (cursorul trece la linia următoare)

}

void afis(sir x, int k){int i;

for(i=1;i<=k;i++) (pentru i de la 1 la k)cout<<x[i]<<” ”; (se afişează x[i])

cout<<endl; (cursorul trece la linia următoare)

}

Page 13: Metoda Backtracking

void valid(int &ev){

ev=1; (presupunem că orice alegere de haine ne convine)

}

void valid(int &ev){

ev=1; (presupunem că orice alegere de haine ne convine)

}

Page 14: Metoda Backtracking

Pentru realizarea programului se parcurg următoarele etape:

construirea tipului sir declararea tuturor variabilelor care apar în cadrul programului principal

realizarea funcţiei succ realizarea funcţiei valid realizarea funcţiei afiş programul principal care conţine rutina principală

Pentru realizarea programului se parcurg următoarele etape:

construirea tipului sir declararea tuturor variabilelor care apar în cadrul programului principal

realizarea funcţiei succ realizarea funcţiei valid realizarea funcţiei afiş programul principal care conţine rutina principală

Page 15: Metoda Backtracking

construirea tipului sirconstruirea tipului sir

#include<iostream.h>#include<stdio.h>typedef int sir[100];sir x;

#include<iostream.h>#include<stdio.h>typedef int sir[100];sir x;

Page 16: Metoda Backtracking

declararea tuturor variabilelor care apar în cadrul programului principal

declararea tuturor variabilelor care apar în cadrul programului principal

int k, as,ev; int k, as,ev;

Page 17: Metoda Backtracking

realizarea funcţiei succrealizarea funcţiei succ

void succ(sir x, int k, int&as){if(x[k]<10)

{as=1;x[k]=x[k]+1;

}else as=0;}

void succ(sir x, int k, int&as){if(x[k]<10)

{as=1;x[k]=x[k]+1;

}else as=0;}

Verific dacă mai sunt sau nu raioane pe etajul k

Page 18: Metoda Backtracking

realizarea funcţiei validrealizarea funcţiei valid

void valid(int&ev){

ev=1;}

void valid(int&ev){

ev=1;}

Am găsit ce îmi place

Page 19: Metoda Backtracking

realizarea funcţiei afişrealizarea funcţiei afiş

void afis(sir x,int k){int i;

for(i=1;i<=k;i++)cout<<x[i]<<" ";

cout<<endl;}

void afis(sir x,int k){int i;

for(i=1;i<=k;i++)cout<<x[i]<<" ";

cout<<endl;}

Afişarea rezultatului

Page 20: Metoda Backtracking

programul principal care conţine rutina

principală

programul principal care conţine rutina

principalăint main(void){k=1;x[k]=0;while(k>0){

do{

succ(x,k,as);if (as)

valid(ev);}

while(as&&!ev);

int main(void){k=1;x[k]=0;while(k>0){

do{

succ(x,k,as);if (as)

valid(ev);}

while(as&&!ev);

if(as)if(k==5)

afis(x,k);else

{

k=k+1;

x[k]=0;}

else k=k-1;}}

Page 21: Metoda Backtracking

ComentariiComentarii

1. Dacă la etajul 1 ar fi fost n1 raioanela etajul 2 ar fi fost n2 raioane

.......la etajul k ar fi fost nk raioane

Funcţia succesor se modifică astfel:

1. Dacă la etajul 1 ar fi fost n1 raioanela etajul 2 ar fi fost n2 raioane

.......la etajul k ar fi fost nk raioane

Funcţia succesor se modifică astfel:

void succ(sir x, int k, int&as)

{if(x[k]<n[k])

{as=1;x[k]=x[k]

+1;}

else as=0;}

void succ(sir x, int k, int&as)

{if(x[k]<n[k])

{as=1;x[k]=x[k]

+1;}

else as=0;}

Page 22: Metoda Backtracking

ComentariiComentarii

2. Dacă magazinul are m etaje atunci condiţia „dacă s-au făcut toate cumpărăturile” sau „s-a ajuns la ultimul etaj” se scrie

if(k==m)

2. Dacă magazinul are m etaje atunci condiţia „dacă s-au făcut toate cumpărăturile” sau „s-a ajuns la ultimul etaj” se scrie

if(k==m)

Page 23: Metoda Backtracking

ComentariiComentarii

3. Dacă la fiecare etaj numărul de magazine este variabil (nu 10) condiţia de testare din funcţia succesor este

if(x[k]<n[k])

3. Dacă la fiecare etaj numărul de magazine este variabil (nu 10) condiţia de testare din funcţia succesor este

if(x[k]<n[k])

Page 24: Metoda Backtracking

Atunci când nu există condiţii între componentele vectorului soluţie funcţia valid are forma:

void valid(int&ev){

ev=1;}

Atunci când nu există condiţii între componentele vectorului soluţie funcţia valid are forma:

void valid(int&ev){

ev=1;}

Page 25: Metoda Backtracking

Atunci când componentele vectorului soluţie trebuie să fie distincte trebuie arătat că xkxi pentru i=1...k-1 se procedează astfel:

- se presupune că xk este diferit de toate elementele din faţa sa- se parcurg indicii 1...k-1 cu i- dacă xk nu este diferit de xi, atunci presupunerea este falsă

void valid(int&ev){

int i;ev=1;for(i=1;i<=k-1;i++)

if(!(x[k]!=x[i]))ev=0;

}

Atunci când componentele vectorului soluţie trebuie să fie distincte trebuie arătat că xkxi pentru i=1...k-1 se procedează astfel:

- se presupune că xk este diferit de toate elementele din faţa sa- se parcurg indicii 1...k-1 cu i- dacă xk nu este diferit de xi, atunci presupunerea este falsă

void valid(int&ev){

int i;ev=1;for(i=1;i<=k-1;i++)

if(!(x[k]!=x[i]))ev=0;

}

X[k] nu este diferit de x[i]

Page 26: Metoda Backtracking

PermutăriPermutăriO permutare a unei mulţimi cu n elemente este un şir

de elemente obţinut prin schimbarea ordinii elementelor mulţimii date sau chiar mulţimea însăşi.

Ne gândim la generarea permutărilor atunci când se dă o mulţime cu n elemente ca date de intrare iar soluţia este sub forma de vector, tot cu n elemente, ale cărui componente sunt distincte şi aparţin mulţimii date.

Exemplu: Fie A={1,2,3}. Permutările mulţimii A sunt: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), (3,2,1).

Fie A={a1, a2,…,am} o mulţime cu elemente de tip întreg. Trebuie determinate elementele mulţimii { y1, y2,…,ym }| ykA, k=1,2,...,m, pentru yiyj pentru ij}.

Deci, x=( x1, x2,…,xm) unde x{1,...,m}, elementele vectorului x trebuie să fie distincte.

O permutare a unei mulţimi cu n elemente este un şir de elemente obţinut prin schimbarea ordinii elementelor mulţimii date sau chiar mulţimea însăşi.

Ne gândim la generarea permutărilor atunci când se dă o mulţime cu n elemente ca date de intrare iar soluţia este sub forma de vector, tot cu n elemente, ale cărui componente sunt distincte şi aparţin mulţimii date.

Exemplu: Fie A={1,2,3}. Permutările mulţimii A sunt: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), (3,2,1).

Fie A={a1, a2,…,am} o mulţime cu elemente de tip întreg. Trebuie determinate elementele mulţimii { y1, y2,…,ym }| ykA, k=1,2,...,m, pentru yiyj pentru ij}.

Deci, x=( x1, x2,…,xm) unde x{1,...,m}, elementele vectorului x trebuie să fie distincte.

Page 27: Metoda Backtracking

Programul:Programul:

#include<iostream.h>#include<stdio.h>typedef int sir[100];sir x;int i,k,m;int as,ev;sir a;

#include<iostream.h>#include<stdio.h>typedef int sir[100];sir x;int i,k,m;int as,ev;sir a;

Page 28: Metoda Backtracking

void succ(sir x, int k, int &as){if(x[k]<m)

{as=1;x[k]=x[k]+1;

}else as=0;}

void succ(sir x, int k, int &as){if(x[k]<m)

{as=1;x[k]=x[k]+1;

}else as=0;}

Page 29: Metoda Backtracking

void valid(sir x, int k, int &as){int i;ev =1;for(i=1;i<=k-1;i++)

if(!(x[i]!=x[k]))ev=0;

}

void valid(sir x, int k, int &as){int i;ev =1;for(i=1;i<=k-1;i++)

if(!(x[i]!=x[k]))ev=0;

}

Page 30: Metoda Backtracking

void afis(sir x, int k){int i;for(i=1;i<=k;i++)

cout<<a[x[i]]<<" ";cout<<endl;}

void afis(sir x, int k){int i;for(i=1;i<=k;i++)

cout<<a[x[i]]<<" ";cout<<endl;}

Page 31: Metoda Backtracking

int main(void){cout<<"m=";cin>>m;for(i=1;i<=m;i++)

cin>>a[i];k=1;x[k]=0;while(k>0)

{do{succ(x,k,as);

if(as) valid(x,k,ev);

}while(as&&!ev);

int main(void){cout<<"m=";cin>>m;for(i=1;i<=m;i++)

cin>>a[i];k=1;x[k]=0;while(k>0)

{do{succ(x,k,as);

if(as) valid(x,k,ev);

}while(as&&!ev);

if(as) if(k==m) afis(x,k);else

{k=k+1;x[k]=0;

}else k=k-1;}}

if(as) if(k==m) afis(x,k);else

{k=k+1;x[k]=0;

}else k=k-1;}}

Page 32: Metoda Backtracking

AranjamenteAranjamente

Se dau două mulţimi A={1,2,…,p} şi B={1,2,…,m} se cer toate funcţiile injective definite pe A cu valori în B. O astfel de problemă este una de generare a aranjamentelor de n luate cate p (An

p).

Exemplu: p=2, n=3. Avem (1,2), (2,1), (1,3), (3,1), (2,3), (3,2). De exemplu (2,1) este funcţia f:A→B dată astfel f(1)=2, f(2)=1. Avem relaţiile: =m(m-1)...(m-p+1).

Se dau două mulţimi A={1,2,…,p} şi B={1,2,…,m} se cer toate funcţiile injective definite pe A cu valori în B. O astfel de problemă este una de generare a aranjamentelor de n luate cate p (An

p).

Exemplu: p=2, n=3. Avem (1,2), (2,1), (1,3), (3,1), (2,3), (3,2). De exemplu (2,1) este funcţia f:A→B dată astfel f(1)=2, f(2)=1. Avem relaţiile: =m(m-1)...(m-p+1).

Page 33: Metoda Backtracking

Avem relaţiile:Avem relaţiile:)(

!

pm

mA pn

= m(m-1)...(m-p+1).

Se citesc m şi p. Să se genereze toate aranjamentele de m luate câte p.

Se observă că dacă se cunoaşte fiecare submulţime de p elemente a mulţimii de m elemente, atunci aranjamentele se pot obţine permutând în toate modurile posibile elementele unei astfel de mulţimi.

O soluţie este de forma: x1,x2,...xp unde x1,x2,...xpB. În plus x1,x2,...xp trebuie să fie distincte. O soluţie are p numere din mulţimea B şi numerele trebuie să fie distincte.

De aici rezultă că algoritmul este acelaşi ca la permutări, diferenţa fiind dată de faptul că soluţia are p numere, nu m ca în cazul permutărilor.

Page 34: Metoda Backtracking

#include<iostream.h>#include<stdio.h>typedef int sir[100];sir x;int i,k,m,p;int as,ev;sir a;

void succ(sir x, int k, int &as){if(x[k]<m)

{as=1;x[k]=x[k]+1;

}else as=0;}

Page 35: Metoda Backtracking

void valid(sir x, int k, int &as){int i;ev =1;for(i=1;i<=k-1;i++)

if(x[k]==x[i])ev=0;

}

void afis(sir x, int k){int i;for(i=1;i<=k;i++)

cout<<a[x[i]]<<" ";cout<<endl;

}

se verifică dacă xkxi unde i=1,2,...,k-1

se afişează elementele din mulţimea A care corespund poziţiilor date de elementele

vectorului x

Page 36: Metoda Backtracking

int main(void){cout<<"m=";cin>>m;for(i=1;i<=m;i++)

cin>>a[i];cout<<"p=";cin>>p;

k=1;x[k]=0;while(k>0)

{do

{succ(x,k,as);

if(as) valid(x,k,ev);}

while(as&&!ev);if(as)

if(k==p) afis(x,k);else{

k=k+1;x[k]=0;

}else k=k-1;

}}

Page 37: Metoda Backtracking

CombinăriCombinări

Fiind dată o mulţime A cu n elemente, a combina elementele mulţimii în grupe de câte p<n elemente înseamnă a determina toţi vectorii cu p elemente ale căror componente aparţin mulţimii A şi sunt sortate crescător.

Ne gândim la generarea combinărilor atunci când se dă o mulţime cu n elemente ca date de intrare iar soluţia este sub forma unui vector cu p<n elemente, astfel încât să nu aibă importanţă ordinea pe care o au în cadrul şirului. Componentele sunt sortate crescător şi aparţin mulţimii date.

Fie A={1,2,3}. Combinările mulţimii A în grupe de câte două elemente sunt (1,2), (1,3), (2,3).

Fiind dată o mulţime A cu n elemente, a combina elementele mulţimii în grupe de câte p<n elemente înseamnă a determina toţi vectorii cu p elemente ale căror componente aparţin mulţimii A şi sunt sortate crescător.

Ne gândim la generarea combinărilor atunci când se dă o mulţime cu n elemente ca date de intrare iar soluţia este sub forma unui vector cu p<n elemente, astfel încât să nu aibă importanţă ordinea pe care o au în cadrul şirului. Componentele sunt sortate crescător şi aparţin mulţimii date.

Fie A={1,2,3}. Combinările mulţimii A în grupe de câte două elemente sunt (1,2), (1,3), (2,3).

Page 38: Metoda Backtracking

#include<iostream.h>#include<stdio.h>typedef int sir[100];sir x;int i,k,m,p;int as,ev;sir a;

void succ(sir x, int k, int &as){if(x[k]<m)

{as=1;x[k]=x[k]+1;

}else as=0;}

Page 39: Metoda Backtracking

void valid(sir x, int k, int &as){int i;ev =1;for(i=1;i<=k-1;i++)if((k>=2)&&!(a[x[k]]>a[x[k-1]])) ev=0;}

void afis(sir x, int k){int i;for(i=1;i<=k;i++)

cout<<a[x[i]]<<" "; cout<<endl;

}

se verifică dacă componentele aparţin mulţimii date şi sunt

sortate crescător

se afişează elementele din mulţimea A care corespund poziţiilor date de elementele

vectorului x

Page 40: Metoda Backtracking

int main(void){cout<<"m=";cin>>m;for(i=1;i<=m;i++)

cin>>a[i];cout<<"p=";cin>>p;

k=1;x[k]=0;while(k>0)

{do

{succ(x,k,as);

if(as) valid(x,k,ev);}

while(as&&!ev);if(as)

if(k==p) afis(x,k);else{

k=k+1;x[k]=0;

}else k=k-1;

}}

Page 41: Metoda Backtracking

Problema celor n dameProblema celor n dame

Pentru rezolvare se vor folosi:k = variabila întreagă ce reprezintă linia pe

care se aşează a k-a damăx = vector cu componente întregi cu

proprietatea că xk reprezintă coloana pe care se aşează a k-a damă

Deoarece tabla are n linii şi n coloane k{1,2,..,n} si xk{1,2,...,n} adică:

x=(x1,x2,...,xn) unde xk{1,2,…n}, k{1,2,...,n}.

Pentru rezolvare se vor folosi:k = variabila întreagă ce reprezintă linia pe

care se aşează a k-a damăx = vector cu componente întregi cu

proprietatea că xk reprezintă coloana pe care se aşează a k-a damă

Deoarece tabla are n linii şi n coloane k{1,2,..,n} si xk{1,2,...,n} adică:

x=(x1,x2,...,xn) unde xk{1,2,…n}, k{1,2,...,n}.

Page 42: Metoda Backtracking

În desenul de mai jos este ilustrată situaţia în care dama k şi dama i sunt situate pe aceeaşi diagonală.

În desenul de mai jos este ilustrată situaţia în care dama k şi dama i sunt situate pe aceeaşi diagonală.

k

i

xi xk

k-i=xk-xi

(trebuie ca damele să fie aşezateÎn colţurile unui pătrat cu latura K-i, respectiv xk-xi)

Page 43: Metoda Backtracking

În desenul de mai jos este ilustrată situaţia în care dama k şi dama i sunt situate pe aceeaşi diagonală.

În desenul de mai jos este ilustrată situaţia în care dama k şi dama i sunt situate pe aceeaşi diagonală.

k

i

xk xi

k-i=xi-xk

(trebuie ca damele să fie aşezateÎn colţurile unui pătrat cu latura K-i, respectiv xi-xk)

Page 44: Metoda Backtracking

Dama k şi dama i se găsesc pe aceeaşi diagonală dacă k-i=|xk-xi|

Dama k şi dama i se găsesc pe aceeaşi coloană dacă xk=xi.

Dama k şi dama i nu se află e aceeaşi lunie niciodată datorită modului de construire a vectorului x

Dama k şi dama i se găsesc pe aceeaşi diagonală dacă k-i=|xk-xi|

Dama k şi dama i se găsesc pe aceeaşi coloană dacă xk=xi.

Dama k şi dama i nu se află e aceeaşi lunie niciodată datorită modului de construire a vectorului x

Page 45: Metoda Backtracking

Funcţia valid trebuie să verifice dacă dama k nu se află pe aceeaşi coloană sau pe aceeaşi diagonală cu dama i.

Deci trebuie arătat că:

xkxi şi k-i|xk-xi| pentru i=1,2,…,k-1.

adicăif((x[k]==x[i])||(k-i==abs(x[k]-x[i])))

Funcţia valid trebuie să verifice dacă dama k nu se află pe aceeaşi coloană sau pe aceeaşi diagonală cu dama i.

Deci trebuie arătat că:

xkxi şi k-i|xk-xi| pentru i=1,2,…,k-1.

adicăif((x[k]==x[i])||(k-i==abs(x[k]-x[i])))

Page 46: Metoda Backtracking

typedef int sir[100];sir x;int i,k,n;int as,ev;

void succ(sir x, int k, int &as){if(x[k]<n)

{as=1;x[k]=x[k]+1;

}else as=0;}

void valid(sir x, int k, int &ev){ev =1;for(i=1;i<=k-1;i++)

if((x[k]==x[i])||(k-i==abs(x[k]-x[i])))

ev=0;}void afis(sir x,int k){int i;for(i=1;i<=k;i++)

cout<<x[i]<<" ";cout<<endl;}

Page 47: Metoda Backtracking

int main(void){cout<<"n=";cin>>n;k=1;x[k]=0;while(k>0){ do { succ(x,k,as); if(as) valid(x,k,ev); } while(as&&!ev);

if(as) if(k==n) afis(x,k); else {

k=k+1;x[k]=0;

}else k=k-1;

}}

Page 48: Metoda Backtracking

Problema colorării hărţilor

Problema colorării hărţilor

Fiind dată o hartă cu n tări, se cer toate modalităţile de colorare a hărţii, utilizând cel mult m culori, astfel încât două ţări cu frontieră comună să fie colorare diferit. Este demonstrat faptul că sunt suficiente numai 4 culori ca orice hartă să poată fi colorată.

Pentru rezolvare se vor folosi:k: variabilă întreagă, care reprezintă o ţarăx: vector cu componente întregi cu proprietatea

xk reprezintă culoarea ţării cu numărul kdeoarece sunt n ţări şi m culori, k={1,...,n} şi

xk={1,...,m}x=(x1,x2,...,xn) unde xk{1,...,n}.

Fiind dată o hartă cu n tări, se cer toate modalităţile de colorare a hărţii, utilizând cel mult m culori, astfel încât două ţări cu frontieră comună să fie colorare diferit. Este demonstrat faptul că sunt suficiente numai 4 culori ca orice hartă să poată fi colorată.

Pentru rezolvare se vor folosi:k: variabilă întreagă, care reprezintă o ţarăx: vector cu componente întregi cu proprietatea

xk reprezintă culoarea ţării cu numărul kdeoarece sunt n ţări şi m culori, k={1,...,n} şi

xk={1,...,m}x=(x1,x2,...,xn) unde xk{1,...,n}.

Page 49: Metoda Backtracking

esunt vecinnu j tarasi i taradaca 0

esunt vecin j tarasi i taradaca 1

,

,

ji

ji

a

aA

1

2

34

5

Pentru reprezentarea hărţii în program se va folosi matricea de adiacenţă definită astfel:

Exemplu: pentru harta de mai jos:Matricea de adiacenţă este:

01111

10111

11000

11001

11010

A

Page 50: Metoda Backtracking

Concluzie:Ţara k şi ţara i sunt vecine, dacă (ai,k=1) sau

(ak,i=1)

Ţara k şi ţara i au aceeaşi culoare dacă xk=xi

Comentarii la funcţia valid:Trebuie verificat dacă ţara k şi ţara i ce sunt

ţări vecine au culori diferite, adică dacăak,i=1 pentru xkxi, pentru i=1...k-1.

Concluzie:Ţara k şi ţara i sunt vecine, dacă (ai,k=1) sau

(ak,i=1)

Ţara k şi ţara i au aceeaşi culoare dacă xk=xi

Comentarii la funcţia valid:Trebuie verificat dacă ţara k şi ţara i ce sunt

ţări vecine au culori diferite, adică dacăak,i=1 pentru xkxi, pentru i=1...k-1.

Page 51: Metoda Backtracking

#include<iostream.h>#include<math.h>typedef int sir[100];sir x;int m,i,k,n,j;int as,ev;int a[100][100];

void succ(sir x, int k, int &as){if(x[k]<n)

{as=1;x[k]=x[k]+1;

}else as=0;}

Page 52: Metoda Backtracking

void valid(sir x, int k, int &ev){ev =1;for(i=1;i<=k-1;i++)

if((a[k][i]==1)&&(x[k]==x[i]))ev=0;

}

void afis(sir x,int k){int i;for(i=1;i<=k;i++)

cout<<x[i]<<" ";cout<<endl;}

Se verifică dacă ai,k=1 atuncixkxi, unde i=1,...k-1

Page 53: Metoda Backtracking

int main(void){cout<<"Dati numarul de tari:";cin>>n;for(i=1;i<=n;i++)

for(j=1;j<=n;j++){

cin>>a[i][j];a[j]

[i]=a[i][j];}

k=1;x[k]=0;while(k>0) { do { succ(x,k,as); if(as) valid(x,k,ev); } while(as&&!ev); if(as) if(k==n) afis(x,k); else

{ k=k+1; x[k]=0;}

else k=k-1; }}

Page 54: Metoda Backtracking

Problema comis voiajorului

Problema comis voiajorului

Un comis voiajor trebuie să viziteze un număr de n oraşe. Iniţial acesta se află într-unul din ele, notat 1. Comis voiajorul doreşte să nu treacă de două ori prin acelaşi oraş iar la întoarcere să revină în oraşul 1. Cunoscând legăturile existente între oraşe, se cere să se tipărească toate drumurile posibile pe care le poate efectua comis voiajorul.

Un comis voiajor trebuie să viziteze un număr de n oraşe. Iniţial acesta se află într-unul din ele, notat 1. Comis voiajorul doreşte să nu treacă de două ori prin acelaşi oraş iar la întoarcere să revină în oraşul 1. Cunoscând legăturile existente între oraşe, se cere să se tipărească toate drumurile posibile pe care le poate efectua comis voiajorul.

Page 55: Metoda Backtracking

Pentru rezolvarea problemei se vor folosi:k: variabilă întreagă care reprezintă la al

câtelea oraş s-a ajuns (al doilea, al treilea...)

x: vector cu componente întregi, cu proprietatea

că xk reprezintă al k-lea oraş din traseu

Pentru rezolvarea problemei se vor folosi:k: variabilă întreagă care reprezintă la al

câtelea oraş s-a ajuns (al doilea, al treilea...)

x: vector cu componente întregi, cu proprietatea

că xk reprezintă al k-lea oraş din traseu

Page 56: Metoda Backtracking

Pentru a evita parcurgerea unui drum de două ori, se va recurge la strategia de a atribui lui x1 valoarea 1, adică toate drumurile să plece de la primul oraş. Din acest motiv, xk{2,…,n} pentru k{2,…,n}.

x=(x1,x2,…,xn) unde xk{2,…,n} şi x1=1, pentru k{2,…,n}.

Pentru a evita parcurgerea unui drum de două ori, se va recurge la strategia de a atribui lui x1 valoarea 1, adică toate drumurile să plece de la primul oraş. Din acest motiv, xk{2,…,n} pentru k{2,…,n}.

x=(x1,x2,…,xn) unde xk{2,…,n} şi x1=1, pentru k{2,…,n}.

Page 57: Metoda Backtracking

Observaţie: Pentru reprezentarea grafului seva folosi matricea e adiacenţă definită astfel:

ai,j=1, dacă există drum între oraşele i şi j

ai,j=0, dacă nu există drum între oraşele i şi j

Observaţie: Pentru reprezentarea grafului seva folosi matricea e adiacenţă definită astfel:

ai,j=1, dacă există drum între oraşele i şi j

ai,j=0, dacă nu există drum între oraşele i şi j

Page 58: Metoda Backtracking

Exemplu: pentru harta de mai jos, Exemplu: pentru harta de mai jos,

1

2

3

4

5

matricea de adiacenţă este:

00111

00111

11000

11001

11010

A

Page 59: Metoda Backtracking

Concluzii:Între oraşele k şi i există drum dacă ak,i=1 şi (ai,k=1), deci între oraşele xk şi xi există drum dacă a[xk][xi]=1 (şi a[xi][xk]=1)

oraşul xk trebuie să fie diferit de oraşul xi pentru i=1...k-1oraşul xn trebuie să fie vecin cu oraşul x1 adică a[xk][x1]=1

Concluzii:Între oraşele k şi i există drum dacă ak,i=1 şi (ai,k=1), deci între oraşele xk şi xi există drum dacă a[xk][xi]=1 (şi a[xi][xk]=1)

oraşul xk trebuie să fie diferit de oraşul xi pentru i=1...k-1oraşul xn trebuie să fie vecin cu oraşul x1 adică a[xk][x1]=1

Page 60: Metoda Backtracking

Comentarii la funcţia Valid:Trebuie verificat dacă:- există drum între oraşele xk-1 şi xk adică

trebuie de verificat dacă a[xk-1][xk]=1;

- oraşul xk este diferit de toate oraşele prin care s-a trecut adică xkxi pentru i=1..k-1

- dacă s-a ajuns la al n-lea oraş, trebuie să existe un drum între acesta şi primul oraş adică dacă k=n trebuie a[xk][x1]=1

Comentarii la funcţia Valid:Trebuie verificat dacă:- există drum între oraşele xk-1 şi xk adică

trebuie de verificat dacă a[xk-1][xk]=1;

- oraşul xk este diferit de toate oraşele prin care s-a trecut adică xkxi pentru i=1..k-1

- dacă s-a ajuns la al n-lea oraş, trebuie să existe un drum între acesta şi primul oraş adică dacă k=n trebuie a[xk][x1]=1

Page 61: Metoda Backtracking

ProgramulProgramul

#include<iostream.h>#include<math.h>typedef int sir[100];sir x;int i,j,k,n,as,ev;int a[100][100];

#include<iostream.h>#include<math.h>typedef int sir[100];sir x;int i,j,k,n,as,ev;int a[100][100];

Page 62: Metoda Backtracking

void succ(sir x, int k, int &as){if(x[k]<n)

{as=1;x[k]=x[k]+1;

}else as=0;}

void succ(sir x, int k, int &as){if(x[k]<n)

{as=1;x[k]=x[k]+1;

}else as=0;}

Page 63: Metoda Backtracking

void valid(sir x, int k, int &ev){ev =1;if(a[x[k-1]][x[k]]==0) ev=0;else

{for(i=1;i<=k-1;i++)

if(x[i]==x[k]) ev=0;if((k==n)&&(a[x[n]][x[1]]==0))

ev=0;}

}

void valid(sir x, int k, int &ev){ev =1;if(a[x[k-1]][x[k]]==0) ev=0;else

{for(i=1;i<=k-1;i++)

if(x[i]==x[k]) ev=0;if((k==n)&&(a[x[n]][x[1]]==0))

ev=0;}

}

Page 64: Metoda Backtracking

void afis(sir x,int k){int i;for(i=1;i<=k;i++)

cout<<x[i]<<" ";cout<<endl;}

void afis(sir x,int k){int i;for(i=1;i<=k;i++)

cout<<x[i]<<" ";cout<<endl;}

Page 65: Metoda Backtracking

int main(void){cout<<"Dati numarul de orase:";cin>>n;for(i=1;i<=n;i++)

for(j=1;j<=n;j++){

cin>>a[i][j];a[j][i]=a[i][j];

}x[1]=1;k=2;x[k]=1;

int main(void){cout<<"Dati numarul de orase:";cin>>n;for(i=1;i<=n;i++)

for(j=1;j<=n;j++){

cin>>a[i][j];a[j][i]=a[i][j];

}x[1]=1;k=2;x[k]=1;

Page 66: Metoda Backtracking

while(k>1){

do{

succ(x,k,as);if(as) valid(x,k,ev);

}while(as&&!ev);if(as)

if(k==n) afis(x,k);else

{k=k+1;x[k]=1;

}else k=k-1;

}}

while(k>1){

do{

succ(x,k,as);if(as) valid(x,k,ev);

}while(as&&!ev);if(as)

if(k==n) afis(x,k);else

{k=k+1;x[k]=1;

}else k=k-1;

}}

Page 67: Metoda Backtracking

Pentru exemplul dat mai sus, si matricea de adiacenţă corespunzătoare, drumurile posibile sunt:

1 2 4 3 51 2 5 3 41 4 3 5 21 5 3 4 2

Pentru exemplul dat mai sus, si matricea de adiacenţă corespunzătoare, drumurile posibile sunt:

1 2 4 3 51 2 5 3 41 4 3 5 21 5 3 4 2

1

2

3

4

5

Page 68: Metoda Backtracking

Problema plăţii unei sume s utilizând m tipuri de

monede

Problema plăţii unei sume s utilizând m tipuri de

monede Se dau suma s si m tipuri de monede

având valorile a1, a2, ..., am lei. Se cer toate modalităţile de plată a sumei s utilizând aceste monede.

Va trebui să se genereze toţi vectorii de forma X=(x1,...xm), care verifică relaţia:

x1·a1+x2·a2+...+xm·am=S

Se dau suma s si m tipuri de monede având valorile a1, a2, ..., am lei. Se cer toate modalităţile de plată a sumei s utilizând aceste monede.

Va trebui să se genereze toţi vectorii de forma X=(x1,...xm), care verifică relaţia:

x1·a1+x2·a2+...+xm·am=S

Page 69: Metoda Backtracking

Din această relaţie se poate vedea că:x1 poate lua valori între 0 şi n1=

x2 poate lua valori între 0 şi n2=

......................................................xk poate lua valori între 0 şi nk=

.......................................................xm poate lua valori între 0 şi nm=

Trebuie să se determine elementele mulţimii:{x1,…,xm}| xk{0,…,m} unde k=1,…,m şi x1·a1+x2·a2+...

+xm·am=S

Din această relaţie se poate vedea că:x1 poate lua valori între 0 şi n1=

x2 poate lua valori între 0 şi n2=

......................................................xk poate lua valori între 0 şi nk=

.......................................................xm poate lua valori între 0 şi nm=

Trebuie să se determine elementele mulţimii:{x1,…,xm}| xk{0,…,m} unde k=1,…,m şi x1·a1+x2·a2+...

+xm·am=S

1a

S

ma

S

ka

S

2a

S

Page 70: Metoda Backtracking

Exemplu: S=3; m=2, a[1]=1, a[2]=2.Programul va genera soluţiile:(1,1) ce corespunde la

1·a1+1·a2=1·1+1·2=3(3,0) ce corespunde la

3·a1+0·a2=3·1+0·2=3

Exemplu: S=3; m=2, a[1]=1, a[2]=2.Programul va genera soluţiile:(1,1) ce corespunde la

1·a1+1·a2=1·1+1·2=3(3,0) ce corespunde la

3·a1+0·a2=3·1+0·2=3

Page 71: Metoda Backtracking

0 1 … nm

0 1 … nm-1

… … … … …

0 1 … n2

0 1 … n1

1

k

m

xk nk

Page 72: Metoda Backtracking

Programul Programul

#include<iostream.h>typedef int sir[100];sir x,n,a;int m,i,k,S,as,ev;

#include<iostream.h>typedef int sir[100];sir x,n,a;int m,i,k,S,as,ev;

Page 73: Metoda Backtracking

void succ(sir x, int k, int &as){if(x[k]<n[k])

{as=1;x[k]=x[k]+1;

}else as=0;}

void succ(sir x, int k, int &as){if(x[k]<n[k])

{as=1;x[k]=x[k]+1;

}else as=0;}

Page 74: Metoda Backtracking

void valid(int &ev){ev =1;}

void valid(int &ev){ev =1;}

Page 75: Metoda Backtracking

void afis(sir x,int k){int i,s1;s1=0;for(i=1;i<=k;i++)

s1=s1+x[i]*a[i];if(S==s1)

{for(i=1;i<=k-1;i++)

cout<<x[i]<<"*"<<a[i]<<"+";cout<<x[k]<<"*"<<a[k]<<"="<<S<<endl;

}}

void afis(sir x,int k){int i,s1;s1=0;for(i=1;i<=k;i++)

s1=s1+x[i]*a[i];if(S==s1)

{for(i=1;i<=k-1;i++)

cout<<x[i]<<"*"<<a[i]<<"+";cout<<x[k]<<"*"<<a[k]<<"="<<S<<endl;

}}

Page 76: Metoda Backtracking

int main(void){cout<<"Dati valoarea sumei:"; cin>>S;cout<<"Dati numarul monedelor m="; cin>>m;cout<<"Dati valorile celor "<<m<<" monede: ";

for(i=1;i<=m;i++){

cin>>a[i];n[i]=S/a[i];

}k=1;x[k]=-1;

int main(void){cout<<"Dati valoarea sumei:"; cin>>S;cout<<"Dati numarul monedelor m="; cin>>m;cout<<"Dati valorile celor "<<m<<" monede: ";

for(i=1;i<=m;i++){

cin>>a[i];n[i]=S/a[i];

}k=1;x[k]=-1;

Page 77: Metoda Backtracking

while(k>0){

do{

succ(x,k,as);if(as) valid(ev);

}while(as&&!ev);if(as)

if(k==m) afis(x,k);else

{k=k+1;x[k]=-1;

}else k=k-1;

}}

while(k>0){

do{

succ(x,k,as);if(as) valid(ev);

}while(as&&!ev);if(as)

if(k==m) afis(x,k);else

{k=k+1;x[k]=-1;

}else k=k-1;

}}

Page 78: Metoda Backtracking

Bactracking recursivBactracking recursivvoid back(int k){

if(solutie(k)) afis(x,k);else

{x[k]=0;while(succ(x,k))

{

valid(x,k,ev)if(ev)

back(k+1);}

}}

void back(int k){

if(solutie(k)) afis(x,k);else

{x[k]=0;while(succ(x,k))

{

valid(x,k,ev)if(ev)

back(k+1);}

}}

1. Funcţia back are un parametru întreg k şi funcţionează astfel:- dacă s-a ajuns la o soluţie, se tipăreşte şi se revine la nivelul anterior- dacă nu s-a ajuns la o soluţie

- se iniţializează nivelul- atâta timp cât este

succesor pe acest nivel- dacă este valid,

funcţia back se autoapelează pentru k+1

- dacă nu este succesor, se trece pe nivelul k-1 prin ieşirea din funcţia back.

Se apelează back(1)

1. Funcţia back are un parametru întreg k şi funcţionează astfel:- dacă s-a ajuns la o soluţie, se tipăreşte şi se revine la nivelul anterior- dacă nu s-a ajuns la o soluţie

- se iniţializează nivelul- atâta timp cât este

succesor pe acest nivel- dacă este valid,

funcţia back se autoapelează pentru k+1

- dacă nu este succesor, se trece pe nivelul k-1 prin ieşirea din funcţia back.

Se apelează back(1)

Page 79: Metoda Backtracking

2. Funcţia succ verifică dacă mai sunt elemente în Sk.3. Funcţia valid verifică dacă sunt satisfăcute condiţiile

de continuare4. Funcţia afiş afişează o soluţie rezultat5. Funcţia soluţie returnează

1 dacă pe nivelul k s-a ajuns la soluţie0 dacă pe nivelul k nu s-a ajuns la soluţie

În general funcţia soluţie se defineşte astfel:int soluţie(int k){

return(k==n+1)}

2. Funcţia succ verifică dacă mai sunt elemente în Sk.3. Funcţia valid verifică dacă sunt satisfăcute condiţiile

de continuare4. Funcţia afiş afişează o soluţie rezultat5. Funcţia soluţie returnează

1 dacă pe nivelul k s-a ajuns la soluţie0 dacă pe nivelul k nu s-a ajuns la soluţie

În general funcţia soluţie se defineşte astfel:int soluţie(int k){

return(k==n+1)}

Page 80: Metoda Backtracking

Permutări – recursivfuncţia succ

Permutări – recursivfuncţia succ

#include<iostream.h>typedef int sir[100];sir x;int i,k,n,ev;

int succ(sir x, int k){if(x[k]<n)

{x[k]=x[k]+1;return 1;

}else return 0;}

#include<iostream.h>typedef int sir[100];sir x;int i,k,n,ev;

int succ(sir x, int k){if(x[k]<n)

{x[k]=x[k]+1;return 1;

}else return 0;}

Page 81: Metoda Backtracking

void valid(sir x, int k, int&ev){int i;ev=1;for(i=1; i<=k-1;i++)

if(!(x[k]!=x[i])) ev =0;}

void afis(sir c, int k){int i;for(i=1;i<=k-1;i++)

cout<<x[i]<<" ";cout<<endl;

}

void valid(sir x, int k, int&ev){int i;ev=1;for(i=1; i<=k-1;i++)

if(!(x[k]!=x[i])) ev =0;}

void afis(sir c, int k){int i;for(i=1;i<=k-1;i++)

cout<<x[i]<<" ";cout<<endl;

}

funcţiile valid şi afişfuncţiile valid şi afiş

Page 82: Metoda Backtracking

void back(int k){if (k==n+1) afis(x,k);else

{x[k]=0;while(succ(x,k))

{valid(x,k,ev);if(ev)

back(k+1);}

}}

void back(int k){if (k==n+1) afis(x,k);else

{x[k]=0;while(succ(x,k))

{valid(x,k,ev);if(ev)

back(k+1);}

}}

funcţia backfuncţia back

Page 83: Metoda Backtracking

programul principalprogramul principal

int main(void){cout<<"n=";cin>>n;back(1);}

int main(void){cout<<"n=";cin>>n;back(1);}

Page 84: Metoda Backtracking

Aranjamente - recursivAranjamente - recursiv

#include<iostream.h>typedef int sir[100];sir x;int i,k,n,ev,m;

int succ(sir x, int k){if(x[k]<n)

{x[k]=x[k]+1;return 1;

}else return 0;}

#include<iostream.h>typedef int sir[100];sir x;int i,k,n,ev,m;

int succ(sir x, int k){if(x[k]<n)

{x[k]=x[k]+1;return 1;

}else return 0;}

Page 85: Metoda Backtracking

Funcţiile valid şi afişFuncţiile valid şi afiş

void valid(sir x, int k, int&ev){int i;ev=1;for(i=1; i<=k-1;i++)

if((x[k]==x[i])) ev =0;}

void afis(sir c, int k){int i;for(i=1;i<=k-1;i++)

cout<<x[i]<<" ";cout<<endl;

}

void valid(sir x, int k, int&ev){int i;ev=1;for(i=1; i<=k-1;i++)

if((x[k]==x[i])) ev =0;}

void afis(sir c, int k){int i;for(i=1;i<=k-1;i++)

cout<<x[i]<<" ";cout<<endl;

}

Page 86: Metoda Backtracking

Funcţia backFuncţia back

void back(int k){if (k==m+1) afis(x,k);else

{x[k]=0;while(succ(x,k))

{valid(x,k,ev);if(ev)

back(k+1);}

}}

void back(int k){if (k==m+1) afis(x,k);else

{x[k]=0;while(succ(x,k))

{valid(x,k,ev);if(ev)

back(k+1);}

}}

Page 87: Metoda Backtracking

programul principalprogramul principal

int main(void){cout<<"n=";cin>>n;cout<<"m=";cin>>m;back(1);}

int main(void){cout<<"n=";cin>>n;cout<<"m=";cin>>m;back(1);}