Sunteți pe pagina 1din 15

METODA

BACKTRACKING
Tehnică de programare
Utilitate

■ Metoda backtracking poate fi folosită în rezolvarea a


diverse probleme. Este o metodă lentă, dar de multe ori
este singura pe care o avem la dispoziție!
■ Se doreşte spargerea unui cifru (parolă) format din 4
cifre. Se presupune că există o funcție care primeşte ca
parametru o combinaţie de 4 cifre şireturnează 0
(combinație incorectă) sau 1 (combinație corectă).
Identificarea problemelor care au
rezolvare cu metoda Backtracking
■ soluția poate fi reprezentată printr-un tablou x[]=(x[1],
x[2], ..., x[n]), fiecare element x[i] aparținând unei mulțimi
cunoscute Ai;
■ fiecare mulțime Ai este finită, iar elementele ei se află într-
o relație de ordine precizată – de multe ori cele n mulțimi
sunt identice;
■ se cer toate soluțiile problemei sau se cere o anumită
soluție care nu poate fi determinată într-un alt mod (de
regulă mai rapid).
■ Se caută soluţia/soluţiile valide în spaţiul tuturor soluţiilor
Observații

■ Numărul de elemente ale soluţiei poate fi sau nu


cunoscut; depinde de fiecare problemă
■ Dacă se caută o singură soluţie, algoritmul se opreşte
forţat pentru a economisi timp
Backtracking. Analiza complexității
■ Produs cartezian: Se doreşte spargerea unui cifru format din
4 cifre. Se presupune că există o funcție care primeşte ca
parametru o combinaţie de 4 cifre şi returnează 0 (combinație
incorectă) sau 1 (combinație corectă).

■ Generând produsul cartezian se generează toate soluţiile:


■ (0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2)...(9, 9, 9, 9)
■ Rezolvare : adunare cu 1 în baza 10
Backtracking. Analiza complexității
■ Permutări: Se doreşte generarea tuturor permutărilor de
4 elemente.
■ Soluțiile:
■ (1, 2, 3, 4)
■ (1, 2, 4, 3)
■ (1, 3, 2, 4)
■ (1, 3, 4, 2)
■ ....
■ (4, 3, 2, 1)
■ Numărul soluțiilor este 4!=1*2*3*4=24 soluții
Rutina generală (iterativă):

void back()
{ k=1; // ma pozitionez pe prima poziţie din vectorul solutie
Init(k); // iniţializez prima poziţie din vectorul soluţie cu o valoare de start
while (k>0) // cât timp mai sunt în vectorul soluţie
{ if (Maisuntvalori(k)==1) //verific daca mai sunt valori netestate incă
{sol[k]++; // înaintez în vectorul în care ne construim soluţia
if (E_valid(k)) // testez dacă elementul este valid
if (Solutie(k)==1) //testez dacă noua valoare este soluţie
Tipar(k); // tipăresc soluţia
else
{ k++; // cresc nivelul în vectorul soluţie
Init(k); // iniţializez noua poziţie
}
}
else k--; // cobor nivelul(ma intorc) în vectorul soluţie
}
}
Observaţii:
■ În vectorul sol[] ne vom construi soluţia, pas cu pas;
■ Indicele k indică poziţia curentă în vectorul soluție (la început k=1 construirea
soluţiei pornindu-se de pe prima poziţie);
■ Funcţia Init(k) – iniţializează orice nouă poziţie în vectorul soluţie cu o valoare
de start( FOARTE IMPORTANT: poziţia va fi iniţializată cu prima valoare aflată
înaintea primei valori posibile dintr-o eventuală soluție. În cazul permutărilor cea
mai mica valoare posibila este 1 deci inițializarea se va face cu 0);
■ Funcţia E_valid(k) – verifică dacă o nouă valoare pusă pe poziţia k poate face
parte dintro eventuală soluţie;
■ Funcţia Soluţie(k) – verifică dacă noua valoare validă poate forma deja o
soluţie;
■ Funcţia MaiSuntValori(k) – verifică dacă pe poziţia k mai sunt valori netestate
încă(pe fiecare poziţie a vectorului soluţie există un domeniu maxim de valori
care de multe ori e acelaşi pentru fiecare poziţie a vectorului)
■ Funcţia Tipar(k) – tipăreşte vectrul soluţie până la poziţia k
Implementarea funcțiilor pentru
generarea permutărilor
#include<iostream> else return 0;}
using namespace std; // return (sol[k]<n);
int sol[20],n,k,p,nrsol; int E_valid(int k)
void Init(int k) {
{ for(int i=1;i<k;i++)
sol[k]=0; if (sol[i]==sol[k])
} return 0;
int Maisuntvalori(int k) return 1;
{ if (sol[k]<n) return 1; }
int Solutie(int k)
{ if(k==n)
return 1;
else return 0; // return (k==n);
}
void Tipar(int k)
{ for(int i=1;i<=k;i++)
cout<<sol[i]<<" ";
cout<<endl;
}
Principalele grupuri de probleme sunt:

■ G1) probleme în care vectorul soluţie are lungime fixă şi fiecare element apare o singură
dată în soluţie;
■ G2) probleme în care vectorul soluţie are lungime variabilă şi fiecare element poate să
apară de mai multe ori în soluţie;
■ G3) probleme în plan, atunci când spaţiul în care ne deplasăm este un tablou
bidimensional (backtracking generalizat).
Principiul metodei BKT:

■ soluţia se construieşte pas cu pas;


■ dacă se constată că, pentru o valoare aleasă, nu avem
cum să ajungem la soluţie, se renunţă la acea valoare şi
se reia căutarea din punctul în care am rămas.
Important:
Trebuie sǎ stabilim unele detalii cu privire la:
1. vectorul soluţie – câte componente are, ce conţine
fiecare componentǎ.
2. mulţimea de valori posibile pentru fiecare componentǎ
(sunt foarte importante limitele acestei mulţimi).
3. condiţiile de continuare (condiţiile ca o valoare xk sǎ fie
acceptatǎ).
4. condiţia ca ansamblul de valori generat sǎ fie soluţie.

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