Documente Academic
Documente Profesional
Documente Cultură
else k--; }
Aplicatie: Problema celor n dame
Se considera o tabla de sah de dimensiuni n*n. Se cer toate solutiile de aranjare a n dame astfel incat sa
nu se atace reciproc (sa nu fie pe aceeasi linie/coloana sau pe diagonala).
init : nivelul k al stivei este initializat cu 0;
succesor : se mareste cu 1 valoarea aflata pe nivelul k al stivei in situatia in care aceasta este mai
mica decat n si atribuie variabilei as valoarea true; in caz contrar, atribuie variabilei as valoarea
false;
valid : valideaza valoarea pusa pe nivelul k al stivei, verificand daca nu avem doua dame pe
aceeasi linie/coloana ( st(k) = st(i) ), sau daca nu avem doua dame pe aceeasi diagonala ( |st(k)
st(i)| = | k-i |, caz in care variabilei ev i se atribuie valoarea false; in caz contrar, variabilei ev i se
atribuie true.
solutie : verifica daca stiva a fost completata pana la nivelul n inclusiv;
tipar : tipareste ( afiseaza ) o solutie.
#include <iostream.h>
int n, st[100], as, ev;
void init(int k)
{st[k]=0;}
void succesor(int &as, int st[100], int k)
{ if (st[k]<n) {st[k]++; as=1;}
else as=0;
}
void valid(int &ev, int st[100], int k)
{int i;
ev=1;
for (i=1; i<=k-1; i++)
if (st[k]==st[i]) ev=0;
}
int solutie(int k)
{return k==n+1;
}
void tipar ()
{for(int i=1; i<=n; i++)
cout<<st[i];
cout<<endl;
}
void main()
{cout<<n=;cin>>n;
//rutina generala backtracking
.....
}
2. Backtracking recursiv
Procedurile si functiile folosite sunt, in general, aceleasi cu cele de la backtracking iterativ, cu doua mici
exceptii:
Succesor nu mai este procedura ci functie booleana(deci, dispare variabila as);
Rutina backtracking se transforma in procedura, care se apeleaza prin back(1).
Principiul de functionare al procedurii back, corespunzator unui nivel k, este:
In situatia in care avem o solutie, o tiparim si revenim pe nivelul anterior;
In caz contrar, se initializeaza nivelul si se cauta un succesor;
Cand am gasit unul, verificam daca este valid; procedura se autoapeleaza pentru k+1, in caz
contrar urmand a se continua cautarea succesorului;
Daca nu avem succesor, se trece pe nivelul inferior(k-1) prin iesirea din procedura/functia back.
void back(int k)
{if (solutie(k)) tipar();
else
{init(k,st);
while (succesor(st,k))
if (valid(st,k)) back(k+1);
}
Problema celor n dame:
#include <iostream.h>
int n, st[100];
void init(int k)
{st[k]=0;}
int succesor(int st[100], int k)
{ if (st[k]<n) {st[k]++; return 1;}
else return 0;
}
int valid(int st[100], int k)
{int i, ev=1;
for (i=1; i<=k-1; i++)
if (st[k] == st[i]) ev:=0;
return ev;
}
int solutie(int k)
{return k == n+1;
}
void tipar ()
{for(int i=1;i<=n;i++)
cout<<st[i];
cout<<endl;
}
void back(int k)
{if (solutie(k)) tipar();
else
{init(k,st);
while (succesor(st,k))
if (valid(st,k)) back(k+1);
}
void main()
{cout<<n=; cin>>n; back(1);}
3