Sunteți pe pagina 1din 8

METODA

BACKTRACKING
Problema celor n dame
Enunț
Se dau N dame şi o tablă de şah de dimensiune NxN. Să se găsească toate modalităţile
de a aranja toate damele astfel încât oricare două dame să nu se atace. Două dame se
atacă dacă se află pe aceeaşi linie, coloană sau diagonală. Se cere să se afişeze
soluțiile în ordine lexicografică şi numărul total de soluţii.
Pentru N=4 sunt 2 soluții
Explicații

■ Aranjarea damelor pe tabla de șah este o problemă clasică


de backtracking.
■ Metoda de rezolvare cu backtracking presupune generarea
tuturor soluțiilor și testarea lor dacă sunt valide sau nu.
■ O dama poate fi plasata pe tabla de sah dacă pentru fiecare
damă aranjată deja, aceasta nu se află pe aceeași coloană,
linie sau diagonală cu niciuna dintre ele.
Analiza problemei
■ Codificarea/ Cum arată soluția?
– Soluția trebuie să fie sub formă de vector
2

4
1
3

– Observăm că numărul damelor corespunde cu numărul


rândurilor. Dacă fiecare nivel al soluției (k) corespunde unei
dame, atunci vectorul soluție x[k] va reține coloana unde
așezăm dama k.
Analiza problemei
■ Care sunt mulțimile soluțiilor posibile pentru fiecare nivel al soluției?
■ Răspuns: Cum pe fiecare nivel punem coloana în care așezăm dama curență,
mulțimea soluțiilor posibile este mulțimea coloanelor adică A={1, 2, 3, …n}

1. Care sunt mulțimile Modificare funcția Back Ai ={1, 2, 3, …n} (pe fiecare nivel se vor pune
soluțiilor posibile pentru limitele for-ului A=primul elemente de la 1, la n}
fiecare nivel al soluției? element din mulțime, void Back(int k){
B=ultimul for(int i = 1 ; i <= n; ++i)
{
x[k]=i;
if( OK(k) )
if(Solutie(k))
Afisare(k);
else
Back(k+1);
}
}
2. Când avem soluție? Modificare funcția soluție Când stiva este plină (k==n) avem soluție
R: Când am așezat toate int Solutie(int k){
damele. return (k==4)
}

Vom ajunge la o soluție când am așezat pe tablă toate cele n dame.


3. Care sunt condițiile de Se modifică funcția ok Când adăugăm un element în stivă, el trebuie
validitate ale problemei? • să nu se regăsească pe pozițiile anterioare
(adică altă dama nu a mai fost așezată în
această coloană, adică x[i] ≠x[k]|),
• (i,x[i]) respectiv (k,x[k]) nu sunt pe acceaşi
diagonală dacă |i-k|≠|x[i]-x[k]|, oricare ar fi i-
dama anterioara.
int OK(int k){
for(int i=1; i:=k-1; i++)
if(x[k]==x[i] ||abs(x[k]-x[i])==(k-i)))
return 0;
return 1;}

1 2 3 4
De exemplu, în configurația alăturată, dama i=2, este așezată în coloana x[2]=1,
1 iar dama k=3 este în coloana x[3]=2. Nu este o configurație validă deoarece |3-
2 * 2]=|1-2| (adică se află pe aceeași diagonală)
3 *
4
Cum arată soluția? Se modifică funcția void Afisare(int k)
În vectorul x(stivă) se vor Afisare astfel încăt să {
genera sub forma tipărească toate for(int i=1; i:=k; i++)
2, 4, 1, 3 elementele soluției cout<<x[i]<<‘ ‘;
3, 1, 4, 2 cout<<endl;

void afisare(int k)
{
Pentru a afișa sub forma int i,j;
Solutia:1 sol++;
_D__ cout<<"Solutia:"<<sol<<endl;
___D for(i=1;i<=k;i++)
D___ {
__D_ for(j=1;j<=k;j++)
Solutia:2 if(x[i]==j)
__D_ cout<<"D";
D___ else
___D cout<<"_";
_D__ cout<<endl;
}
}

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