Documente Academic
Documente Profesional
Documente Cultură
?
Backtracking
Spaiul soluiilor
Fie mulimile ,
, o relaie de ordine pe
spaiul soluiilor
funcie de validare
Backtracking cutare
complet
lent, costisitoare, complexitate mare
Metod
,,
- condiii de continuare
se construiete element cu element
se trece la elementul
altfel se alege alt valoare pentru
valoarea aleas pentru e consumat mulimea valorilor consumate
dac nu mai snt valori disponibile se revine la elementul anterior
nu garanteaz obinerea unei soluii rezultat
Reprezentare date
ie curent
Configura
Configuraie iniial
Configuraie soluie
Configuraie final
Rezolvare problem:
Operaii
i avanseaz
Atribuie
ncercare euat
Revenire
//construire
configuraie iniial
ct timp
//ct timp configuraia nu e final
dac
//configuraie de tip soluie?
reine soluia
altfel
Implementare recursiv
void back(unsigned k)
{
if (k==n) retine_solutie();
else
{
x[k]=init(k);
while (succ(k))
if (continuare(k)) back(k+1);
}
}
retine_solutie - descrie prelucrarea dorit pentru o soluie determinat;
init(k) iniializeaz xk cu o valoare prin care se indic faptul c, pn la acel
moment, nu a fost selectat nici o alternativ pentru poziia k;
succ(k) - calculeaz 1, dac exist succesor pentru xk n Sk (determina i
succesorul)
continuare(k) - calculeaz 1 dac este posibil extinderea drumului curent.
Implementare recursiv
Generarea permutrilor
S se genereze toate permutrile mulimii {1, 2,..., n}.
Generarea permutrilor
unsigned x[7], n;
unsigned init()
{
return 0;
}
unsigned succ(unsigned k)
{
return x[k]++<n;
}
unsigned continuare(unsigned k)
{
unsigned i;
for(i=0;(i<k)&&(x[i]-x[k]);i++);
return i==k;
}
Generarea permutrilor
void retine_solutie()
{
for (int i=0;i<n;i++) printf("%u ",x[i]);
printf("\n");
getch();
}
void back(unsigned k)
{
if(k==n) retine_solutie();
else
{
x[k]=init();
while(succ(k))
if(continuare(k))back(k+1);
}
}
Generarea permutrilor
void retine_solutie()
{
for (int i=0;i<n;i++) printf("%u ",x[i]);
printf("\n");
getch();
}
void back(unsigned k)
{
if(k==n) retine_solutie();
else
{
x[k]=init();
while(succ(k))
if(continuare(k))back(k+1);
}
}
Generarea permutrilor
Simplificri n scrierea codului,:
funcia init(k) nu depinde de valoarea lui k i returneaz ntotdeauna
valoarea 0;
funcia succ(k) nu depinde de valoarea parametrului k i realizeaz
ntotdeauna o incrementare (S0 = S1 = ... =Sn-1 = {1, 2,..., n}).
void back(unsigned k)
{
unsigned i;
if (k==n) retine_solutie();
else
for (i=1;i<=n;i++)
{
x[k]=i;
if (continuare(k))back(k+1);
}
}
nlocuirea structurii repetitive while cu ciclul for este posibil datorit faptului
c funcia succ realiza incrementarea valorii elementului x[k].
conf k conf i k i
unsigned x[7],n,p;
unsigned init()
{return 0;}
unsigned succ(unsigned k)
{return x[k]++<n;}
unsigned continuare(unsigned k)
{
unsigned i;
for(i=0;(i<k)&&(x[i]-x[k]);i++);
return i==k;
}
void retine_solutie()
{
for (int i=0;i<p;i++) printf("%u ",x[i]);
printf("\n");getch();
}
void back(unsigned k)
{
if(k==p) retine_solutie();
else
{
x[k]=init();
while(succ(k))
if(continuare(k))back(k+1);
}
}
0, S[i] SubS
SubS[i]=
1, altfel
Problema canibalilor i a
misionarilor
typedef struct{
int ncs,ncd,nms,nmd; //nr. de canibali si misionari de pe malurile
stang si drept ale raului
int pb; // pozitia barcii
}stare;
stare sol[50];
Problema canibalilor i a
misionarilor
int mut[2][5]={{0,1,1,2,0},{1,0,1,0,2}}; // (mut[0][i],mut[1][i])-o
posibilitate corect de a alege
// mut[0][i] canibali i mut[1][i] misionari pentru a ndeplini condiia
de non-atac la o mutare
FILE *f; // Fisierul in care prezint solutiile problemei
// Funcia verific dac starea st a fost deja trecuta in vectorul solutie
unsigned visit(stare st,int l)
{
// 1- starea st a fost trecuta anterior in solutie, 0- in caz contrar
for(int i=0;i<l;i++)
if ((sol[i].ncs==st.ncs) &&(sol[i].ncd==st.ncd) &&
(sol[i].nmd==st.nmd) &&(sol[i].nms==st.nms) &&
(sol[i].pb==st.pb))
return 1;
return 0;
}
Problema canibalilor i a
misionarilor
// Funcia verific dac starea st este o stare valid (respect condiiile
problemei)
unsigned pot_muta(stare st, int j)
{
// 1- starea st poate fi acceptata
// 0- in caz contrar
if (st.pb==-1) // barca este pe malul stng
if((st.ncs>=mut[0][j]) &&
// pot selecta mut[0][j] canibali i
mut[1][j] misionari
(st.nms>=mut[1][j]))
return 1;
if (st.pb==1) // barca este pe malul drept
if((st.ncd>=mut[0][j])&&(st.nmd>=mut[1][j]))
return 1;
return 0;
}
Problema canibalilor i a
misionarilor
void back(stare st, int l)
{
stare st1; int i,j; st=sol[l];
if((st.ncd+st.nmd==6)&&(st.pb==1)){// o poziie valid
for(i=0;i<=l;i++){
fprintf(f,"Mal st.: canibali="); fprintf(f,"%u",sol[i].ncs);
fprintf(f,", misionari="); fprintf(f,"%u",sol[i].nms);
fprintf(f," Mal dr.: canibali="); fprintf(f,"%u",sol[i].ncd);
fprintf(f,", misionari="); fprintf(f,"%u",sol[i].nmd);
fprintf(f," barca pe malul ");
if (sol[i].pb==-1) fprintf(f,"stang\n");
else fprintf(f,"drept\n");
}
fprintf(f,"\n");
}
Problema canibalilor i a
misionarilor
else
for (j=0;j<5;j++) // pentru toate cele 5 posibiliti de alegere a unei
mutri
if(((st.ncs+st.pb*mut[0][j]<=st.nms+st.pb*mut[1][j]) ||
(st.nms+st.pb*mut[1][j]==0)) &&
// dac nr. canibali rmai pe malul stng<= nr. misionari rmai pe
malul stng
//sau nr. misionari rmai pe malul stng =0
((st.ncd-st.pb*mut[0][j]<=st.nmd-st.pb*mut[1][j]) || (st.nmdst.pb*mut[1][j]==0)) &&
(st.nms+st.pb*mut[1][j]>=0) &&
//dac nr. misionari rmai pe malul stng este nenegativ
(st.ncs+st.pb*mut[0][j]>=0) &&
(st.nmd-st.pb*mut[1][j]>=0) && (st.ncd-st.pb*mut[0][j]>=0)
&&pot_muta(st,j)){
st1=st;
st1.ncs+=st1.pb*mut[0][j];
st1.nms+=st1.pb*mut[1][j];
st1.nmd-=st1.pb*mut[1][j];
st1.ncd-=st1.pb*mut[0][j];
st1.pb=-st1.pb;
Problema canibalilor i a
misionarilor
Mal stng
Mal drept
Poziie barc
Mal dr.: canibali=0 , misionari=0 barca pe
Mal dr.: canibali=1 , misionari=1 barca pe
Mal dr.: canibali=1 , misionari=0 barca pe
Mal dr.: canibali=3 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=2 barca pe
Mal dr.: canibali=1 , misionari=1 barca pe
Mal dr.: canibali=1 , misionari=3 barca pe
Mal dr.: canibali=0 , misionari=3 barca pe
Mal dr.: canibali=2 , misionari=3 barca pe
Problema canibalilor i a
misionarilor
Mal stng
Mal drept
Poziie barc
Mal dr.: canibali=0 , misionari=0 barca pe
Mal dr.: canibali=1 , misionari=1 barca pe
Mal dr.: canibali=1 , misionari=0 barca pe
Mal dr.: canibali=3 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=2 barca pe
Mal dr.: canibali=1 , misionari=1 barca pe
Mal dr.: canibali=1 , misionari=3 barca pe
Mal dr.: canibali=0 , misionari=3 barca pe
Mal dr.: canibali=2 , misionari=3 barca pe
Problema canibalilor i a
misionarilor
Mal stng
Mal drept
Poziie barc
Mal dr.: canibali=0 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=0 barca pe
Mal dr.: canibali=1 , misionari=0 barca pe
Mal dr.: canibali=3 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=2 barca pe
Mal dr.: canibali=1 , misionari=1 barca pe
Mal dr.: canibali=1 , misionari=3 barca pe
Mal dr.: canibali=0 , misionari=3 barca pe
Mal dr.: canibali=2 , misionari=3 barca pe
Problema canibalilor i a
misionarilor
Mal stng
Mal drept
Poziie barc
Mal dr.: canibali=0 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=0 barca pe
Mal dr.: canibali=1 , misionari=0 barca pe
Mal dr.: canibali=3 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=0 barca pe
Mal dr.: canibali=2 , misionari=2 barca pe
Mal dr.: canibali=1 , misionari=1 barca pe
Mal dr.: canibali=1 , misionari=3 barca pe
Mal dr.: canibali=0 , misionari=3 barca pe
Mal dr.: canibali=2 , misionari=3 barca pe
Spor la nvat!