Construiește toate aranjamentele posibile ale unui șir prin Backtracking — animat pas cu pas
O permutare a unui șir este o reordonare a tuturor elementelor sale. Pentru n elemente există n! permutări distincte.
Exemplu pentru n=3:
n=3 → 3! = 3×2×1 = 6
n=4 → 4! = 4×3×2×1 = 24
n=5 → 5! = 120 | n=10 → 10! = 3.628.800
Backtracking este un algoritm general de descoperire a tuturor soluțiilor unei probleme, bazat pe construirea incrementală a soluțiilor-candidat și abandonarea oricărui candidat parțial care nu poate duce la o soluție validă.
Exemplul clasic este problema reginelor: se plasează 8 regine pe o tablă de șah astfel încât niciuna să nu atace alta. Orice configurație parțială cu două regine ce se atacă este abandonată imediat.
Tehnica se poate aplica numai problemelor ce admit un concept de candidat parțial de soluție și un test rapid de validare. Când se poate aplica, BKT este mult mai rapid decât forța brută, eliminând dintr-un singur test un număr mare de candidați.
Backtrackingul stă la baza unor limbaje de programare logică (Icon, Planner, Prolog) și este util la rezolvarea problemelor de satisfacere a constrângerilor. Termenul a fost inventat de matematicianul american D. H. Lehmer în anii 1950.
Soluția este un vector X = (x1, x2, …, xn), unde fiecare componentă aparține unei mulțimi finite:
Ak — mulțimea valorilor posibile pentru xk — este finită și ordonată. De regulă A1 = A2 = … = An. BKT generează soluția completând X în ordinea x1, x2, …, xn și întoarce toate soluțiile.
Patru aspecte de definit înainte de a scrie codul:
Pe baza celor 4 aspecte se scriu funcțiile apelate de algoritmul general, aplicabil tuturor problemelor BKT:
Inițializează xk cu valoarea dinaintea primei valori din Ak. La prima incrementare xk++ devine primul element valid. Dacă Ak = {1..n} → xk = 0.
Verifică dacă mai există valori netestate în Ak (xk nu a atins limita maximă). Returnează 1 (continuă) sau 0 (revenire).
Verifică compatibilitatea lui xk cu valorile plasate la 1..k−1. Dacă returnează 0, valoarea este respinsă și se trece la următoarea.
Verifică dacă s-a obținut o soluție completă. Condiția clasică: k == n (toate cele n componente au fost completate).
Afișează soluția: vectorul x1, x2, …, xk. Bucla iterează i = 1..k inclusiv (nu 1..k−1).
Structura while se aplică tuturor problemelor BKT. Doar funcțiile se adaptează problemei concrete.
Pseudocod C++Când xk are mai multe caracteristici (ex: coordonate 2D), se introduce variabila auxiliară d[k] și funcția VALPOS(k) care calculează xk din d[k].