Sunteți pe pagina 1din 30

PROIECT INFORMATICA

METODA BACKTRACKING

Prezentarea tehnicii backtracking


Metoda backtracking se foloseste in rezolvarea problemelor in care solutia poate fi pusa sub forma unui vector.Vectorul se va genera progresiv de la primul lui element catre ultimul.Pentru a fi o solutie corecta vectorul trebuie sa respecte pentru fiecare element al lui o serie de conditii de continuare.Daca la o etapa oarecare un element din vector nu respecta conditiile de continuare indiferent de valorile celorlalte elemente din vector, solutia generata nu este corecta.

Elementele vectorului x, primesc, pe rand, valori.Astfel, lui xk i se atribuie o valoare numai daca au fost deja atribuite valori lui x1,,xk-1.Mai mult,odata o valoare pentru xk stabilita, nu se trece direct la atribuirea de valori lui xk+1, ci se verifica conditiile de continuare referitoare la x1,,xk.Aceste conditii stabilesc situatiile in care are sens sa trecem la determinarea lui xk+1.Neindeplinirea lor exprima faptul ca, oricum am alege xk+1,,xn, nu vom putea ajunge la o solutie rezultat,adica la o solutie pentru care conditiile sa fie satisfacute.In cazul in care conditiile de continuare nu sunt indeplinite, se va alege alt xk din Sk, iar daca Sk s-a epuizat ne intoarcem la Sk.

Exemplu de problema rezolvata cu ajutorul tehnicii backtracking.

Generarea permutarilor. Se citeste un numar natural n.Sa se genereze toate permutarile multimii {1,2,n}. Ex.:A={1,2,3} 123 132 213 231 312 321
#include<iostream.h> int n,k,x[10]; Void afisare() //afisarea solutiei curente { for(int i=1;i<=n;i++) cout<<x[i]<<" "; cout<<endl; }

int test(int k) //testarea condiiilor de continuare pentru x[k] {for(int i=1;i<k;i++) if (x[i]==x[k]) return 0; return 1;} void main() {cout<<"n=";cin>>n; //se citeste n k=1;
//se ncepe generarea cu prima poziie a vectorului

x[k]=0; //se iniializeaz x[k] cu o valoare mai mic cu o unitate dect cea
mai mica valoare posibil pentru x[1]

while(k>0) //ct timp nu s-au generat toate soluiile posibile si nu s-au


ncercat toate valorile posibile pentru elementul x[k]

{ while (x[k]<n) { x[k]++; //se ncearc urmtoarea valoare disponibil

if (test(k)) //se verifica pt. x[k] indeplinirea conditiilor de continuare if (k==n) afisare(); //dac x[k] trece testul i s-au generat toate cele n
//elemente necesare, se afieaz soluia obinut

else {k++; //se ncearc urmtoarea valoare disponibil x[k]=0; }} k--;}}

PROBLEME REZOLVATE
1. Se dau numele a 3 persoane.Se cere sa se afiseze toate modurile posibile in care acestea se pot aseza intr-o banca.
Ex: n=3 Ioana, Costel si Mihaela; solutii: Ioana Costel Mihaela; Ioana Mihaela Costel; Costel Ioana Mihaela; ..

#include<iostream.h> int n,k,x[100],v[100]; //vectorul v[i] retine numele personelor care se pot
aseza in banca iar x este vectorul cu ajutorul caruia vom permuta

Void afisare() { for(int i=1;i<=n;i++) If(x[i]==1) cout<<v[1]; //daca vectorul x are valoare 1 se va afisa v[1] adica
numele persoanei corespunzatoare vectorului v[1] analog pentru x[2] si x[3]

If(x[i]==2) cout<<v[2]; If(x[3]==3) cout<<v[3]; Cout<<endl;} int test(int k) {for(int i=1;i<k;i++) if (x[i]==x[k]) return 0; //nu poate exista aceeasi valoare de mai multe ori
in vectorul x

return 1;}

void main() {cout<<"n=";cin>>n; for(i=1;i<=n;i++) cin>>v[i]; //citim numele personalor k=1; //se ncepe generarea cu prima poziie a vectorului x[k]=0; //se iniializeaz x[k] cu o valoare mai mic cu o unitate dect cea
//mai mica valoare posibil pentru x[1]

while(k>0)

//ct timp nu s-au generat toate soluiile posibile si nu //s-au ncercat toate valorile posibile pentru elementul x[k]

{ while (x[k]<n) { x[k]++; //se ncearc urmtoarea valoare disponibil if (test(k)) //se verifica daca se indeplinesc conditiile de continuare if (k==n) afisare(); //in cazul in care s-au generat toate numerele se vor
//afisa solutia obtinuta

else { //altfel se incearca urmatoarea solutie k++; x[k]=0; } }k--;}}

2. Utilizand metoda backtracking se genereaza toate permutarile cuvantului mate. Solutii:amte,tame,atme,s.a.m.d;


#include<iostream.h> int k,x[10]; void afisare() //afiarea soluiei curente { for(int i=1;i<=4;i++) if(x[i]==1) cout<<m; if(x[i]==2) cout<<a; if(x[i]==3) cout<<t; if(x[i]==4) cout<<e;}

int test(int k ) //conditia de continuare {for(int i=1;i<k;i++) if (x[i]==x[k]) return 0; //nu pot exista aceeasi persoana de 2 ori in banca return 1;} void main() {k=1; //se ncepe generarea cu prima poziie a vectorului x[k]=0; //se iniializeaz x[k] cu o valoare mai mic cu o unitate dect cea
//mai mica valoare posibil pentru x[1]

while(k>0)

//ct timp nu s-au generat toate soluiile posibile si nu s-au //ncercat toate valorile posibile pentru elementul x[k]

{ while (x[k]<4) { x[k]++; //se ncearc urmtoarea valoare disponibil if (test(k)) //se verifica daca se indeplinesc conditiile de //continuare if (k==4) afisare(); //in cazul in care s-au generat toate numerele se va
afisa solutia obtinuta

else { k++; //altfel se incearca urmatoarea solutie x[k]=0; } }k--;}}

3. Se genereaza toate numerele formate din 4 cifre distincte din multimea{1,2,...n}.Sa se afiseze cate numere au prima cifra egala cu 1. Exemplu:solutii:1234,1234,1432 etc.
#include<iostream.h> int n,k,x[10],a; void afisare() //afisarea solutiei curente { for(int i=1;i<=n;i++) cout<<x[i]<< ; cout<<endl; if(x[1]==1) a++;} //daca prima cifra din vector este 1 a va creste cu o
valoare

int test(int k) //subprogramul test verifica conditiile de continuare {for(int i=1;i<k;i++) if (x[i]==x[k]) return 0; //nu poate exista aceeasi valoare de mai multe ori in vector return 1;}

void main() {cout<<n=; cin>>n; //se citeste n k=1; //se ncepe generarea cu prima poziie a vectorului x[k]=0; //se iniializeaz x[k] cu o valoare mai mic cu o unitate dect cea mai
mica valoare posibil pentru x[1]

while(k>0) { while (x[k]<n) { x[k]++; if (test(k)) //se verfica indeplinirea conditiilor de continuare if (k==n-1) afisare(); //daca s-au generat toate cele n-1 posibilitati se va
//apela afisarea

else {k++; //altfel se trece la elementul urmator de generat

4. Scrieti un program care afiseaza toate secventele de n litere(n par) din multimea R, O, G, V secvente ce se constituie dupa regula nu sunt doua litere identice una langa alta,se vor utiliza exact n/2 litera G. Ex.:n=2 RO,RG,RV,RA etc.
#include <iostream.h> Void afisare() {int a=0; //se foloseste o constanta pentru a numara nr de aparitii a literei G For(int i=1;i<=n;i++) If(x[i]==3) a++; //daca vectorul x este egal cu 3 a creste cu o valoare If(a==n/2) //daca a apare de n/2 ori se vor afisa solutiile gasite {for(i=1;i<=n;i++)

{if(x[i]==1) cout<<R; If(x[i]==2) cout<<O; If(x[i]==3) cout<<G; If(x[i]==4)cout<<V;}cout<<endl;}} Int test(int k) //conditia de continuare {if(x[k]==x[k-1]) return 0; //sa nu existe doua litere identice una langa alta return 1;} void main() { cin>>n; //nr de aparitie a literelor k=1; x[k]=0; while(k>0) { while (x[k]<4) {x[k]++; if (test(k)) if (k==n) afisare(); //daca s-au generat toate elementele posibile se vor afisa
solutiile obtinute

else { k++; x[k]=0; } }k--;}}

5. Se citesc numele a n elevi.Afisati toate submultimile multimii celor n elevi. Ex.n=3 (Ioana,Mihai,Maria) Ioana;Ioana Maria;Ioana Mihai Maria etc.
#include <iostream.h> Int k,x[100],v[100],n,i;
//se va folosi pentru a genera toate submultimile multimii celor n elevi un vector x[i] care ia valori 0 si 1

void afisare() //afisarea solutiei curente {for(i=1;i<=n;i++) if(x[i]==1) cout<<v[i]<< ; //in cazul in care vectorul x este egal cu 1 se va
//afisa numele elevului corespunzator

cout<<endl}

//subprogramul test nu va exista deoarece vectorul x poate avea in vector si //valori care se repeta

void main() { cin>>n; //se citesc nr elevilor for(i=1;i<=n;i++) cin>>v[i]; //se citesc numele elevilor k=1; //se ncepe generarea cu prima poziie a vectorului x[k]=-1; //se initializeaza x[k] cu o valoare mai mic cu o unitate dect cea
//mai mic

While(k>1) {While(x[k]<1) {x[k]++; if(k==n) afisare(); else{ k++; x[k]=-1;}} k--; }}

6. Utilizand metoda backtracking sa se genereze toate permutarile cifrelor numarului dat n cu proprietatea ca ultima cifra din numerele generate sa fie intotdeuna egale cu suma cifrelor nr n. Ex.: n=123 solutii: 126 136
#include<iostream.h> int n,k,x[100],v[100],s;

Void afisare() //afisarea solutiei curente {for(int i=1;i<=a;i++) cout<<x[i]<< ; cout<<endl;}

/*subprogramul cifre va afisa sub forma de vector cifrele numarului n*/

void cifre() { int a=0; //folosim constanta a pentru a numara numarul cifrelor ale lui n while(n!=0) //cat timp n este diferit de 0 {a++; //constanta a creste cu o unitate v[a]=n%10; //vectorul v va lua pe rand valorile cifrelor numarului n n=n/10;}}
/*suprogramul suma va returna suma cifrelor numarului n*/

int suma(int n) {int s=0; while(n!=0) { s=s+n%10; n=n/10; } return s;}

Int test (int k ) //subprogramul test verifica conditiile de continuare {for(i=1;i<k;i++) if(x[i]==x[k]) return 0; /* daca elementele din vector nu sunt distincte
returneaza 0 */

if(k==a && x[a]!=s) return 0; //daca s-a ajuns la ultima generare si vectorul
x[a] este diferit de suma cifrelor numarului n se va returna 0

return 1;}
void main() {cin>>n; //se citeste numarul n cifre(); //se apeleaza subprogramele cifre() si suma(n) suma(n); k=1; //se ncepe generarea cu prima poziie a vectorului x[k]=0; //se iniializeaz x[k] cu o valoare mai mic cu o unitate dect cea mai
mica valoare posibil pentru x[1] while(k>0) //ct timp nu s-au generat toate soluiile posibile si nu s-au ncercat toate valorile posibile pentru elementul x[k]

{while(x[k]<a) {x[k]++; //se ncearc urmtoarea valoare disponibil

if(test(k)) //se verifica pt. x[k] indeplinirea conditiilor de continuare if(k==a) afisare(); //dac x[k] trece testul i s-au generat toate cele n
//elemente necesare, se afieaz soluia obinut

else{ k++; //altfel se incearca urmatoarea solutie x[k]=0;}} k--;}}

7. Un vector contine intr-o oridine oarecare n numere naturale(n nr par).Dintre cele n numere jumatate sunt pare.Sa se afiseze toate permutarile elementelor vectorului astfel incat toate numerele impare sa fie in prima jumatate a vectorului. Ex.:n=6 1 2 4 5 8 7 3 permutari: 2 4 8 7 3 5 2 8 4 7 5 3 etc.
#include<iostream.h> int k,n,x[100],v[100],i; void afisare //afisarea solutiei curente
{for(int i=1;i<=n;i++) cout<<v[x[i]];}

int test(int k) //conditii de continuare {for(int i=1;i<k;i++) if(x[i]==x[k]) return 0; If(k<=n/2) If(v[x[i]]%2==0) return 0; //daca vectorul v[x[i]] este numar par functia va returna valoarea 0 Return 1;} Void main() {cin>>n; For(i=1;i<=n;i++) cin>>v[i]; //se citeste vectorul v K=1; X[k]=0; While(k>0) {while(x[k]<n) X[k]++; If(test(k)) //verificarea indeplinirii conditiilor din functia test If(k==n) afisare(); Else{k++;x[k]=0}}k--;}}

8. Se dau suma s si n tipuri de monede avand valori de a1,a2,,an lei.Se cer toate modalitatile de plata a sumei s utilizand aceste monede.Se presupune ca se dispune de un numer nelimitat de exeplare din fiecare tip de moneda. Ex.:pt s=5 si n=3 (1,2,3) solutiile pot fi:1 de 2, 1 de 3; 1 de 1, 2 de 2 etc.
#include<iostream.h> Int i,n,k,s,x[100],v[100]; Void afisare() //afisarea solutiei curente {for(int i=1;i<=n;i++) Cout<<x[i]<<monede de<<v[i]<<endl;}

void main() {cin>>n; //se citesc numarul de monede for(i=1;i<=n;i++) cin>>v[i]; //se citesc valorile monedelor
cin>>suma; //se citeste suma

K=1;x[k]=-1; while(k>0) {while(x[k]<n) {x[k]++; if(k==n) //daca s-au generat toate elementele posibile int s=0; //s este suma pe care o vom calcula si compara cu suma ceruta for(i=1;i<=n;i++) s=s+x[i]*a[i]; //s se calculeaza insumand vechiul s si
produsul dintre vectorul permutat si valorile monezilor

If(s==suma) afisare(); //daca s este egala cu suma ceruta se va face


afisarea

else{k++; //altfel se trece la generarea elementului urmator x[k]=-1;}}k--;}}

9. Se citeste un numar natural pozitiv n,se cere sa se afiseze toate descompunerile sale ca suma de p numere prime. ex.n=5 131 113 311 etc.
#include<iostream.h> Int n,i,k,s,x[100],p; Void afisare() //afisarea solutiei curente {for(i=1;i<=p;i++) Cout<<x[i]<< ; cout><<endl;}

/* prin subprogramul prim se verifica daca un numar este prim*/

int prim(int m) {for(i=2;i<=m/2;i++) If(m%10==0) return 0; return 1;}


/*subprogramul suma calculeaza suma elementelor din vectorul x*/

Int suma(int k) {int s=0; for(i=1;i<k;i++) s=s+x[i]; return s;} void main() {cin>>n; cin>>p; k=1;x[k]=0;

while(k>0) {while(x[k]<n-suma) {x[k]++; if(k==p) //daca s-au generat toate elementele posibile if(prim(x[k])) //daca numerele generate sunt numere prime si daca suma
acestora coincide cu n se va face afisarea

if(suma(k)==n) afisare(); else{ k++; //in cazul in care nu se verifica conditiile se trece la elementul
urmator

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

BIBLOGRAFIE
Manual de informatica Clasa a-XI-a;Ed.L&S Soft; Manual pentru clasa a X-a Tehnici de programare;Ed. L&S Soft; www.referate.ro;

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