Informatiile acestui spatiu sunt gratuite. Observatii si sugestii pot fi trimise pe adresa de contact sau pe forum.

     Metoda Backtracking

Backtracking-ul este o metoda ce foloseste principiul recursivitatii. Recursivitatea este o tehnica de programare in care o fuctie se apeleaza pe ea insasi, ceea ce se schimba in acest apel fiind valoarea parametrilor. Recursivitatea se foloseste atunci cand o anumita problema poate fi impartita in subprobleme de acelasi fel / de acelasi tip, dar mai mici.


Proncipiul de functionare

Metoda backtracking foloseste arborele de decizie explorand fiecare potentiala posibilitate de a ajunge la o solutie a problemei si revenind la un pas anterior in momentul in care solutia la care se ajunge nu este una valida adica nu respecta constrangerile/conditiile problemei. Ca sa fim mai expliciti si sa intelegem conceptual, sa ne gandim ca plecam de acasa catre o anumita destinatie. La un moment dat ajungem pe o straduta care se infunda. Ce facem? Ne intoarcem inapoi pana acasa? Nu - ne intoarcem doar pana la prima intersectie anterioara si o luam pe alt drum decat pe cel pe care o luasem anterior si care s-a infundat. Acelasi principiu este si in cazul backtracking: cand constatam ca solutia nu este una buna, ne intoarcem la un pas anterior si exploram alta optiune valida.


Pasi
  1. Pornim de la o soluție goală (Plecam de acasa).
  2. Încercăm să extindem soluția pas cu pas (Mergem pe straduta din dreapta de exemplu).
  3. Verificăm dacă soluția parțială este validă (Ne-am blocat sau nu?).
    • Dacă este validă (Nu am ajuns pe straduta care se infunda), continuăm explorarea.
    • Dacă nu este validă (Am ajuns pe straduta care se infunda), revenim la pasul anterior (intersesctia anteriara) și încercăm altă opțiune.
  4. Dacă am ajuns la o soluție completă (Am ajuns la destinatie), o afișăm/salvăm.
  5. Continuăm explorarea până când epuizăm toate posibilitățile (Cautam rute alternative).

Exemplu:

Se da o listă de n numere cu ajutorul carora dorim să generăm toate permutările posibile folosind metoda backtracking.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
using namespace std;

const int MAX_N = 10; //Numarul maxim de elemente
int N; // Numărul efectiv de elemente ale sirului
int numere[MAX_N]; // Lista inițială
int permutare[MAX_N]; // Permutarea curentă
bool utilizat[MAX_N] = {false}; // Marcam numerele utilizate

void backtrack(int k)
  {
     if (k == N) // Când permutarea este completă
     {
      for (int i = 0; i < N; i++)
        cout << permutare[i] << " ";
      cout << endl;
      return;
     }

     for (int i = 0; i < N; i++)
     {
       if (!utilizat[i]) // Dacă numărul nu a fost folosit
        {
        utilizat[i] = true; // Marcam ca utilizat
        permutare[k] = numere[i]; // Adăugăm numărul în permutare

        backtrack(k + 1); // Apel recursiv pentru poziția următoare

        utilizat[i] = false; // Backtracking: revenim la starea anterioară
        }
     }
  }

int main()
  {
     cout<<"Cate elemente are multimea: N=";
     cin>>N;
     cout<<"Introduceti elementele multimii:"<<endl;
     for (int i=0;i<N; i++)
     {
       cout<<"Numere["<<i<<"]=";
       cin>>numere[i];
     }
     cout<<"Elementele multimii sunt:"<<endl;
     for (int i=0;i<N;i++)
       cout<<numere[i]<<" ";
     cout<<endl;
     cout <<"Permutarile sunt:\n";
   backtrack(0); // Start recursiv de la poziția 0
   return 0;
}
Cate numere are multimea: N=3
Introduceti elementele multimii:
Numere[0]=1
Numere[1]=2
Numere[2]=3
Elementele multimii sunt: 1 2 3
Permutarile sunt:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1