Documente Academic
Documente Profesional
Documente Cultură
Vlada
METODA BACKTRACKING
Metoda se aplica pentru problemele ale căror soluţii se pot reprezenta sub formă
de vectori
n
S = (x1 ,..., x n ) ∈ S = ∏ S i
i =1
unde S = spaţiul soluţiilor posibile
si = |Si|; Si fiind de o anumită natură (tipuri de date reale,
matrice etc.).
Complexitatea problemei este determinată de dimensiunea spaţiilor soluţiilor
posibile.
|S| = s1,…sn
1
Conf. dr. M. Vlada
Si={1,2,…n}, i=1,…,n
si=n si |S|=nn dimensiunea spaţiilor soluţiilor posibile
Vectorul X=(xi)i=1,…,n este soluţie rezultat, dacă
are valoarea true în cazul în care (x1,…,xk) poate fi dintr-o soluţie rezultat.
2
Conf. dr. M. Vlada
1 2.. … s1
x1 → s1 noduri
. . .
. . .
. . .
s1…sn
1 2 ..sn 1 2. ….sn 1 2…sn noduri
xn →
Arborele ataşat spaţiului soluţiilor posibile.
1 2.. … n
x1 → n noduri
1 2….n 1 2 .. n 1 2...n n2
x2 → noduri
. . .
. . .
. . .
3
Conf. dr. M. Vlada
x1 →
x2 → Observaţie:
ϕn(x1,…,xn) ≡ ϕ
x3 →
xk-1 →
1 2 sk 1 2 sk 1 2 sk
xk →
Implementarea metodei
Procedura nerecursivă
INPUT :
{ }
____
S k = α k1 , α k2 ,..., α ksk , k = 1, n, sk = sk
( )
∧
valorile α k0 ∉ S k cu proprietatea ca succ α k0 = α k
ϕk(x1,…,xk) condiţii de continuare
Procedure BACK;
4
Conf. dr. M. Vlada
Varianta recursivă:
Procedure BACK(k:integer);
if k=k+1 then
write (x1,x2,…,xn)
else {se caută altă soluţie}
xk← αk0 {valoare de start}
sk
while xk< αk do {Sk nu s-a epuizat}}
xk ← succ(xk)
if ϕk(x1,…,xk) then back(k+1)
Utilizare:
BACK(1);
program permutari;
var
x:array[1..200] of integer;
nr,i,n,k:integer;
function col(k:integer):boolean;
begin
col:=true;
for i:=1 to k-1 do
if x[i]=x[k] then
begin
col:=false;
exit;
end;
end;
begin
write('n=');
readln(n);
5
Conf. dr. M. Vlada
nr:=0;
k:=1;
for i:=1 to n do
x[i]:=0;
while k>0 do
if k=n+1 then
begin
k:=k-1;
nr:=nr+1;
writeln(' solutia nr ',nr);
for i:=1 to n do
write(x[i]:2);
readln;
end
else
if x[k]<n then
begin
x[k]:=x[k]+1;
if col(k) then
k:=k+1;
end
else
begin
x[k]:=0;
k:=k-1;
end;
end.
Condiţii interne:
Fie i şi j două dame:
a) damele să nu se afle pe aceeaşi coloană xi≠xj; i≠j
b) să nu se afle pe diagonala xi , xj
(i,xi) (i,xi)
(j,xj) (j,xj)
j-i ≠ xj – xi i-j ≠ xi -xj
|i-j| ≠ |xi-xj|
6
Conf. dr. M. Vlada
Program cele_8_regine;
var
x:array[1..200] of integer;
nr,i,n,k:integer;
function col(k:integer):boolean;
begin
col:=true;
for i:=1 to k-1 do
if (x[i]=x[k]) or (abs(i-k)=abs(x[i]-x[k])) then
begin
col:=false;
exit;
end;
end;
begin
write('n=');
readln(n);
nr:=0;
k:=1;
for i:=1 to n do
x[i]:=0;
while k>0 do
if k=n+1 then
begin
k:=k-1;
nr:=nr+1;
writeln(' solutia nr ',nr);
for i:=1 to n do
write(x[i]:2);
readln;
end
else
if x[k]<n then
begin
x[k]:=x[k]+1;
if col(k) then
k:=k+1;
end
else
begin
x[k]:=0;
k:=k-1;
end;
end.
Observaţii:
Pentru n = 3, nu sunt soluţii;
Pentru n = 4 sunt 2 soluţii: 2 4 1 3, 3 1 4 2;
Pentru n = 5 sunt 10 soluţii: 1 3 5 2 4; 1 4 2 5 3, 2 4 1 3 5, … , 5 3 1 4 2
Pentru n = 6 sunt 4 soluţii: 2 4 6 1 3 5, 3 6 2 5 1 4, 4 1 5 2 6 3, 5 3 1 6 4 2;
Pentru n = 8 există 92 de soluţii, dintre care 12 sunt distincte ( restul au fost obţinute
din simetricele lor, prin rotirea tablei cu 900, 1800, 2700).
Ex: 1 5 8 6 3 7 2 4, 1 6 8 3 7 4 2 5, 1 7 4 6 8 2 5 3, 1 7 5 8 2 4 6 3, 2 4 6 8 3 1 7 5,
2 5 7 1 3 8 6 4, 2 5 7 4 1 8 6 3, 2 6 1 7 4 8 3 5, 2 6 8 3 1 4 7 5, 2 7 3 6 8 5 1 4,
2 7 5 8 1 4 6 3, 2 8 6 1 3 5 7 4, 3 1 7 5 8 2 4 6, 3 5 2 8 1 7 4 6, 3 5 2 8 6 4 7 1,
3 5 7 1 4 2 8 6, 3 5 8 4 1 7 2 6, 3 6 2 5 8 1 7 0 … sol 92 = 8 4 1 3 6 2 7 5.
7
Conf. dr. M. Vlada
Program colorare_harti;
var
a:array[1..30,1..30] of 0..1;
x:array[1..30] of integer;
nr,i,j,n,m,k,c:integer;
function cont(k:integer):boolean;
begin
cont:=true;
for i:=1 to k-1 do
for j:=i+1 to k do
if (a[i,j]=1) and (x[i]=x[j]) then
begin
cont:=false;
8
Conf. dr. M. Vlada
exit;
end;
end;
begin
write('nr de noduri (tari): n=');
readln(n);
write('nr.de muchii (vecini): m=');
readln(m);
nr:=0;
k:=1;
for i:=1 to n do
for j:=1 to n do
a[i,j]:=0;
writeln('introduceti muchiile (i j):');
for i:=1 to m do
begin
readln(k,c);
a[k,c]:=1;
a[c,k]:=1;
end;
write('nr. de culori c=');
readln(c);
k:=1;
for i:=1 to n do
x[i]:=0;
while k>0 do
if k=n+1 then
begin
k:=k-1;
nr:=nr+1;
writeln(' solutia nr ',nr);
for i:=1 to n do
write(x[i]:2);
readln;
end
else
if x[k]<c then
begin
x[k]:=x[k]+1;
if cont(k) then
k:=k+1;
end
else
begin
x[k]:=0;
k:=k-1;
end;
end.
9
Conf. dr. M. Vlada
xn-1
n →
←
1 xn-1
1 →
A,left B,centre C,right
Demonstratia faptului ca 2n-1 este numarul minim de mutari pentru cele n discuri.
xn = nr. minim de mutări
xn= ?
xn=xn+1 + 1 + xn-1
↓ ↓ ↓
trecere trecere trecerea celor
pe C A→B (n-1) discuri
pe B
xn=2xn-1+1
xn+1=2xn-1+2
yn=xn+1
yn=2yn-1, y0=0
yn=2n ===>xn=2n-1 nr. minim de mutari pentru cele n discuri.
Program turnuri_Hanoi;
( metoda: Divide et impera }
var
n:integer;
10
Conf. dr. M. Vlada
a,b,c:char;
procedure Hanoi(n:integer;a,b,c:char);
begin
if n=1 then
writeln(a,b)
else
begin
Hanoi(n-1,a,c,b);
writeln(a,b);
Hanoi(n-1,c,b,a);
end;
end;
begin
write('dati nr.de discuri n=');
readln(n);
a:='a'; b:='b'; c:='c';
Hanoi(n,a,b,c);
end.
11