Sunteți pe pagina 1din 4

Metoda backtracking

Aceast metod general de programare se aplic problemelor n care soluia se poate reprezenta
sub forma unui vector X = (x1, ..., xn)S unde S = S1 x ... x Sn , unde mulimile S1, ...,Sn sunt mulimi
finite avnd |Si| = si elemente. Pentru fiecare problem concret sunt date anumite relaii ntre
componentele x1 , ... xn ale vectorului X, numite condiii interne.
Mulimea finit S = S1 x S2 x... x Sn se numete spaiul soluiilor posibile (este un produs cartezian).
Soluiile posibile care satisfac condiiile interne se numesc soluii rezultat. Ceea ce ne propunem este
de a determina toate soluiile rezultat, cu scopul de a le afia sau de a alege dintre ele una care
maximizeaz sau minimizeaz o eventual funcie obiectiv dat.
O 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. Dezavantajul const n faptul c
timpul cerut de aceast investigare exhaustiv este foarte mare. Astfel, chiar pentru |Si| = 2, " i,
timpul necesar este de ordinul 2n, deci exponenial.
Metoda backtracking urmrete s evite generarea tuturor soluiilor posibile. n acest scop,
elementele vectorului X primesc pe rnd valori n sensul c lui xk i se atribuie o valoare numai dac
au fost atribuite deja valori lui x1 ,... xk-1 . Mai mult, odat o valoare pentru xn stabilit, nu se trece
direct la atribuirea de valori lui xk+1 , nendeplinirea lor exprimnd faptul c oricum am alege
xk+1,...,xn nu vom putea ajunge la o soluie rezultat, adic o condiie pentru care condiiile interne s
fie satisfcute. Evident c n cazul nendeplinirii condiiilor de continuare va trebui s facem o alt
alegere pentru xk sau dac Sk a fost epuizat s micorm pe k cu o unitate ncercnd s facem o nou
alegere pentru xk etc.; aceast micorare a lui k d numele metodei, ilustrnd faptul c atunci cnd
nu mai putem avansa, urmrim napoi secvena curent din soluie. Este evident c ntre condiiile de
continuare i condiiile interne exist o strns legtur. O bun alegere pentru condiiile de
continuare are ca efect o important reducere a numrului de calcule.
Metoda backtracking poate fi reprezentat uor, pe un arbore construit astfel:
- nivelul 1 conine rdcina;
- din orice vrf de pe nivelul k pleac sk muchii spre nivelul k+1 etichetai cu cele sk muchii ale lui Sk.
Nivelul n+1 va conine s1 s2 ... sn vrfuri. Pentru fiecare vrf de pe nivelul n+1, etichetele
muchiilor coninute pe drumul ce leag rdcina de acest vrf reprezint o soluie posibil.
Exemplu - S considerm problema submulimilor de sum dat care const n urmtoarele: Fie A =
(a1, a2, ..., an) cu ai > 0, " i. Fie MR+. Se caut toate submulimile B ale lui A pentru care suma
elementelor este M.
Pentru a putea realiza problema prin metoda backtracking vom reprezenta soluia sub forma x = (x1,
..., xn) unde xi = 1 dac aiB i xi = 0 n caz contrar. Sa ne situm n ipoteza ca n=4. Arborele ataat
metodei backtracking este urmtorul:


Ctigul obinut prin introducerea condiiilor de
continuare const n faptul c, dac ntr-un vrf ele
nu mai sunt verificate, se va renuna la parcurgerea
subarborelui care are ca rdcin acest vrf.
Acest exemplu permite prezentarea unei variante a
metodei backtracking. ntr-adevr, s considerm
drept soluie posibil o valoare k n mpreun cu k-
uplul (x1, ..., xk) unde pentru i {1, ..., k}, xi
reprezint indicele elementului pe care l introducem n B. Evident xi xj pentru ij. Pentru a nu se
repeta soluii, vom presupune x1<x2<...<xn .
Obinem astfel urmtorul arbore n care fiecare vrf corespunde unei soluii posibile.
Diferitele variante ale metodei
backtracking nu schimb esena ei care
const n faptul c este reprezentabil pe
un arbore care este parcurs "cobornd" n
arbore numai dac exist anse de a
ajunge la o soluie rezultat.
n continuare, problemele care vor fi
prezentate vor urma o schema general i
anume:
- se va testa dac am obinut o soluie, situaie n care acesta se va reine;
- dac nu am obinut soluie se ncearc plasarea unui nou element n vectorul soluie cu respectarea
condiiilor de continuare;
- dac nu se reuete 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.
Faptul 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 backtracking. Acest lucru permite o scriere mult mai scurt i mai
simpl a algoritmilor i apoi a programelor care i implementeaz. Astfel, general, un algoritm
backtracking poate fi prezentat astfel:
Subalgoritm back (k)
pentru fiecare valoare i din multimea Sk execut
xki
dac X respect condiiile interne atunci
dac X este solutie atunci
afiseaz X
altfel
apeleaz back(k+1)
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 pstrndu-se.
Exercitiu
Partiiile unui numr natural. Fie n>0, natural. S se scrie un program care s afieze toate partiiile
unui numr natural n.
Numim partiie a unui numr natural nenul n o mulime de numere naturale nenule {p1, p2, , pk}
care ndeplinesc condiia p1+p2+ +pk = n.
Ex: pt n = 4 programul va afia:
4 = 1+1+1+1
4 = 1+1+2
4 = 1+3
4 = 2+2
4 = 4
Observaii: - lungimea vectorului soluie cel mult n;
exist posibilitatea ca soluiile s se repete;
condiia de final este ndeplinit atunci cnd 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 cnd
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 mrete cu elementul ce se plaseaz n vectorul soluie. Apelul procedurii back din programul
principal va fi back(1, 0).
Exist i posibilitatea de a apela procedura back din programul principal back(1, n) i valoarea celui
de al doilea parametru se decrementeaz cu elementul ce se plaseaz n vectorul sol, iar o soluie
avem cnd acest parametru este zero. Indiferent care modalitate este aleas acest al doilea
parametru ne permite s optimizm puin programul n sensul c putem considera nite condiii de
continuare mai strnse.
#include<iostream.h>
int n, ns,sol[20];
void afis(int l)
{ int i;
ns++;
cout<<"Solutia nr. "<< ns<<" : ";
for(i=1;i<=l;i++) cout<<sol[i]<<" ";
cout<<endl;
}
void back(int i, int sp)
{ int j;
if (sp==n) afis(i-1);
else for(j=1;j<=n-sp;j++)
if (j>=sol[i-1])
{
sol[i]=j;
back(i+1, sp+j);
}
}
void main()
{
cin>>n;
ns=0;
back(1,0);
cout<<ns<<" solutii";
}

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