Sunteți pe pagina 1din 6

Colegiul Financiar-Bancar din Chișinău

Studiu Individual la
SDA
tema: Metoda de programare
Backtracking

Elev: Gîrbu Nicolae


Grupa: INF1311G

Chișinău 2015
Această metodă generală de programare se aplică problemelor în care soluţia se poate reprezenta sub forma
unui vector X = (x1, ..., xn)ÎS unde S = S1 x ... x Sn , unde mulţimile S1, ...,Sn sunt mulţimi finite având |Si|
= si elemente. Pentru fiecare problemă concretă sunt date anumite relaţii între componentele x1 , ... xn ale
vectorului X, numite condiţii interne.
Mulţimea finită S = S1 x S2 x... x Sn se numeşte spaţiul soluţiilor posibile (este un produs cartezian).
Soluţiile posibile care satisfac condiţiile interne se numesc soluţii rezultat. Ceea ce ne propunem este de a
determina toate soluţiile rezultat, cu scopul de a le afişa sau de a alege dintre ele una care maximizează sau
minimizează o eventuală funcţie obiectiv dată.
O metoda simplă de determinare a soluţiilor rezultat constă în a genera într-un mod oarecare toate soluţiile
posibile şi de a verifica dacă ele satisfac condiţiile interne. Dezavantajul constă în faptul că timpul cerut de
această investigare exhaustivă este foarte mare. Astfel, chiar pentru |Si| = 2, " i, timpul necesar este de
ordinul 2n, deci exponenţial.
Metoda backtracking urmăreşte să evite generarea tuturor soluţiilor posibile. În acest scop, elementele
vectorului X primesc pe rând valori în sensul că lui xk i se atribuie o valoare numai dacă au fost atribuite
deja valori lui x1 ,... xk-1 . Mai mult, odată o valoare pentru xn stabilită, nu se trece direct la atribuirea de
valori lui xk+1 , neîndeplinirea lor exprimând faptul că oricum am alege xk+1,...,xn nu vom putea ajunge la
o soluţie rezultat, adică o condiţie pentru care condiţiile interne să fie satisfăcute. Evident că în cazul
neîndeplinirii condiţiilor de continuare va trebui să facem o altă alegere pentru xk sau dacă Sk a fost epuizat
să micşorăm pe k cu o unitate încercând să facem o nouă alegere pentru xk etc.; această micşorare a lui k dă
numele metodei, ilustrând faptul că atunci când nu mai putem avansa, urmărim înapoi secvenţa curentă din
soluţie. Este evident că între condiţiile de continuare şi condiţiile interne există o strânsă legătură. O bună
alegere pentru condiţiile de continuare are ca efect o importantă reducere a numărului de calcule.
Metoda backtracking poate fi reprezentată uşor, pe un arbore construit astfel:
- nivelul 1 conţine rădăcina;
- din orice vârf de pe nivelul k pleacă sk muchii spre nivelul k+1 etichetaţi cu cele sk muchii ale lui Sk.
Nivelul n+1 va conţine s1 × s2 × ... × sn vârfuri. Pentru fiecare vârf de pe nivelul n+1, etichetele muchiilor
conţinute pe drumul ce leagă rădăcina de acest vârf reprezintă o soluţie posibilă.
Exemplu - Să considerăm problema submulţimilor de sumă dată care constă în următoarele: Fie A = (a1, a2,
..., an) cu ai > 0, " i. Fie MÎR+. Se caută toate submulţimile B ale lui A pentru care suma elementelor este M.
Pentru a putea realiza problema prin metoda backtracking vom reprezenta soluţia sub forma x = (x1, ..., xn)
unde xi = 1 dacă aiÎB şi xi = 0 în caz contrar. Sa ne situăm în ipoteza ca n=4. Arborele ataşat metodei
backtracking este următorul:
Câştigul obţinut prin introducerea condiţiilor de continuare constă în faptul că, dacă într-un vârf ele nu mai
sunt verificate, se va renunţa la parcurgerea subarborelui care are ca rădăcină acest vârf.
Acest exemplu permite prezentarea unei variante a metodei backtracking. Într-adevăr, să considerăm drept
soluţie posibilă o valoare k £ n împreună cu k-uplul (x1, ..., xk) unde pentru i Î {1, ..., k}, xi reprezintă
indicele elementului pe care îl introducem în B. Evident xi ¹ xj pentru i¹j. Pentru a nu se repeta soluţii, vom
presupune x1<x2<...<xn .
Obţinem astfel următorul arbore în care fiecare vârf corespunde unei soluţii posibile.

Diferitele variante ale metodei backtracking nu schimbă esenţa ei care constă în faptul că este
reprezentabilă pe un arbore care este parcurs "coborând" în arbore numai dacă există şanse de a ajunge la o
soluţie rezultat.
În continuare, problemele care vor fi prezentate vor urma o schema generală şi anume:
- se va testa dacă am obţinut o soluţie, situaţie în care acesta se va reţine;
- dacă nu am obţinut soluţie se încearcă plasarea unui nou element în vectorul soluţie cu respectarea
condiţiilor de continuare;
- dacă nu se reuşeşte plasarea unui nou element şi spaţiul valorilor posibile de plasat s-a epuizat, se
revine la poziţia anterioară şi se încearcă să se plaseze pe ea un alt element.
Faptul că după plasarea unui element în vectorul soluţie algoritmul presupune plasarea unui element
pe poziţia imediat următoare, adică de fapt reluarea algoritmului, conduce posibilitatea abordării recursive a
algoritmilor de tip backtracking. Acest lucru permite o scriere mult mai scurtă şi mai simplă a algoritmilor şi
apoi a programelor care îi implementează. Astfel, general, un algoritm backtracking poate fi prezentat astfel:
Subalgoritm back (k)
pentru fiecare valoare i din multimea Sk execută
xk←i
dacă X respectă condiţiile interne atunci
dacă X este solutie atunci
afisează X
altfel
apelează back(k+1)
sfdacă
sfdacă
sfpentru

În funcţie de problema concretă, în algoritmul descris mai sus se vor modifica doar instrucţiunea
pentru, condiţiile interne şi cele de soluţie, structura algoritmului păstrându-se.
Probleme de generare. Oportunitatea utilizării metodei backtracking
Problemele care se rezolvă prin metoda backtracking pot fi împărţite în mai multe grupuri de
probleme cu rezolvări asemănătoare, in funcţie de modificările pe care le vom face în algoritm. Principalele
grupuri de probleme sunt:
a) probleme în care vectorul soluţie are lungime fixă şi fiecare element apare o singură dată în
soluţie;
b) probleme în care vectorul soluţie are lungime variabilă şi fiecare element poate să apară de mai
multe ori în soluţie;
c) probleme în plan, atunci când spaţiul în care ne deplasăm este un tablou bidimensional.
Vom prezenta în cele ce urmează câteva probleme care pac parte din primul grup. Cele mai
cunoscute sunt:
• generarea permutărilor unei mulţimi
• generarea aranjamentelor unei mulţimi
• generarea submulţimilor unei mulţimi
• generarea submulţimilor cu m elemente ale unei mulţimi (combinări)
• generarea produsului cartezian a n mulţimi
• generarea tuturor secvenţelor de n (par) paranteze care se închid corect.
• colorarea ţărilor de pe o hartă astfel încât oricare două ţări vecine să aibă culori diferite
• aranjarea a n regine pe o tablă de şah de dimensiune n fără ca ele să se atace.
Toate problemele din acest grup au particularitatea că soluţia se obţine atunci când vectorul soluţie
ajunge să conţină un anumit număr de elemente.
Problema Damelor
Aranjarea reginelor. Dându-se o tablă de şah de dimensiune nxn (n>3) să se aranjeze pe ea n regine fără ca
ele să se atace. Reamintim că o regină atacă linia, coloana şi cele 2 diagonale pe care se află. În figura de
mai jos celulele colorare mai închis sunt atacate de regina poziţionată unde indică litera “R”.

În algoritmul de mai sus avem de particularizat următoarele:


Instrucţiunea pentru fiecare valoare i din mulţimea Sk execută va fi înlocuită cu o instrucţiune pentru care
parcurge toate valorile de la 1 până la n.
Condiţia de a putea plasa o regină pe poziţia k este un pic mai complicată şi presupune verificarea ca să nu
se atace cu nici una dintre celelalte k-1 regine deja plasate pe tabla. Dacă pe poziţia k din vectorul X punem
o valoare ea va reprezenta coloana pe care se plasează pe tablă regina k. Condiţiile devin astfel:
x[i]¹x[k] şi |k-i|¹|x[k]-x[i]| cu i de la 1 la k-1 şi |x| reprezentând modului lui x.
Condiţia de soluţie este simplă şi presupune plasarea corectă a tuturor celor n regine.

Codul C++ :
#include<iostream.h> return 1;
#include<math.h> }
int x[100],n,nrsol; void back(int k)
void scriesol () {
{ int i,j; int i;
nrsol++; for(i=1;i<=n;i++)
cout<<"Solutia a "<<nrsol<<" {
este"; x[k]=i;
for(i=1;i<=n;i++) if (potcont(k))
{ cout<<endl; if (k==n) scriesol();
for(j=1;j<=n;j++) else back(k+1);
if (x[j]==i) cout<<"X "; }
else cout<<"O "; }
} void main()
} {
int potcont(int k) cin>>n;
{ int i; nrsol=0;
for(i=1;i<=k-1;i++) back(1);
if (x[i]==x[k] || k-i==abs(x[k]- cout<<nrsol<<" solutii";
x[i])) return 0; }
Bibliografie :
 http://info.tm.edu.ro:8080/~asimulescu/public/clasa11D/Backtracking_1.pdf

 http://89.121.249.92/2010-2011/Catedre/Informatica/11/Teorie_back.pdf

 http://www.unibuc.ro/prof/vlada_m/docs/2011/apr/11_15_48_17met_BACKTRACKING.pdf

 https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&uact=8&ved=0ahU
KEwiM9Mul7LDJAhUEYA8KHd-
zAWMQFgg0MAQ&url=https%3A%2F%2Fro.wikipedia.org%2Fwiki%2FBacktracking&usg=AFQjC
NGTGDsfF7Jt4XcfwwP7s4uF8sjZgw&sig2=2fiur7d8VeWlMgRtzLkCTw

 https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=6&ved=0ahUKEwiM9Mul7LD
JAhUEYA8KHd-zAWMQFgg5MAU&url=https%3A%2F%2Ftuneam.wordpress.com%2F11-
info%2Fmetoda-backtracking%2F&usg=AFQjCNFu9gS3A1tUn3LTTE-fxOfMDC_1ag&sig2=-
NwadzmCKOhSi8gSMeEDvw&cad=rja

 https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=8&cad=rja&uact=8&ved=0ahU
KEwiM9Mul7LDJAhUEYA8KHd-
zAWMQtwIIRDAH&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DMBvGarFn5dI&u
sg=AFQjCNHwyQZX3d5MR5wdhtCgGjC0FMesOw&sig2=8mhk9XOmR_WyoM8OBkVkHA

 https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=10&cad=rja&uact=8&ved=0ah
UKEwiM9Mul7LDJAhUEYA8KHd-
zAWMQFghMMAk&url=http%3A%2F%2Fwww.dponline.ro%2Farticol.php%3Fidarticol%3D112&us
g=AFQjCNGjOUu_VtfnfSODMFVscZfdn1IUJg&sig2=DH6tQE5Gesns6y7K1Zktrg

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