Sunteți pe pagina 1din 150

Examen scris

242, 244 - Miercuri 14.01.2015 la curs

241, 243 Joi 15.01.2014 la seminar


241 : 8-10
243 : 10-12

Laborator 241, 242

Marti 13.01.2015

Miercuri 07.01.2014

Miercuri 14.01.2014 de la ora 12 -restana

Sunt utilizai n probleme de optim, pentru care


spaiul de cutare a soluiilor posibile este mare

nu se cunosc algoritmi exaci mai rapizi

Furnizeaz o soluie aproximativ.

Denumirea lor se datoreaz prelurii unor


mecanisme din biologie: motenirea genetic i
evoluia natural pentru populaii de indivizi.

t =0

considerm o populaie iniial P(0) - multiset al lui D

ct timp nu este ndeplinit condiia de terminare


construim o populaie nou P(t+1) din P(t) astfel
selecie

populaie intermediar P'(t)

aplicm operatorul de ncruciare pentru indivizii din


P'(t)
o nou populaie intermediar P''(t)
aplicm operatorul de mutaie

t= t+1

populaia P(t+1)

numr maxim de iteraii

diversitatea populaiei

stabilizarea performanei maxime

Date de intrare + parametri de control

intervalul [a, b]

precizia p

dimensiunea populaiei n

numrul de generaii

probabilitatea de ncruciare pc

probabilitatea de mutaie pm

Problema rucsacului
TSP (Travelling salesman problem) ciclul
hamiltonian minim

Probleme de trafic, rutare, proiectare

Criptare, code-breaking

Teoria jocurilor

Clustering

etc

Schema = tipar care surprinde similariti dintre


cromozomi
Formal = cuvnt de lungime l peste {0,1,*}
* = dont care symbol
1*01*00*

Ordinul schemei H o(H) = numrul de poziii fixe din


schem particularitatea schemei

Lungimea schemei H (H) = distana de la prima la


ultima poziie fix ct de compact este informaia

Ordinul schemei H o(H) = numrul de poziii fixe din


schem particularitatea schemei

Lungimea schemei H (H) = distana de la prima la


ultima poziie fix ct de compact este informaia
m(H,t) = numrul de exemplare ale schemei H n P(t)
f(H,t) = fitness pentru schema H = media funciei de
fitness pentru indivizi din P(t)

Teorema schemei: Algoritmul genetic bazat pe


selecie proporional, ncruciare cu un punct de
tietur i mutaie rar ncurajeaz nmulirea
schemelor mai bine adaptate dect media, de

lungime redus i de ordin mic:

f (H , t) n
(H )

m( H , t 1) m( H , t )
pm o( H )
1 pc
F (t )
l 1

Teorema schemei:
f (H , t) n
(H )

m( H , t 1) m( H , t )
1 pc
pm o( H )
F (t )
l 1

(
Probabilitatea de distrugere a schemei dup ncruciare

O mutaie poate distruge o schem dac modific o poziie fix

Teorema schemei:
f (H , t) n
(H )

m( H , t 1) m( H , t )
1 pc
pm o( H )
F (t )
l 1

Ipoteza blocurilor constituente: Un algoritm genetic caut


soluia suboptimal prin juxtapunerea schemelor scurte,
de ordin mic i performan mare, numite building blocks

(blocuri constituente/constructive)

Michalewicz, Zbigniew (1999),


Genetic Algorithms + Data Structures = Evolution Programs,

Springer-Verlag.

n timpul rezolvrii unei probleme, putem


ajunge la un moment dat n situaia de a avea
de ales ntre mai multe variante de continuare.

n timpul rezolvrii unei probleme, putem


ajunge la un moment dat n situaia de a avea
de ales ntre mai multe variante de continuare.
se alege aleator una dintre variante

n timpul rezolvrii unei probleme, putem


ajunge la un moment dat n situaia de a avea
de ales ntre mai multe variante de continuare.
se alege aleator una dintre variante
rand (a,b)
rand([a, b])

n timpul rezolvrii unei probleme, putem


ajunge la un moment dat n situaia de a avea
de ales ntre mai multe variante de continuare.
se alege aleator una dintre variante
la executri diferite ale unui algoritm probabilist,
rezultatele sunt n general diferite.

Categorii

Monte Carlo

Las Vegas

numerici

Furnizeaz totdeauna un rezultat, care ns nu


este neaprat corect

Probabilitatea ca rezultatul s fie corect crete


pe msur ce timpul disponibil crete

Se consider un vector cu n elemente distincte. S


se determine un element al vectorului care s fie
mai mare sau egal cu mediana a celor n numere
din vector

n este foarte mare


timpul avut la dispoziie este mic

Repet fr a depi timpul disponibil:

- alegem aleator un element al vectorului


- pstrm ntr-o variabil v cel mai mare dintre
elementele alese

Care este probabilitatea ca un element ales s fie


mai mic dect mediana?
Care este probabilitatea ca toate cele k elemente
alese (n timpul de rulare avut la dispoziie) s fie
mai mici dect mediana?

Probabilitatea ca valoarea s fie greit


este

**

Probabilitatea ca valoarea s fie corect


este

1 - 1/2k
Pentru k=20, aceast probabilitate este
mai mare dect 0,999999.

Nu furnizeaz totdeauna un rezultat, dar dac


furnizeaz un rezultat atunci acesta este corect

Nu furnizeaz totdeauna un rezultat, dar dac


furnizeaz un rezultat atunci acesta este corect
Probabilitatea ca algoritmul s se termine crete
pe msur ce timpul disponibil crete

Se dau n texte (n foarte mare) cu urmtoarele


proprieti:
exist un unic text t0 care apare de cel puin
10% ori;
celelalte texte sunt distincte.

Se cere determinarea textului t0.

repeat
i random(1..n); j random(1..n);
if ij and ti=tj
write ti; stop
until false

Probabilitatea algoritmul s se termine:


probabilitatea ca ti = t0

probabilitatea ca tj = t0
probabilitatea ca ti = tj = t0 este
1/10 * 1/10 = 1/100

Probabilitatea algoritmul s se termine:


probabilitatea ca ti = t0

1/10

probabilitatea ca tj = t0

1/10

probabilitatea ca ti = tj = t0 este
1/10 * 1/10 = 1/100

Probabilitatea algoritmul s se termine:


probabilitatea ca ti = t0

1/10

probabilitatea ca tj = t0

1/10

probabilitatea ca ti = tj = t0 este
1/10 * 1/10 = 1/100
Teoretic sunt suficiente 100 de ncercri,
independent de valoarea lui n

Problema celor n dame


Se consider un caroiaj nn. Prin analogie cu o
tabl de ah (n=8), se dorete plasarea a n dame
pe ptrelele caroiajului, astfel nct s nu existe
dou dame una n btaia celeilalte

http://backtracking.xhost.ro/prcd.html

Reprezentarea soluiei
x = {x1, x2,, xn}, unde
xk = coloana pe care este plasat dama

de pe linia k

xk {1,2,,n}

pr

Algoritm probabilist

plasm o dam pe prima linie;

presupunnd c am plasat cte o dam pe liniile 1,...,k1, facem o list a poziiilor posibile pentru dama de pe
linia k
Dac lista este nevid, alegem aleator o poziie din
list
Altfel relum ntreg algoritmul (!nu ne ntoarcem la
linia precedent)

Dac am plasat o dam pe linia n, atunci am determinat


o soluie i oprim programul

Algoritm probabilist

plasm o dam pe prima linie;


presupunnd c am plasat cte o dam pe liniile
1,...,k-1, facem o list a poziiilor posibile pentru
dama de pe linia k
Dac lista este nevid, alegem aleator o poziie din
list
Altfel relum ntreg algoritmul (!nu ne ntoarcem la
linia precedent)

Dac am plasat o dam pe linia n, atunci am determinat


o soluie i oprim programul

Algoritm probabilist

plasm o dam pe prima linie;


presupunnd c am plasat cte o dam pe liniile
1,...,k-1, facem o list a poziiilor posibile pentru
dama de pe linia k
Dac lista este nevid, alegem aleator o poziie din
list

Algoritm probabilist

plasm o dam pe prima linie;


presupunnd c am plasat cte o dam pe liniile
1,...,k-1, facem o list a poziiilor posibile pentru
dama de pe linia k
Dac lista este nevid, alegem aleator o poziie din
list
Altfel relum ntreg algoritmul (! nu ne ntoarcem la
linia precedent)

Algoritm probabilist

plasm o dam pe prima linie;


presupunnd c am plasat cte o dam pe liniile
1,...,k-1, facem o list a poziiilor posibile pentru
dama de pe linia k
Dac lista este nevid, alegem aleator o poziie din
list
Altfel relum ntreg algoritmul (! nu ne ntoarcem la
linia precedent)

Dac am plasat o dam pe linia n, atunci am


determinat o soluie i oprim programul

Pentru a ine o eviden a coloanelor i diagonalelor


ocupate vectorii:
NV_SE[-n+1..n-1] (j - i = constant)

NE_SV[2..2n] (j + i = constant)
C[1..n]
0 1

n-1

2 3

n+1
n+2

-1

NV_SE

-n+1

NE_SV

2n

repeat
repeat
iniializm componentele celor 3 vectori C,
NV_SE, NE_SV cu valoarea true
k 1
formm un vector a cu acele poziii i{1,...,n}
cu
C[i] = NV_SE[i-k] = NE_SV[i+k] = true
i notm na lungimea vectorului obinut
if na>0 then
aleg aleator i{1,...,na}; i ai
xk i ;
NV_SE[i-k] false; NE_SV[i+k] false;
Ci false;
k k+1
until na=0 sau k=n+1
until k=n+1
write(x)

repeat
repeat
iniializm componentele celor 3 vectori C,
NV_SE, NE_SV cu valoarea true
k 1
formm un vector a cu acele poziii i{1,...,n}
cu
C[i] = NV_SE[i-k] = NE_SV[i+k] = true
i notm na lungimea vectorului obinut
if na>0 then
aleg aleator i{1,...,na}; i ai
xk i ;
NV_SE[i-k] false; NE_SV[i+k] false;
Ci false;
k k+1
until na=0 sau k=n+1
until k=n+1
write(x)

Urmresc determinarea aproximativ a unei valori


Cu ct timpul alocat executrii algoritmului este
mai mare, precizia rezultatului se mbuntete

Aproximarea lui
Aproximarea

f ( x) dx
a

f : a , b c, d

1. Acul lui Buffon


Se consider o mulime de linii paralele astfel nct
oricare dou linii vecine sunt la distan de o unitate.
Un ac de lungime o jumtate de unitate este aruncat
aleator i se numr de cte ori a intersectat vreo linie.
Probabilitatea ca acul s intersecteze o linie este 1/
Dup un numr "suficient de mare" de ncercri, de .

1. Acul lui Buffon


Se consider o mulime de linii paralele astfel nct
oricare dou linii vecine sunt la distan de o unitate.
Un ac de lungime o jumtate de unitate este aruncat
aleator i se numr de cte ori a intersectat vreo linie.
Probabilitatea ca acul s intersecteze o linie este 1/
Dup un numr "suficient de mare" de ncercri,
raportul ntre:
numrul total de ncercri
- numrul cazurilor n care acul a intersectat
vreo linie

va fi "suficient de aproape" de .

1. Acul lui Buffon

Probabilitatea ca acul s intersecteze o linie este 1/

Dup un numr "suficient de mare" de ncercri,


raportul ntre:
numrul total de ncercri

- numrul cazurilor n care acul a intersectat


vreo linie

va fi "suficient de aproape" de .

1. Acul lui Buffon

Probabilitatea ca acul s intersecteze o linie este 1/

Dup un numr "suficient de mare" de ncercri,


raportul ntre:
- numrul total de ncercri

- numrul cazurilor n care acul a intersectat


vreo linie

va fi "suficient de aproape" de .

2. Se arunc repetat cu o sgeat ntr-un panou ptrat,


cu inta un cerc nscris n ptrat.
Se presupune c sgeata nimerete totdeauna panoul.

2. Se arunc repetat cu o sgeat ntr-un panou ptrat,


cu inta un cerc nscris n ptrat.
Se presupune c sgeata nimerete totdeauna panoul.
Atunci raportul dintre:
- numrul cazurilor n care sgeata nimerete n
cercul nscris n ptrat

- numrul total de ncercri

tinde la

f ( x) dx,

f : a , b c, d

fhfghfgh

f ( x) dx,

f : a , b c, d

fhfghfgh
b

f ( x) dx,

f : a , b c, d

s 0
for i=1,n
x random([a,b]);
s s+f(x)
s s.(b-a)/n
write(s)

fhfghfgh

Complexitatea n timp a algoritmilor joac un rol


esenial.
Un algoritm este considerat "acceptabil" numai
dac timpul su de executare este polinomial

X=X1 ... Xn = spaiul soluiilor posibile


(!vectori)

:X {0,1} este o proprietate definit pe X

Cutm un vector xX cu proprietatea (x)


condiii interne pentru x

Generarea tuturor elementelor produsului


cartezian X nu este acceptabil.

Metoda backtracking ncearc micorarea


timpului de calcul.

Generarea tuturor elementelor produsului


cartezian X nu este acceptabil.
Metoda backtracking ncearc micorarea
timpului de calcul - prin evitarea generrii unor
soluii care nu satisfac condiiile interne

Vectorul x este construit progresiv, ncepnd cu


prima component.

Vectorul x este construit progresiv, ncepnd cu


prima component.

Se avanseaz cu o valoare xk dac este satisfcut


o condiie de continuare k(x1,...,xk)

Vectorul x este construit progresiv, ncepnd cu


prima component.

Se avanseaz cu o valoare xk dac este satisfcut


o condiie de continuare k(x1,...,xk)
Condiiile de continuare rezult de obicei din Ele
sunt strict necesare, ideal fiind s fie i suficiente.

Backtracking = parcurgerea limitat n adncime


a unui arbore
x1
x2

xk
Dac nu este satisfcut condiia de
continuare nu se mai parcurge subarborele

Cazuri posibile la alegerea lui xk:


x1
x2

xk

Atribuie i avanseaz
x1
x2

xk v
sunt verificate condiiile de continuare
xk+1

ncercare euat
x1
x2

xk v
nu sunt verificate condiiile
de continuare

Revenire
x1
x2

xk

nu mai exist valori pentru xk


neconsiderate

Revenire dup determinarea unei soluii


x1
x2

xk

xn
soluie

revenire dup
determinarea unei soluii

Ck = mulimea valorilor consumate din Xk

Ci, i;
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o soluie}
else
if Ck Xk
alege vXk\Ck; CkCk{v};
if k(x1,,xk-1,v)
xkv; kk+1; { atribuie i avanseaz }
else
{ ncercare euat }
else Ck; kk-1;
{ revenire }

Ck = mulimea valorilor consumate din Xk

Ci, i;
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o soluie}
else
if Ck Xk
alege vXk\Ck; CkCk{v};
if k(x1,,xk-1,v)
xkv; kk+1; { atribuie i avanseaz }
else
{ ncercare euat }
else Ck; kk-1;
{ revenire }

Ck = mulimea valorilor consumate din Xk

Ci, i;
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o soluie}
else
if Ck Xk
alege vXk\Ck; CkCk{v};
if k(x1,,xk-1,v)
xkv; kk+1; { atribuie i avanseaz }
else
{ ncercare euat }
else Ck; kk-1;
{ revenire }

Ck = mulimea valorilor consumate din Xk

Ci, i;
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o soluie}
else
if Ck Xk
alege vXk\Ck; CkCk{v};
if k(x1,,xk-1,v)
xkv; kk+1; { atribuie i avanseaz }
else
{ ncercare euat }
else Ck; kk-1;
{ revenire }

Ck = mulimea valorilor consumate din Xk

Ci, i;
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o soluie}
else
if Ck Xk
alege vXk\Ck; CkCk{v};
if k(x1,,xk-1,v)
xkv; kk+1; { atribuie i avanseaz }
else
{ ncercare euat }
else Ck; kk-1;
{ revenire }

Ck = mulimea valorilor consumate din Xk

Ci, i;
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o soluie}
else
if Ck Xk
alege vXk\Ck; CkCk{v};
if k(x1,,xk-1,v)
xkv; kk+1; { atribuie i avanseaz }
else
{ ncercare euat }
else Ck; kk-1;
{ revenire }

Dac Xi= {pi, pi+1,,ui} algoritmul devine:


xipi-1, i=1,...,n
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o sol.}
else
if xk<uk
xkxk+1;
if k(x1,,xk)
kk+1;
{ atribuie i avanseaz }
else
{ ncercare euat }
else xkpk-1; kk-1;
{ revenire }

Dac Xi= {pi, pi+1,,ui} algoritmul devine:


xipi-1, i=1,...,n
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o sol.}
else
if xk<uk
xkxk+1;
if k(x1,,xk)
kk+1;
{ atribuie i avanseaz }
else
{ ncercare euat }
else xkpk-1; kk-1;
{ revenire }

Dac Xi= {pi, pi+1,,ui} algoritmul devine:


xipi-1, i=1,...,n
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o sol.}
else
if xk<uk
xkxk+1;
if k(x1,,xk)
kk+1;
{ atribuie i avanseaz }
else
{ ncercare euat }
else xkpk-1; kk-1;
{ revenire }

Dac Xi= {pi, pi+1,,ui} algoritmul devine:


xipi-1, i=1,...,n
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o sol.}
else
if xk<uk
xkxk+1;
if k(x1,,xk)
kk+1;
{ atribuie i avanseaz }
else
{ ncercare euat }
else xkpk-1; kk-1;
{ revenire }

Dac Xi= {pi, pi+1,,ui} algoritmul devine:


xipi-1, i=1,...,n
k1;
while k>0
if k=n+1
retsol(x); kk-1;{revenire dup o sol.}
else
if xk<uk
xkxk+1;
if k(x1,,xk)
kk+1;
{ atribuie i avanseaz }
else
{ ncercare euat }
else xkpk-1; kk-1;
{ revenire }

Xi= {pi, pi+1,,ui}


Apelul iniial este: back(1)
procedure back(k)
if k=n+1
retsol(x)
else
for (i=pk; i<=uk; i++) //valori posibile
xki;
if k(x1,,xk)
back(k+1);
//revenire din recursivitate
end.

Xi= {pi, pi+1,,ui}


Apelul iniial este: back(1)
procedure back(k)
if k=n+1
retsol(x)
else
for (i=pk; i<=uk; i++) {valori posibile}
xki;
if k(x1,,xk)
back(k+1);
//revenire din recursivitate
end.

Xi= {pi, pi+1,,ui}


Apelul iniial este: back(1)
procedure back(k)
if k=n+1
retsol(x)
else
for (i=pk; i<=uk; i++) {valori posibile}
xki;
if k(x1,,xk)
back(k+1);
{revenire din recursivitate}
end.

Permutri, combinri, aranjamente

Colorarea hrilor

Problema celor n dame

iruri corecte de paranteze

Problema ciclului hamiltonian

Pentru a testa condiiile de continuare k(x1,,xk)


vom folosi funcia cont(k)

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk {1,2,,n} (pk = 1, uk = n).

Condiii interne (finale)


xi xj pentru orice i j.

Condiii de continuare (!!pentru xk)


xi xk pentru orice i{1,2,,k-1}

1
1
1
1
1
1
1
1
1
1
1
1

1
2
2
2
2
2
3
3
3
3
3

1
2
3
3 soluie

1
2
2 soluie
3

2
2 1
2 1
2 1
2 1
2 1
etc

1
2
3
3 soluie

Se consider o hart cu n ri.

Se cere colorarea ei folosind cel mult 4 culori,


astfel nct oricare dou ri vecine s fie colorate
diferit

Reprezentareansoluiei
x = {x1, x2,, xn}, unde

xk = culoarea cu care este colorat ara k


xk {1,2,3,4} (pk = 1, uk = 4).

Condiii interne (finale)


xi xj pentru orice dou ri vecine i i j.

Condiii de continuare (!!pentru xk)


xi xk pentru orice ar i{1,2,,k-1}

vecin cu ara k

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk = culoarea cu care este colorat ara k
xk {1,2,3,4} (pk = 1, uk = 4).

Condiii interne (finale)


xi xj pentru orice dou ri vecine i i j.

Condiii de continuare (!!pentru xk)


xi xk pentru orice ar i{1,2,,k-1}

vecin cu ara k

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk = culoarea cu care este colorat ara k
xk {1,2,3,4} (pk = 1, uk = 4).

Condiii interne (finale)


xi xj pentru orice dou ri vecine i i j.

Condiii de continuare (!!pentru xk)


xi xk pentru orice ar i{1,2,,k-1}

vecin cu ara k

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk = culoarea cu care este colorat ara k
xk {1,2,3,4} (pk = 1, uk = 4).

Condiii interne (finale)


xi xj pentru orice dou ri vecine i i j.

Condiii de continuare (!!pentru xk)


xi xk pentru orice ar i{1,2,,k-1}

vecin cu ara k

boolean cont(int k){


for(int i=1;i<k;i++)
if(a[i][k]==1 && x[i]==x[k])
return false;
return true;
}
void backrec(int k){
if(k==n+1)
retsol(x);
else
for(int i=1;i<=4;i++){
x[k]=i;
if (cont(k))
backrec(k+1);
}
}

boolean cont(int k){


for(int i=1;i<k;i++)
if(a[i][k]==1 && x[i]==x[k])
return false;
return true;
}
void backrec(int k){
if(k==n+1)
retsol(x);
else
for(int i=1;i<=4;i++){
x[k]=i;
if (cont(k))
backrec(k+1);
}
}

boolean cont(int k){


for(int i=1;i<k;i++)
if(a[i][k]==1 && x[i]==x[k])
return false;
return true;
}
void backrec(int k){
if(k==n+1)
retsol(x);
else
for(int i=1;i<=4;i++){
x[k]=i;
if (cont(k))
backrec(k+1);
}
}

boolean cont(int k){


for(int i=1;i<k;i++)
if(a[i][k]==1 && x[i]==x[k])
return false;
return true;
}
void backrec(int k){
if(k==n+1)
retsol(x);
else
for(int i=1;i<=4;i++){
x[k]=i;
//atribuie
if (cont(k))
//avanseaza
backrec(k+1);
}
}

void back(){
int k=1;
x=new int[n+1];
for(int i=1;i<=n;i++) x[i]=0;
while(k>0){
if(k==n+1){retsol(x); k--;} //revenire dupa sol
else{
if(x[k]<4){

x[k]++;

//atribuie

if (cont(k)) k++;

//si avanseaza

}
else{ x[k]=0; k--; }

}
}
}

//revenire

void back(){
int k=1;
x=new int[n+1];
for(int i=1;i<=n;i++) x[i]=0;
while(k>0){
if(k==n+1){retsol(x); k--;} //revenire dupa sol
else{
if(x[k]<4){

x[k]++;

//atribuie

if (cont(k)) k++;

//si avanseaza

}
else{ x[k]=0; k--; }

}
}
}

//revenire

void back(){
int k=1;
x=new int[n+1];
for(int i=1;i<=n;i++) x[i]=0;
while(k>0){
if(k==n+1){retsol(x); k--;} //revenire dupa sol
else{
if(x[k]<4){

x[k]++;

//atribuie

if (cont(k)) k++;

//si avanseaza

}
else{ x[k]=0; k--; }

}
}
}

//revenire

Se consider un caroiaj nn.

Prin analogie cu o tabl de ah (n=8), se dorete


plasarea a n dame pe ptrelele caroiajului, astfel

nct s nu existe dou dame una n btaia


celeilalte

Reprezentareansoluiei
x = {x1, x2,, xn}, unde

xk = coloana pe care este plasat dama

de pe linia k

xk {1,2,,n}

(pk = 1, uk = n).

Condiii interne (finale)


pentru orice ij: xixj i |xi-xj||j-i|

Condiii de continuare
pentru orice i<k: xixk i |xi-xk|k-i

Reprezentareansoluiei
x = {x1, x2,, xn}, unde

xk = coloana pe care este plasat dama

de pe linia k

xk {1,2,,n}

(pk = 1, uk = n).

Condiii interne (finale)


pentru orice ij: xixj i |xi-xj||j-i|

Condiii de continuare
pentru orice i<k: xixk i |xi-xk|k-i

Reprezentareansoluiei
x = {x1, x2,, xn}, unde

xk = coloana pe care este plasat dama

de pe linia k

xk {1,2,,n}

(pk = 1, uk = n).

Condiii interne (finale)


pentru orice ij: xixj i |xi-xj||j-i|

Condiii de continuare
pentru orice i<k: xixk i |xi-xk|k-i

Reprezentareansoluiei
x = {x1, x2,, xn}, unde

xk = coloana pe care este plasat dama

de pe linia k

xk {1,2,,n}

(pk = 1, uk = n).

Condiii interne (finale)


pentru orice ij: xixj i |xi-xj||j-i|

Condiii de continuare
pentru orice i<k: xixk i |xi-xk|k-i

boolean cont(int k){


for(int i=1;i<k;i++)
if((x[i]==x[k]) || (Math.abs(x[k]-x[i])==k-i))
return false;
return true;
}
void retsol(int[] x){
for(int i=1;i<=n;i++)
System.out.print("("+i+","+x[i]+") ");
System.out.println();
}

boolean cont(int k){


for(int i=1;i<k;i++)
if((x[i]==x[k]) || (Math.abs(x[k]-x[i])==k-i))
return false;
return true;
}
void retsol(int[] x){
for(int i=1;i<=n;i++)
System.out.print("("+i+","+x[i]+") ");
System.out.println();
}

void backrec(int k){


if(k==n+1)
retsol(x);
else
for(int i=1;i<=n ;i++){ //Xk
x[k]=i;
if (cont(k))
backrec(k+1);
}
}

void back(){
int k=1;
x=new int[n+1];

for(int i=1;i<=n;i++) x[i]=0;


while(k>0){
if(k==n+1){ retsol(x); k--; }//revenire dupa sol

else{
if(x[k]<n){
x[k]++;

//atribuie

if (cont(k)) k++;

//si avanseaza

}
else{ x[k]=0;
}
}
}

k--; }

//revenire

void back(){
int k=1;
x=new int[n+1];

for(int i=1;i<=n;i++) x[i]=0;


while(k>0){
if(k==n+1){ retsol(x); k--; }//revenire dupa sol

else{
if(x[k]<n){
x[k]++;

//atribuie

if (cont(k)) k++;

//si avanseaza

}
else{ x[k]=0;
}
}
}

k--; }

//revenire

S se genereze toate irurile de n paranteze


ce se nchid corect (n par)

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk {'(', ')'}

Condiii interne (finale)


Notm dif = nr( - nr)
dif = 0
dif 0 pentru orice secven {x1, x2,, xk}

Condiii de continuare
dif 0

-> doar necesar

dif n-k

-> i suficient

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk {'(', ')'}

Condiii interne (finale)


Notm dif = nr( - nr)
dif = 0
dif 0 pentru orice secven {x1, x2,, xk}

Condiii de continuare
dif 0

-> doar necesar

dif n-k

-> i suficient

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk {'(', ')'}

Condiii interne (finale)


Notm dif = nr( - nr)
dif = 0
dif 0 pentru orice secven {x1, x2,, xk}

Condiii de continuare
dif 0

-> doar necesar

dif n-k

-> i suficient

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk {'(', ')'}

Condiii interne (finale)


Notm dif = nr( - nr)
dif = 0
dif 0 pentru orice secven {x1, x2,, xk}

Condiii de continuare
dif 0

-> doar necesar

Reprezentareansoluiei
x = {x1, x2,, xn}, unde
xk {'(', ')'}

Condiii interne (finale)


Notm dif = nr( - nr)
dif = 0
dif 0 pentru orice secven {x1, x2,, xk}

Condiii de continuare
dif 0

-> doar necesar

dif n-k

-> i suficient

void back(){
dif=0;
back(1);
}
void back(int k){
if(k==n+1)
retsol(x);
else{
x[k]='(';
dif++;
if (dif <= n-k)
back(k+1);
dif--;
x[k]=')';
dif--;
if (dif >= 0)
back(k+1);
dif++;
}
}

void back(){
dif=0;
back(1);
}
void back(int k){
if(k==n+1)
retsol(x);
else{
x[k]='(';
dif++;
if (dif <= n-k)
back(k+1);
dif--;
x[k]=')';
dif--;
if (dif >= 0)
back(k+1);
dif++;
}
}

void back(){
dif=0;
back(1);
}
void back(int k){
if(k==n+1)
retsol(x);
else{
x[k]='(';
dif++;
if (dif <= n-k)
back(k+1);
dif--;
x[k]=')';
dif--;
if (dif >= 0)
back(k+1);
dif++;
}
}

Variantele cele mai uzuale ntlnite n


aplicarea metodei backtracking sunt
urmtoarele:

soluia poate avea un numr variabil de


componente
i/sau
dintre ele alegem una care optimizeaz o
funcie dat

Exemplu: Dat un numr natural n, s se


genereze toate partiiile lui n ca sum de
numere pozitive

Partiie a lui n = {x1, x2,, xk} cu


x1+ x2 ++ xk = n

Reprezentareansoluiei
x = {x1, x2,, xk}, unde
xi {1,,n}

Condiii interne (finale)


x1 + x2 +... +

xk = n

Pentru unicitate: x1 x2 ...

Condiii de continuare
xk-1 xk
x1 + x2 +... +

xk {xk-1,,n}
xk n

xk

Reprezentareansoluiei
x = {x1, x2,, xk}, unde
xi {1,,n}

Condiii interne (finale)


x1 + x2 +... +

xk = n

Pentru unicitate: x1 x2 ...

Condiii de continuare
xk-1 xk
x1 + x2 +... +

xk {xk-1,,n}
xk n

xk

Reprezentareansoluiei
x = {x1, x2,, xk}, unde
xi {1,,n}

Condiii interne (finale)


x1 + x2 +... +

xk = n

Pentru unicitate: x1 x2 ...

xk

Condiii de continuare
xk-1 xk
x1 + x2 +... +

xk {xk-1,,n} = Xk
xk n

void retsol(int[] x,int k){


for(int i=1;i<=k;i++)
System.out.print(x[i]+" ");
System.out.println();
}
void backrec(){
x=new int[n+1];
x[0]=1;
s=0;
backrec(1);
}

void backrec(int k){


for(int i=x[k-1];i<=n;i++){
x[k]=i;
if(s+x[k]<=n)////verif.cond.de cont
if(s+x[k]==n){//este solutie
retsol(x,k);
return;
}
else{
s+=x[k];
backrec(k+1);
s-=x[k];
}
// else return;
}
}

void backrec(int k){


for(int i=x[k-1];i<=n;i++){
x[k]=i;
if(s+x[k]<=n)////verif.cond.de cont
if(s+x[k]==n){//este solutie
retsol(x,k);
return;
}
else{
s+=x[k];
backrec(k+1);
s-=x[k];
}
// else return;
}
}

void backrec(int k){


for(int i=x[k-1];i<=n;i++){
x[k]=i;
if(s+x[k]<=n)////verif.cond.de cont
if(s+x[k]==n){//este solutie
retsol(x,k);
return;
}
else{
s+=x[k];
backrec(k+1);
s-=x[k];
}
// else return;
}
}

void back(){
int k=1,s=0; int x[]=new int[n+1];
x[1]=0;
while(k>=1){
if(x[k]<n){
x[k]++; s++;
if(s<=n){//cont verif. conditiilor de cont
if(s==n){//dc este sol
retsol(x,k);
s=s-x[k]; k--;//revenire dupa sol
}
else{ k++; x[k]=x[k-1]-1; s+=x[k]; //avansare
}
}
else{ s=s-x[k]; k--; //revenire
}
}
}
}

void back(){
int k=1,s=0; int x[]=new int[n+1];
x[1]=0;
while(k>=1){
if(x[k]<n){
x[k]++; s++;
if(s<=n){//cont verif. conditiilor de cont
if(s==n){//dc este sol
retsol(x,k);
s=s-x[k]; k--;//revenire dupa sol
}
else{ k++; x[k]=x[k-1]-1; s+=x[k]; //avansare
}
}
else{ s=s-x[k]; k--; //revenire
}
}
}
}

void back(){
int k=1,s=0; int x[]=new int[n+1];
x[1]=0;
while(k>=1){
if(x[k]<n){
x[k]++; s++;
if(s<=n){//cont verif. conditiilor de cont
if(s==n){//dc este sol
retsol(x,k);
s=s-x[k]; k--;//revenire dupa sol
}
else{ k++; x[k]=x[k-1]-1; s+=x[k]; //avansare
}
}
else{ s=s-x[k]; k--; //revenire
}
}
}
}

void back(){
int k=1,s=0; int x[]=new int[n+1];
x[1]=0;
while(k>=1){
if(x[k]<n){
x[k]++; s++;
if(s<=n){//cont verif. conditiilor de cont
if(s==n){//dc este sol
retsol(x,k);
s=s-x[k]; k--;//revenire dupa sol
}
else{ k++; x[k]=x[k-1]-1; s+=x[k]; //avansare
}
}
else{ s=s-x[k]; k--; //revenire
}
}
}
}

Se consider un caroiaj (matrice) A cu m linii i n


coloane. Poziiile pot fi:
libere: aij=0;
ocupate: aij=1.
Se mai d o poziie (i0,j0). Se caut toate
drumurile care ies n afara matricei, trecnd
numai prin poziii libere.

Micrile posibile sunt date printr-o matrice


depl cu dou linii i ndepl coloane. De
exemplu, dac deplasrile permise sunt cele
ctre poziiile vecine situate la E, N, S:
1 0 1 0

0 1 0 1

Micrile posibile sunt date printr-o matrice


depl cu dou linii i ndepl coloane. De
exemplu, dac deplasrile permise sunt cele
ctre poziiile vecine situate la E, N, S:
1 0 1 0

0 1 0 1

Bordm matricea cu 2 pentru a nu studia separat


ieirea din matrice.

Reprezentareansoluiei
x = {x1, x2,, xk}, unde
xi = a i-a celul din drum

Condiii interne (finale)


xk = celul din afara matricei (marcat cu 2)

Condiii de continuare
xk celul liber (cu 0) prin care nu am mai trecut

Reprezentareansoluiei
x = {x1, x2,, xk}, unde
xi = a i-a celul din drum

Condiii interne (finale)


xk = celul din afara matricei (marcat cu 2)

Condiii de continuare
xk celul liber (cu 0) prin care nu am mai trecut

Reprezentareansoluiei
x = {x1, x2,, xk}, unde
xi = a i-a celul din drum

Condiii interne (finale)


xk = celul din afara matricei (marcat cu 2)

Condiii de continuare
xk celul liber (cu 0) prin care nu am mai trecut

dac poziia este liber i putem continua,


setm aij=-1 (a fost atins), continum
repunem aij=0 la ntoarcere (din recursivitate).

void back(i, j){


for (t = 1; t<=ndepl; t++){
ii = i + depl[1][t]
jj = j + depl[2][t];
if (a[ii][jj] == 1)
else
if (a[ii][jj] == 2)
retsol(x,k);
else
if (a[ii][jj] == 0){
k = k+1;
//creste
xk (ii, jj);
a[i][j] = -1; //marcam
back(ii, jj);
a[i][j] = 0; //demarcam
k = k1 ;
//scade
}
}
}

void back(i, j){


for (t = 1; t<=ndepl; t++){
ii = i + depl[1][t]
jj = j + depl[2][t];
if (a[ii][jj] == 1)
else
if (a[ii][jj] == 2)
retsol(x,k);
else
if (a[ii][jj] == 0){
k = k+1;
//creste
xk (ii, jj);
a[i][j] = -1; //marcam
back(ii, jj);
a[i][j] = 0; //demarcam
k = k1 ;
//scade
}
}
}

void back(i, j){


for (t = 1; t<=ndepl; t++){
ii = i + depl[1][t]
jj = j + depl[2][t];
if (a[ii][jj] == 1)
else
if (a[ii][jj] == 2)
retsol(x,k);
else
if (a[ii][jj] == 0){
k = k+1;
//creste
xk (ii, jj);
a[i][j] = -1; //marcam
back(ii, jj);
a[i][j] = 0; //demarcam
k = k1 ;
//scade
}
}
}

void back(i, j){


for (t = 1; t<=ndepl; t++){
ii = i + depl[1][t]
jj = j + depl[2][t];
if (a[ii][jj] == 1)
else
if (a[ii][jj] == 2)
retsol(x,k);
else
if (a[ii][jj] == 0){
k = k+1;
//creste
xk (ii, jj);
a[i][j] = -1; //marcam
back(ii, jj);
a[i][j] = 0; //demarcam
k = k1 ;
//scade
}
}
}

Apel:
x1 (i0, j0);
k = 1;
back(i0, j0)

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