You are on page 1of 10

Noiuni teoretice - Backtraking

Prezentare general
Aceast metod general de programare se aplic problemelor n care soluia se poate
reprezenta sub forma unui vector X = (x1, ..., xn!" unde " = "1 x ... x "n , unde mulimile
"1, ...,"n sunt mulimi finite av#nd $"i$ = si elemente. %entru fiecare problem concret sunt
date anumite relaii ntre componentele x1 , ... xn ale vectorului X, numite condiii interne.
&ulimea finit " = "1 x "' x... x "n se nume(te spaiul soluiilor posibile (este un produs
cartezian. "oluiile posibile care satisfac condiiile interne se numesc soluii rezultat. )eea ce
ne propunem este de a determina toate soluiile rezultat, cu scopul de a le afi(a sau de a alege
dintre ele una care maximizeaz sau minimizeaz o eventual funcie obiectiv dat.
* metoda simpl de determinare a soluiilor rezultat const n a genera ntr+un mod oarecare
toate soluiile posibile (i de a verifica dac ele satisfac condiiile interne. ,ezavanta-ul const
n faptul c timpul cerut de aceast investigare ex.austiv este foarte mare. Astfel, c.iar
pentru $"i$ = ', / i, timpul necesar este de ordinul 'n, deci exponenial.
&etoda bac0trac0ing urmre(te s evite generarea tuturor soluiilor posibile. !n acest scop,
elementele vectorului X primesc pe r#nd valori n sensul c lui x0 i se atribuie o valoare numai
dac au fost atribuite de-a valori lui x1 ,... x0+1 . &ai mult, odat o valoare pentru xn
stabilit, nu se trece direct la atribuirea de valori lui x011 , nendeplinirea lor exprim#nd faptul
c oricum am alege x011,...,xn nu vom putea a-unge la o soluie rezultat, adic o condiie
pentru care condiiile interne s fie satisfcute. 2vident c n cazul nendeplinirii condiiilor de
continuare va trebui s facem o alt alegere pentru x0 sau dac "0 a fost epuizat s mic(orm
pe 0 cu o unitate ncerc#nd s facem o nou alegere pentru x0 etc.3 aceast mic(orare a lui 0
d numele metodei, ilustr#nd faptul c atunci c#nd nu mai putem avansa, urmrim napoi
secvena curent din soluie. 2ste evident c ntre condiiile de continuare (i condiiile interne
exist o str#ns legtur. * bun alegere pentru condiiile de continuare are ca efect o
important reducere a numrului de calcule.
&etoda bac0trac0ing poate fi reprezentat u(or, pe un arbore construit astfel4
+ nivelul 1 conine rdcina3
+ din orice v#rf de pe nivelul 0 pleac s0 muc.ii spre nivelul 011 etic.etai cu cele s0 muc.ii
ale lui "0.
5ivelul n11 va conine s1 6 s' 6 ... 6 sn v#rfuri. %entru fiecare v#rf de pe nivelul n11,
etic.etele muc.iilor coninute pe drumul ce leag rdcina de acest v#rf reprezint o soluie
posibil.
2xemplu + " considerm problema submulimilor de sum dat care const n urmtoarele4
7ie A = (a1, a', ..., an cu ai 8 9, / i. 7ie &!:1. "e caut toate submulimile ; ale lui A pentru
care suma elementelor este &.
%entru a putea realiza problema prin metoda bac0trac0ing vom reprezenta soluia sub forma x
= (x1, ..., xn unde xi = 1 dac ai!; (i xi = 9 n caz contrar. "a ne situm n ipoteza ca n=<.
Arborele ata(at metodei bac0trac0ing este urmtorul4
)#(tigul obinut prin introducerea condiiilor de continuare const n faptul c, dac ntr+un
v#rf ele nu mai sunt verificate, se va renuna la parcurgerea subarborelui care are ca rdcin
acest v#rf.
Acest exemplu permite prezentarea unei variante a metodei bac0trac0ing. !ntr+adevr, s
considerm drept soluie posibil o valoare 0 = n mpreun cu 0+uplul (x1, ..., x0 unde pentru
i ! >1, ..., 0?, xi reprezint indicele elementului pe care l introducem n ;. 2vident xi @ x-
pentru i@-. %entru a nu se repeta soluii, vom presupune x1Ax'A...Axn .
*binem astfel urmtorul arbore n care fiecare v#rf corespunde unei soluii posibile.
,iferitele variante ale metodei bac0trac0ing nu sc.imb esena ei care const n faptul c este
reprezentabil pe un arbore care este parcurs /cobor#nd/ n arbore numai dac exist (anse
de a a-unge la o soluie rezultat.
!n continuare, problemele care vor fi prezentate vor urma o sc.ema general (i anume4
+ se va testa dac am obinut o soluie, situaie n care acesta se va reine3
+ dac nu am obinut soluie se ncearc plasarea unui nou element n vectorul soluie cu
respectarea condiiilor de continuare3
+ dac nu se reu(e(te plasarea unui nou element (i spaiul valorilor posibile de plasat s+a
epuizat, se revine la poziia anterioar (i se ncearc s se plaseze pe ea un alt element.
7aptul c dup plasarea unui element n vectorul soluie algoritmul presupune plasarea unui
element pe poziia imediat urmtoare, adic de fapt reluarea algoritmului, conduce
posibilitatea abordrii recursive a algoritmilor de tip bac0trac0ing. Acest lucru permite o scriere
mult mai scurt (i mai simpl a algoritmilor (i apoi a programelor care i implementeaz.
Astfel, general, un algoritm bac0trac0ing poate fi prezentat astfel4
Subalgoritm back (k)
pentru fiecare valoare i din multimea "0 execut
x0i
dac X respect condiiile interne atunci
dac X este solutie atunci
afiseaz X
altfel
apeleaz bac0(011
sfdac
sfdac
sfpentru
!n funcie de problema concret, n algoritmul descris mai sus se vor modifica doar
instruciunea pentru, condiiile interne (i cele de soluie, structura algoritmului pstr#ndu+se.
Probleme de generare. Oportunitatea utilizrii metodei backtracking
%roblemele care se rezolv prin metoda bac0trac0ing pot fi mprite n mai multe grupuri de
probleme cu rezolvri asemntoare, in funcie de modificrile pe care le vom face n algoritm.
%rincipalele grupuri de probleme sunt4
a probleme n care vectorul soluie are lungime fix (i fiecare element apare o singur dat n
soluie3
b probleme n care vectorul soluie are lungime variabil (i fiecare element poate s apar de
mai multe ori n soluie3
c probleme n plan, atunci c#nd spaiul n care ne deplasm este un tablou bidimensional.
Bom prezenta n cele ce urmeaz c#teva probleme care pac parte din primul grup. )ele mai
cunoscute sunt4
generarea permutrilor unei mulimi
generarea aran-amentelor unei mulimi
generarea submulimilor unei mulimi
generarea submulimilor cu m elemente ale unei mulimi (combinri
generarea produsului cartezian a n mulimi
generarea tuturor secvenelor de n (par paranteze care se nc.id corect.
colorarea rilor de pe o .art astfel nc#t oricare dou ri vecine s aib culori
diferite
aran-area a n regine pe o tabl de (a. de dimensiune n fr ca ele s se atace.
Coate problemele din acest grup au particularitatea c soluia se obine atunci c#nd vectorul
soluie a-unge s conin un anumit numr de elemente.
Bom exemplifica modul de lucru al metodei bac0trac0ing pentru problema damelor.
Aranjarea reginelor. ,#ndu+se o tabl de (a. de dimensiune nxn (n8D s se aran-eze pe ea
n regine fr ca ele s se atace. :eamintim c o regin atac linia, coloana (i cele ' diagonale
pe care se afl. !n figura de mai -os celulele colorare mai nc.is sunt atacate de regina
poziionat unde indic litera E:F.


R

!n algoritmul de mai sus avem de particularizat urmtoarele4
Gnstruciunea pentru fiecare valoare i din mulimea "0 execut va fi nlocuit cu o instruciune
pentru care parcurge toate valorile de la 1 p#n la n.
)ondiia de a putea plasa o regin pe poziia 0 este un pic mai complicat (i presupune
verificarea ca s nu se atace cu nici una dintre celelalte 0+1 regine de-a plasate pe tabla. ,ac
pe poziia 0 din vectorul X punem o valoare ea va reprezenta coloana pe care se plaseaz pe
tabl regina 0. )ondiiile devin astfel4
xHiI@xH0I (i $0+i$@$xH0I+xHiI$ cu i de la 1 la 0+1 (i $x$ reprezent#nd modului lui x.
)ondiia de soluie este simpl (i presupune plasarea corect a tuturor celor n regine.
%rogramele %ascal si )11 rezultate prin implementarea algoritmului descris mai sus
urmtoarele4
Varianta Pascal
Varianta C/C++
var x:array[1..100] of byte;
n:byte;
nrsol:word;
procedure scriesol;
var i,j:byte;
begin
incnrsol!;
writeln"#olutia a",nrsol,"este"!;
for i:$1 to n do begin
writeln;
for j:$1 to n do if x[j]$i
t%en write"&"," "!
else write"'"," "!;
end;
end;
function potcont(:byte!:boolean;
var i:byte;
atac:boolean;
begin
atac:$false;
for i:$1 to ()1 do
ifx[i]$x[(]! or ()i$absx[(])x[i]!! t%en
atac:$true;
potcont:$not atac;
end;
procedure bac((:byte!;
var i:byte;
begin
for i:$1 to n do
begin
x[(]:$i;
if potcont(! t%en
if ($n t%en scriesol
else bac((*1!;
end;
end;
begin
readn!;
+include,iostrea-.%.
+include,-at%.%.
int x[100],n,nrsol;
void scriesol !
/ int i,j;
nrsol**;
cout,,0#olutia a 0,,nrsol,,0 este0;
fori$1;i,$n;i**!
/ cout,,endl;
forj$1;j,$n;j**!
if x[j]$$i! cout,,0& 0;
else cout,,0' 0;
1
1
int potcontint (!
/ int i;
fori$1;i,$()1;i**!
if x[i]$$x[(] 22 ()i$$absx[(])x[i]!! return 0;
return 1;
1
void bac(int (!
/
int i;
fori$1;i,$n;i**!
/
x[(]$i;
if potcont(!!
if ($$n! scriesol!;
else bac((*1!;
1
1
void -ain!
/
cin..n;
nrsol$0;
bac(1!;
cout,,nrsol,,0 solutii0;
nrsol:$0;
bac(1!;
writelnnrsol,"solutii"!;
end.
1
,in al doilea grup fac parte probleme a cror condiie de soluie nu se mai pune asupra
numrului de elemente din vectorul X, ci asupra elementelor din soluie. 2xemple4
partiiile unui numr natural n
partiiile unei mulimi
plata unei sumei cu monede de valori date
Partiiile unui numr natural. 7ie n89, natural. " se scrie un program care s afi(eze
toate partiiile unui numr natural n.
5umim partiie a unui numr natural nenul n o mulime de numere naturale nenule >p1, p',
J, p0? care ndeplinesc condiia p11p'1 J1p0 = n.
2x4 pt n = < programul va afi(a4
< = 1111111
< = 1111'
< = 11D
< = '1'
< = <
*bservaii4 + lungimea vectorului soluie cel mult n3
exist posibilitatea ca soluiile s se repete3
condiia de final este ndeplinit atunci c#nd suma elementelor vectorului soluie este
n.
Am menionat mai sus c vom folosi doi parametri, unul pentru poziia n vectorul soluie (i un
al doilea n care avem sumele pariale la fiecare moment. Avem determinat o soluie atunci
c#nd valoarea celui de+al doilea parametru este egal cu n.
!n aceast situaie la fiecare plasare a unei valori n vectorul sol valoarea celui de al doilea
parametru se mre(te cu elementul ce se plaseaz n vectorul soluie. Apelul procedurii bac0
din programul principal va fi bac0(1, 9.
2xist (i posibilitatea de a apela procedura bac0 din programul principal bac0(1, n (i valoarea
celui de al doilea parametru se decrementeaz cu elementul ce se plaseaz n vectorul sol, iar
o soluie avem c#nd acest parametru este zero. Gndiferent care modalitate este aleas acest al
doilea parametru ne permite s optimizm puin programul n sensul c putem considera ni(te
condiii de continuare mai str#nse.
Varianta Pascal Varianta C/C++
progra- 3artitii4nr4natural;
var n, ns: byte;
sol: array[1..50] of byte;
procedure afisl: byte!;
var i: byte;
begin
incns!;
write "#olutia ", ns, " : "!;
for i:$1 to l do
writesol[i]:6!;
writeln;
end;
procedure bac(i, sp: byte!;
var j: byte;
begin
if sp $ n t%en afisi)1!
else for j:$1 to n)sp do
if j.$sol[i)1]!
t%en begin
sol[i]:$j;
bac(i*1, sp*j! end;
end;
begin
readn!;
ns:$0;
bac(1,0!;
writelnns,"solutii"!;
end.
+include,iostrea-.%.
int n, ns,sol[50];
void afisint l!
/ int i;
ns**;
cout,,0#olutia nr. 0,, ns,,0 : 0;
fori$1;i,$l;i**! cout,,sol[i],,0 0;
cout,,endl;
1
void bac(int i, int sp!
/ int j;
if sp$$n! afisi)1!;
else forj$1;j,$n)sp;j**!
if j.$sol[i)1]!
/
sol[i]$j;
bac(i*1, sp*j!;
1
1
void -ain!
/
cin..n;
ns$0;
bac(1,0!;
cout,,ns,,0 solutii0;
1

%roblemele n plan necesit parcurgerea unui tablou unidimensional, iar cele mai cunoscute
sunt4
parcurgerea tablei de (a. cu un cal, fr a trece de dou ori prin aceea(i poziie
gsirea ie(irii dintr+un labirint
%roblemele care se rezolv prin metoda bac0trac0ing n plan au ca cerin deplasarea n
tablou, pe linii, coloane sau diagonale sau prin sritur (de obicei sritura calului dintr+un
punct n alt punct al tabloului sau pe frontier (prima linie sau coloan, ultima linie sau
coloan eventual respect#nd anumite condiii de deplasare. ,ac ne gsim ntr+un anumit
punct iar cerina este de a ne deplasa n unul din cei opt vecini ai lui vom utiliza pentru acest
lucru dou cicluri for de la K1 la 1 cu care valori vom modifica coordonata punctului curent.
,ac deplasarea este permis numai pe linii condiia de respectat este ca suma n valoare
absolut pentru cei doi indici s fie 1, iar pentru deplasarea pe diagonal '. ,e asemenea se
mai impune condiia de a nu prsi tabloul, lucru care l vom respecta test#nd coordonatele
noului punct s aparin mulimii H1..nrliniiI (i H1..nrcolI.
Sritura calului. 7iind dat o tabl de (a. de dimensiunea nxn (i un cal n colul st#nga sus
al acesteia, se cere s se afi(eze toate posibilitile de mutare a acestei piese de (a. astfel
nc#t s treac o singur dat prin fiecare ptrat al tablei. * soluie va fi afi(at ca o matrice
nxn n care sunt numerotate sriturile calului.
2xemplu, pentru n=L, o soluie este
1 1< M '9 'D
19 1M '' 1L N
L ' 1D '< '1
1N 11 < O 1P
D P 1O 1' 'L
%entru rezolvarea acestei probleme vom codifica direciile de deplasare pentru c ar fi
ineficient s scriem dou cicluri for de la K' la ' cu cele 'L de variante de deplasare din care
valide sunt doar opt. ,e asemenea aici spre deosebire de celelalte probleme tratate la
aplicarea metodei bac0trac0ing n plan nu vom folosi un vector soluie, ci vom scrie sriturile
n tablou urmrind ca la revenire s refacem poziiile ocupate pentru a nu se lua bloca-e. !n
figura de mai -os sunt prezentate cele N mutri posibile pentru un cal.


7



Varianta Pascal
Varianta C/C++
const dx:array[1..8] of )5..5$)1,1,5,5,1,)1,)5,)5!;
dy:array[1..8] of )5..5$)5,)5,)1,1,5,5,1,)1!;
var a:array[1..10,1..10] of integer;
n:integer;
f:text;
procedure cit;
var i,j :integer;
begin
readlnn!;
for i:$1 to n do
for j:$1 to n do a[i,j]:$0;
end;
procedure afis;
var i,j:integer;
begin
for i:$1 to n do begin
for j:$1 to n do writef,a[i,j]:6!;
writelnf!;
end;
writelnf!;
end;
9:;7<='; inside i,j:integer!:boolean;
begin
inside:$i in [1..n]!and j in [1..n]!
end;
procedure bac(i,j,pas:integer!;
var (,inou,jnou:integer;
begin
a[i,j]:$pas;
if pas$n>n t%en afis
else for (:$1 to 8 do begin
inou:$i*dx[(];
jnou:$j*dy[(];
if insideinou,jnou! and a[inou,jnou]$0!
t%en bac(inou,jnou,pas*1!;
end;
+include,fstrea-.%.
const int dx[8]$/)1,1,5,5,1,)1,)5,)51;
const int dy[8]$/)5,)5,)1,1,5,5,1,)11;
int a[10][10],n;
ofstrea- f0cal.out0!;
void afis!
/ int i,j;
fori$1;i,$n;i**!
/ forj$1;j,$n;j**! f,,a[i][j],,0 0;
f,,endl;
1
f,,endl;
1
int insideint i,int j!
/
return i.$1 ?? i,$n ?? j.$1 ?? j,$n;
1
void bac(int i, int j, int pas!
/ int (,inou,jnou;
a[i][j]$pas;
if pas$$n>n! afis!;
else for($0;(,8;(**!
/ inou$i*dx[(];
jnou$j*dy[(];
if insideinou,jnou! ?? a[inou][jnou]$$0!
bac(inou,jnou,pas*1!;
1
a[i][j]$0;
1
void -ain!
/ cin..n;;
bac(1,1,1!;
1
a[i,j]:$0;
end;
begin
assignf,"cal.txt"!;
rewritef!;
cit;
bac(1,1,1!;
closef!;
end.

Qa aceste categorii de probleme se adaug (i cele de optim, care presupun alegerea soluiei
optime dintre cele generate.
,e asemenea, problemele de combinatoric se pot rezolva folosind metoda bac0trac0ing.
"oluiile cerute se pot reprezenta ca vectori de forma X = (x1, ..., xn!" unde " = "1 x ... x
"n, unde mulimile "1, ...,"n sunt mulimi finite. "oluiile se genereaz element cu element (i
trebuie s respecte o serie de reguli, n funcie de problema de generare concret.
Algoritmii de tip bac0trac0ing prezentai n capitolul anterior vor fi folosii pentru a genera
permutri, aran-amente, etc. %entru fiecare probleme, ns, putem face modificri pentru a
cre(te eficiena algoritmului de rezolvare sau pentru a+l simplifica. %entru fiecare algoritm vom
identifica particularitile sale (i condiiile care trebuie puse asupra vectorului soluie.
Algoritmii (i programele prezentate mai -os folosesc mulimi de forma >1,',J,n? pentru a
simplifica lucrurile. Crecerea la o mulime general se face setul de simplu deoarece gener#nd
indicii, practic se genereaz mulimea, (i astfel, oricrui vector soluie X generat pe baza
indicilor i se poate asocia o soluie dintr+o mulime oarecare.
,e asemenea, este bine s numrm c#te soluii genereaz fiecare program (i s verificm
aceste numere cu a-utorul formulelor cunoscute de la matematic.
Generarea permutrilor
"e d o mulime cu n elemente A=>a1,a',J,an?. "e cere s se genereze si s se afi(eze toate
permutrile ei. Altfel spus, se cere s se afi(eze toate modurile n care se pot amesteca
elementele mulimii A.
7olosim pentru generare mulimea >1,',J,n?. )ondiiile care se pun sunt urmtoarele4
7iecare element din vectorul X se ia din >1,',J,n?3
Rn element X0 este valid dac el nu a fost plasat anterior n vectorul soluie X3
)#nd am generat n elemente cu condiiile de mai sus, atunci avem o soluie.
"e pot identifica mai multe modaliti de a verifica dac elementul X0 a fost plasat de-a n
vectorul soluie. )ele mai importante dou sunt4
parcurgerea elementelor de-a generate pentru a verifica daca X0 apare sau nu ntre
ele3
folosirea unui vector cu n elemente n care vom avea valori 9 sau 1 corespunztoare
elementelor mulimii iniiale. Baloarea 1 va preciza faptul c elementul de pe poziia
corespunztoare a fost plasat anterior n vectorul soluie, iar valoarea 9 c nu.
)orespunztor acestor dou moduri de a verifica dac un element a mai fost sau nu plasat n
vectorul soluie, avem ' moduri de generare a permutrilor.
Generarea aranjamentelor
Senerm aran-amentele unei mulimi atunci c#nd ne se cer toate modurile de a alege m
elemente distincte dintre cele n ale mulimii (mAn.
Aceast problem se rezolv foarte u(or folosind metodele de generarea permutrilor.
"ingurele modificri presupun citirea numrului m, modificarea condiiei de soluie, care va fi
0=m n loc de 0=n (i a numrului de elemente afi(ate.
Generarea combinrilor
Senerm combinrilor unei mulimi presupune o condiie suplimentar fa de permutri sau
aran-amente. Acest lucru se datoreaz faptului c generarea combinrilor presupune alegerea
n ordine strict cresctoare a elementelor care compun vectorul soluie.
Astfel, condiia de continuare, sau de validare a unui element este aceea c el trebuie s fie
strict mai mare dec#t cel plasat anterior. !n acest mod asigurm faptul c elementele nu se vor
repeta (i c vor fi generate n ordine strict cresctoare. Crebuie, ns, s avem gri- s nu
punem aceast condiie si asupra primului element din vectorul soluie, deoarece el nu are cu
cine s fie comparat.
* optimizare a algoritmului de generare a combinrilor se poate obine pornind instruciunea
for pentru plasarea unui element de la valoare urmtoare valorii generate anterior. Crebuie s
avem gri- la prima poziie, care nu are element anterior. Am putea iniializa X9 cu 9. Astfel
nu mai trebuie s verificm dac elementul X0 este mai mare ca X0+1.
Generarea produsului cartezian
"e consider n mulimi A1, A', ... , An de forma >1,'..,an?. " se genereze produsul
cartezian al acestor mulimi.
Am considerat mulimile de forma >1,'..,an? pentru a simplifica problema, n special la partea
de citire si afi(are, algoritmul de generare rm#n#nd nemodificat.
Gdentificm urmtoarele particulariti (i condiii4
7iecare element X0 din vectorul soluie aparine unei mulimi >1,'..,a0?. Aici este o
diferen fa de algoritmii anteriori n care fiecare element din soluie era luat din
aceea(i mulime (i trebuie s avem gri- la acest fapt c#nd scriem programul.
5u exist condiii ntre elementele vectorului soluie.
*binem soluia c#nd s+au generat n valori.
Generarea submulimilor unei mulimi
Senerarea submulimilor unei mulimi A cu n elemente se poate face cu a-utorul algoritmului
de generare a combinrilor, apel#ndu+l repetat cu valorile 1, ', ..., n pentru a genera
submulimile cu un element, apoi cele cu dou elemente, apoi cu D elemente etc.
Aceast modalitate de rezolvare este (i mai complicat (i mai puin eficient dec#t
urmtoarea, care se bazeaz pe generarea produsului cartezian >9,1?n. Aceast a doua
metod este eficient deoarece genereaz 'n soluii, adic exact at#tea c#te submulimi are o
mulime cu n elemente.
A(adar, generm toate combinaiile de lungime n cu valorile 9 (i 1. %entru fiecare combinaie
parcurgem soluia X (i afi(m elementele din mulimea A crora le corespund valori 1 n X.
Astfel, pentru combinaia 991911 vom afi(a elementele de pe poziiile D, L (i P din mulimea
iniial.
Generarea partiiilor unei mulimi
Senerm partiiilor unei mulimi presupune mprirea mulimii n mulimi nevide (i dis-uncte
care reunite s dea ntreaga mulime. %utem, ca (i n cazurile anterioare, s considerm
mulimea >1,',J,n?. )onstruim un vector soluie n care pentru fiecare element vom trece
submulimea n care l vom include. Aceast submulime mai este numit (i clas.
Algoritmul genereaz pe r#nd toate modalitile de a mpri elementele mulimii >1,',J,n?
folosind mai nt#i o singur clas, apoi dou, (.a.m.d. p#n la n clase.

You might also like