Sunteți pe pagina 1din 6

Backtracking

Tehnica Backtracking propune generarea soluţiei prin completarea


vectorului x în ordine x1x2... xn şi are la bazǎ un principiu “de bun simţ”:
dacǎ se constatǎ cǎ având o combinaţie parţialǎ de formǎ v1v2...v k-1 (unde
vi,…,vk-1 sunt valori deja fixate), dacǎ alegem pentru xk o valoare vk şi
combinaţia rezultatǎ nu ne permite sǎ ajungem la o soluţie, se renunţǎ la
aceastǎ valoare şi se încearcǎ o alta (dintre cele netestate în aceastǎ etapǎ).
Într-adevǎr, oricum am alega celelalte valori, dacǎ una nu corespunde nu
putem avea o soluţie.

Altgoritmul general al metodei Backtracking


Pentru evitarea generǎrii combinaţiilor neconvenabile se procedeazǎ
astfel:
Presupunem cǎ s-au gǎsit valorile v1v2…vk-1 pentru componentele
x1x2... xk-1 (au rǎmas de determinat valorile pentru xk…xn). ne ocupǎm în
continuare de componenta xk. Paşii urmaţi sunt:
1. Pentru început, pentru xk nu s-a testat încǎ nici o valoare.
2. Se verificǎ dacǎ existǎ valori netestate pentru xk .
a) În caz afirmativ, se trece la pasul 3.
b) Altfel, se revine la componenta anterioarǎ, xk-1; se reia pasul
2 pentru k=k-1.
3. Se alege prima valoare v dintre cele netestate încǎ pentru xk.
4. Se verificǎ dacǎ acestǎ combinaţie parţialǎ v1v2…vk-1v ne poate
conduce la un rezultat (dacǎ sunt îndeplinite anumite condiţii de
continuare).
a) Dacǎ valoarea aleasǎ este bunǎ se trece la pasul 5.
b) Altfel, se rǎmâne pe aceeaşi poziţie k şi se reia cazul 2.
5. Se verificǎ dacǎ s-a obţinut o soluţie .
a) În caz afirmativ, se tipǎreşte aceastǎ soluţie şi se rǎmâne la
aceeaşi componentǎ xk, reluându-se pasul 2.
b) Altfel se reia altgoritmul pentru urmǎtoarea componentǎ (se
trece la pasul 1 pentru k=k+1).

Înainte de a scrie programul care ne va obţine soluţiile, trebuie sǎ


stabilim unele detalii cu privire la:
- vectorul soluţie – câte componente are, ce menţine fiecare
componentǎ.
- mulţimea de valori posibile pentru fiecare componentǎ (sunt
foarte importante limitele acestei mulţimi).
- condiţiile de continuare (condiţiile ca o valoare x[k]sǎ fie
acceptatǎ).
- condiţia ca ansamblul de valori generat sǎ fie soluţie.

Probleme :

Problema damelor :

#include<iostream.h>
#include<math.h>

int st[100],n,k;

void init()
{
st[k]=0;
}

int am_succesor()
{
if(st[k]<n){st[k]++;
return 1;
}
else return 0;
}

int e_valid()
{
for(i=1;i<k;i++)if(st[k]==st[i] || abs(st[k]-st[i])==abs(k-i))return 0;
return 1;
}

int solutie()
{
return k==n;
}
void tipar()
{
for(i=1;i<=n;i++)cout<<st[i];
cout<<endl;
}

void back()
{
int as;k=1;
init();
while(k>0)
{
do{}while((as=am_succesor()) && !e_valid());
if(as)if(solutie())tipar();
else {k++;init();}
else k--;
}
}

int main()
{
cout<<"n=";cin>>n;
back();
}

Generarea combinarilor :

#include<iostream.h>
int st[10],n,k;

void init()
{
if(k>1)st[k]==st[k-1];
else st[k]=0
}

int am_succesor()
{
if(st[k]<n-p+k){st[k]++;
return 1;
}
else return 0;
}

int e_valid()
{
return 1;
}

int solutie()
{
return k==p }

void tipar()
{
for(i=1;i<=p;i++)cout<<st[i];
cout<<endl;
}

void back()
{
int as;
k=1;
init();
while(k>0)
{
do{}while((as=am_succesor()) && !e_valid());
if(as)if(solutie())tipar();
else { k++;init(); }
else k--;
}
}

int main()
{
cout<<"n=";cin>>n;
cout<<"p=";cin>>p;
back();
}

Colorarea hartilor :

/*Fiind data o harta cu n tari,se cere tpate solutiile de colorare a hartii


utilizand cel mult 4 culori astfel incat doua tari cu frontiera comuna sa fie
colorate diferit.
Harta este furnizata astfel : A(i,j) = 1 , tara i are frontiera comunca cu tara j
0 , astfel

#include<iostream.h>
int st[10],a[20][20],n,k,i;

void init()
{
st[k]=0
}

int am_succesor()
{
if(st[k]<4){st[k]++;
return 1;
}
else return 0;
}

int e_valid()
{
for(i=1;i<=k-1;i++)
if(st[i]==st[k] && a[i][k]==1)return 0;
return 1;
}

int solutie()
{
return k==n }
void tipar()
{
cout<<"Varianta"<<endl;
for(i=1;i<=n;i++)cout<<"Tara "<<i<< " are culoarea "<<st[i]<<endl;
cout<<endl;
}

void back()
{
int as;
k=1;
init();
while(k>0)
{
do{}while((as=am_succesor()) && !e_valid());
if(as)if(solutie())tipar();
else { k++;init(); }
else k--;
}
}

int main()
{
cout<<"Numarul de tari :";cin>>n;
for(i=1;i<=n;i++)
for(j=1lj<=i-1;j++)
{
cout<<a["<<i<<','<<j<<"]=";cin>>a[i][j];
a[j][i]=a[i][j];
}
back();
}