Sunteți pe pagina 1din 13

TEHNICI DE CĂUTARE ÎN SPAŢIUL DE STĂRI

Spaţiul de stări

Fig.2. Stare finală


Fig.1. Stare iniţială Fig.3. Stare legală

Spaţiul de căutare a

Stare curentă
c
Operatori b

Stări noi d e f g

h i j k
Fig.4. Elementele spaţiului de căutare

Fig.5. Un spaţiu de căutare

NivelStăriTotal
stari011123247381541631

Fig.6. Spaţiu de căutare cu operatori binari

1
n 2n 2(n+1)-1
2 4 7
4 16 31
6 64 127
10 1024 2047
15 32768 65536
20 1048576 2097151
30 1073741824 2147483647

Fig.7. Numărul de stări într-un spaţiu cu operatori


binari

Fig.9. Importanţa reprezentării


Fig.8. Spaţiul de stări pentru Turnul Hanoi

Căutarea “oarbă”
Căutarea în adâncime
a

c
b

d e f g

h i j k

Fig.11. Căutarea în adâncime

Căutarea în adâncime în arbore


drum_1(N,[N]):-
stare_finala(N). /*Soluţia=[N], dacă N este nod final*/
drum_1(N,[N|S]):- /*în caz contrar Soluţia=[N|S]*/

2
succesor(N,N1), /*dacă N1 e un nod succesor al lui N şi*/
drum_1(N1,S). /*S e soluţia din N1 spre nodul final*/

De exemplu, fiind dat arborele din fig.11, reprezentat de faptele


stare_finala(j).
stare_finala(f).

succesor(a,b).
succesor(b,d).
succesor(d,h).
succesor(b,e).
succesor(e,i).
succesor(e,j).
succesor(a,c).
succesor(c,f).
succesor(c,g).
succesor(f,k).

atunci la întrebarea cu starea iniţială în calitate de primul argument se obţine următoarea soluţie
?-drum_1(a,S)
S=[a,b,e,j]
S=[a,c,f]

Căutarea în adâncime într-un graf

Dacă, însă, spaţiul de stări este un graf ciclic cum ar fi, spre exemplu, graful obţinut prin
adăugarea la precedentul a arcului
succesor(h,d).

atunci pentru a evita buclele care, de exemplu, apar pentru a răspunde la aceeaşi întrebare, se cere
introducerea unui control. Controlul poate fi făcut prin adăugarea unui al treilea argument ce ar
reprezenta lista nodurilor deja explorate cu care se va confrunta orice nod nou înainte de a fi introdus
în listă.
drum_2(N,[N|C],C):-stare_finala(N).
drum_2(N,S,C):-
succesor(N,N1),
not(apartine(N1,C)),
drum_2(N1,S,[N|C]).

apartine(Elem,[Elem|_]).
apartine(Elem,[_|Rest]):-apartine(Elem,Rest).

Utilizând faptele precedente şi cel adăugat se obţine următorul răspuns


?-drum_2(a,S,[])
S=[j,e,b,a]
S=[f,c,a]

3
Căutarea limitată în adâncime
drum_3(N,[N],_):-stare_finala(N).
drum_3(N,[N|S],Max):-
Max>0,
succesor(N,N1),
Max1 is Max-1,
drum_3(N1,S,Max1).

Predicatul drum_3/3 este apelat cu argumentul trei instanţiat de valoarea adâncimii maxime.
Adresându-ne din nou la graful nostru, obţinem
?-drum_3(a,S,2)
S=[a,c,f]

?-drum_3(a,S,3)
S=[a,b,e,j]
S=[a,c,f]

Căutarea limitată în adâncime cu controlul bucleor

Predicatul de mai jos combină controlul buclelor şi controlul adâncimii de căutare


drum_4(N,[N|C],C,_):-stare_finala(N).
drum_4(N,S,C,Max):-
Max>0,
succesor(N,N1),
not(apartine(N1,C)),
Max1 is Max-1,
drum_4(N1,S,[N|C],Max1).

?-drum_4(a,S,[],2)
S=[f,c,a]

?-drum_4(a,S,[],3)
S=[j,e,b,a]
S=[f,c,a]

Lumea blocurilor

C A
A  B
B C
Fig.12. Lumea blocurilor

Fig.13. Spaţiul de stări Lumea blocurilor

4
Spaţiul de stări Lumea blocurilor

stare_finala(l).

succesor(a,c). succesor(c,a).
succesor(c,e). succesor(e,c).
succesor(b,d). succesor(d,b).
succesor(d,e). succesor(e,d).
succesor(c,d). succesor(d,c).
succesor(e,h). succesor(h,e).
succesor(h,i). succesor(i,h).
succesor(e,g). succesor(g,e).
succesor(g,f). succesor(f,g).
succesor(g,j). succesor(j,g).
succesor(h.k). succesor(k,h).
succesor(e,j). succesor(j,e).
succesor(e,k). succesor(k,e).
succesor(j,l). succesor(l,j).
succesor(k,m). succesor(m,k).

Utilizând procedura de căutare în adâncime cu controlul buclelor, obţinem drumurile ce ar


constitui planurile de reordonare.
?-drum_2(a,S,[])
S=[l,j,g,e,c,a]
S=[l,j,e,c,a]
S=[l,j,g,e,d,c,a]
S=[l,j,e,d,c,a]

Mişcările calului de şah


stare_finala(8).

succesor(1,6).
succesor(1,8).
succesor(2,7).
succesor(2,9).
succesor(3,4).
succesor(3,8).
succesor(4,3).
succesor(4,9).
succesor(6,7).
succesor(6,1).
succesor(7,6).
succesor(7,2).
succesor(8,3).
succesor(8,1).
succesor(9,4).
succesor(9,2).

?-drum_2(1,S,[])
S=[8,3,4,9,2,7,6,1]
S=[8,1]

5
1 1234567812345678Fig.15. Un drum al
2 3 calului de şah
4 5 6

Fig.14. Tabla de şah


337
89

4a 3a

 
 
a
8 7a


 
a
6 5a

 
a
2 1a

Fig.16. Mişcările posibile ale unui


cal

stare_finala(patrat(1,5)).

succesor(patrat(R1,C1),patrat(R2,C2)):-
R1<=6,C1<=7,R2 is R1+2,C2 is C1+1.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1<=6,C1=2,R2 is R1+2,C2 is C1-1.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1>=3,C1<=7,R2 is R1-2,C2 is C1+1.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1>=3,C1>=2,R2 is R1-2,C2 is C1-1.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1<=7,C1<=6,R2 is R1+1,C2 is C1+2.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1<=7,C1>=3,R2 is R1+1,C2 is C1-2.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1>=2,C1<=6,R2 is R1-1,C2 is C1+2.
succesor(patrat(R1,C1),patrat(R2,C2)):-
R1>=2,C1>=3,R2 is R1-1,C2 is C1-2.

?-drum_2(patrat(4,2),S,[])

6
S=[patrat(1,5),patrat(3,4),patrat(1,3),patrat(3,2),
patrat(5,1),patrat(7,2),patrat(5,3),patrat(7,4),
patrat(5,5),patrat(3,6),patrat(2,8),patrat(4,7),
patrat(6,8),patrat(8,7),patrat(6,6),patrat(7,8),
patrat(5,7),patrat(7,6),patrat(8,8),patrat(6,7),
patrat(8,6),patrat(6,5),patrat(8,4),patrat(6,3),
patrat(4,2)]

Problema fermierului
VestEstFLCVFLCV

Fig.17. Soluţiile problemei fermierului

stare_finala(stare(e,e,e,e)).

%Fermierul traversează cu lupul


succesor(stare(X,X,C,V),stare(Y,Y,C,V)):-
opus(X,Y),not(periculos(stare(Y,Y,C,V))).
%Fermierul traversează cu capra
succesor(stare(X,L,X,V),stare(Y,L,Y,V)):-
opus(X,Y),not(periculos(stare(Y,L,Y,V))).
%Fermierul traversează cu varza
succesor(stare(X,L,C,X),stare(Y,L,C,Y)):-
opus(X,Y),not(periculos(stare(Y,L,C,Y))).
%Fermierul traversează singur
succesor(stare(X,L,C,V),stare(Y,L,C,V)):-
opus(X,Y),not(periculos(stare(Y,L,C,V))).

7
opus(e,v).
opus(v,e).

periculos(stare(X,Y,Y,_)):-opus(X,Y).
periculos(stare(X,_,Y,Y)):-opus(X,Y).

?-drum_2(stare(v,v,v,v),S,[])
S=[stare(e,e,e,e),stare(v,e,v,e),stare(e,e,v,e),
stare(v,e,v,v),stare(e,e,e,v),stare(v,v,e,v),
stare(e,v,e,v),stare(v,v,v,v)]
S=[stare(e,e,e,e),stare(v,e,v,e),stare(e,e,v,e),
stare(v,v,v,e),stare(e,v,e,e),stare(v,v,e,v),
stare(e,v,e,v),stare(v,v,v,v)]

Căutarea în lărgime

c
b

d e f g

h i j k

Fig.18. Căutarea în lărgime

În predicatul largime_1(Drumuri_cand,Solutie) lista Solutie este un drum ce se întinde spre


nodul final începând de la lista Drumuri_cand. Drumurile sunt reprezentate prin liste de noduri în
ordine inversă.
largime_1([[Nod|Drum]|_],[Nod|Drum]):-stare_finala(Nod).
/*dacă primul drum al listei Drumuri_cand are în calitate de cap nodul final,
atunci acest drum este soluţia, în caz contrar*/
largime_1([Drum|Drumuri],Sol):-
findall(NouDrum,alegere_urmator_nod(Drum,NouDrum),NoiDrumuri),
/*este generată lista tuturor extinderilor posibile cu un nod adăugat*/
concatenare(Drumuri,NoiDrumuri,Drumuri2),!,
/*această listă este adăugată la coada listei Drumuri_cand */
write(“lista: “,Drumuri2),nl,
largime_1(Drumuri2,Sol).
/*şi lista Drumuri_cand modificată este considerată din nou*/

alegere_urmator_nod([Nod|Drum],[Nod1,Nod|Drum]):-
succesor(Nod,Nod1),
not(apartine(Nod1,[Nod|Drum])).

8
Aici apartine/2 şi concatenare/3 sunt predicate cunoscute asupra listelor, iar findall/3 este un
predicat predefinit în unele implementări Prolog.

Adresându-i bazei de fapte ce corespunde arborelui din fig.5 întrebarea


?-largime_1([[a]],S)

predicatele write vor afişa consecutivitatea de mai jos. În această consecutivitate, la fiece nod curent
sunt găsiţi toţi succesorii adiacenţi ce extind drumul în lista Drumuri_cand. Aici “lista” este lista
Drumuri_cand modificată: se elimină drumul din capul listei şi se adaugă la coadă extinderile acestui
drum.
ista: [[b,a],[c,a]]
lista: [[c,a],[d,b,a],[e,b,a]]
lista: [[d,b,a],[e,b,a],[f,c,a],[g,c,a]]
lista: [[e,b,a],[f,c,a],[g,c,a],[h,d,b,a]]
lista: [[f,c,a],[g,c,a],[h,d,b,a],[i,e,b,a],[j,e,b,a]]
S=[f,c,a]
lista: [[g,c,a],[h,d,b,a],[i,e,b,a],[j,e,b,a],[k,f,c,a]]
lista: [[h,d,b,a],[i,e,b,a],[j,e,b,a],[k,f,c,a]]
lista: [[i,e,b,a],[j,e,b,a],[k,f,c,a]]
lista: [[j,e,b,a],[k,f,c,a]]
S=[j,e,b,a]
lista: [[k,f,c,a]]
lista: []

Altă metodă de realizare a căutării în lărgime constă în utilizează predicatele assert/1 şi


retract/1. Aici în predicatul largime_2(S,C) starea S dată la intrare este starea iniţială, iar C este
drumul obţinut la ieşire. În predicatul cautare_succesori(Nc,C,Ns), Nc este nodul curent, C este
drumul parcurs până la Nc şi Ns este nodul succesor.
largime_2(S,A):-assert(agenda(S,[S])),
repetare,
agenda(St,OS), cautare_succesori(St,OS,NS),
stare_finala(NS),agenda(NS,A),retract(agenda(NS,A)),
assert(agenda_veche(NS,A)),
write(“Agenda:”),nl,
vizualizare(agenda(X,Y)),
vizualizare(agenda_veche(X,Y)).

cautare_succesori(St,OS,NS):-
succesor(St,NS),St<>NS,
not(agenda(NS,S)),not(agenda_veche(NS,S)),
assertz(agenda(NS,[NS|OS])).
cautare_succesori(St,OS,NS):-
retract(agenda(St,OS)),
asserta(agenda_veche(St,OS)),
write(“Agenda:”),nl,
vizualizare(agenda(X,Y)),
vizualizare(agenda_veche(X,Y)),
fail.

repetare.
repetare:-agenda(_,_),repetare.

9
vizualizare(X):-X,write(X),nl,fail.
vizualizare(_).

Formulând întrebarea
?-largime_2(a,S)

asupra aceluiaşi exemplu se poate obţine prima soluţie:


Agenga:
agenda(c,[b,a])
agenda(c,[c,a])
agenda_veche(a,[a])
Agenga:
agenda(c,[c,a])
agenda(d,[d,b,a])
agenda(e,[e,b,a])
agenda_veche(b,[b,a])
agenda_veche(a,[a])
Agenga:
agenda(c,[c,a])
agenda(d,[d,b,a])
agenda(e,[e,b,a])
agenda_veche(f,[f,c,a])
agenda_veche(b,[b,a])
agenda_veche(a,[a])
S=[f,c,a]

Complexitatea căutării oarbe


Pentru a compara performanţa algoritmilor de căutare trebuie considerate patru aspecte
 memoria necesară pentru parcurgere
 timpul consumat în procesul parcurgerii
 completitudinea: strategia garantează găsirea soluţiei, dacă soluţia există
 admisibilitatea: strategia de căutare garantează găsirea soluţiei optimale (ieftine), dacă o
asemenea soluţie există

Să considerăm spaţiul necesar pentru derularea acestei strategii. Până a se trece la adâncimea
k+1 se examinează toate nodurile de la nivelul k. Adică până a parcurge nodurile de la adâncimea p
sunt memorate datele despre f p-1 noduri de la nivelul p-1. Deci dacă soluţia se află la nivelul p, atunci
spaţiul necesar pentru păstrarea nodurilor, în cel mai rău caz, este

1+f+f2+…+f p.

Cu alte cuvinte mărimea spaţiului de memorare a nodurilor este O(f p).

Să calculăm timpul mediu necesar pentru parcurgerea spaţiului de stări. Numărul de noduri
examinate până la nivelul p este

10
p 1 (f p  1)
1  f  f 2  ...  f 
(f  1)
Fiecare din nodurile nivelului p poate fi stare finală. Deci pot fi examinate 1 nod, în cel mai
bun caz şi f p noduri, în cel mai rău caz. Presupunând că nodul final poate fi repartizat uniform la
nivelul p, atunci timpul mediu necesar căutării în lărgime este

Astfel pentru f şi p mari această expresie converge spre f p/2, adică timpul consumat este O(f p).
p 1
(f p  1 ) (1  f p ) (f  f p  f  3)
 
(f - 1) 2 2(f  1)
Fie că factorul de ramificare este 10, memoria necesară pentru păstrarea unui nod este 100
octeţi, iar viteza de parcurgere este 1000 noduri/secundă. Atunci tabelul din fig.19 ilustrează necesităţile de
memorie şi timp pentru căutarea în lărgime.

Adâncime Noduri Timp Memorie


0 1 1 milisecunde 100 O
2 111 0.1 secunde 11 KO
4 11111 11 secunde 1 MO
6 106 18 minute 111 MO
8 108 31 ore 11 GO
10 1010 128 zile 1 TO
12 1012 35 ani 111 TO
14 1014 3500 ani 11111 TO

Fig.19. Memoria şi timpul consumate de căutarea în lărgime

Să analizăm căutarea în adâncime.

În ce priveşte spaţiul consumat, căutarea în adâncime e cu mult mai avantajoasă decât căutarea
în lărgime graţie păstrării numai drumului curent care conţine p noduri. Deci complexitatea spaţiului
este O(p), adică e o funcţie liniară în raport cu adâncimea.

Presupunem că graful de căutare este finit şi are adâncimea p. Dacă soluţia se află în primul
nod al nivelului p, atunci sunt explorate p+1 noduri. Dar dacă soluţia se găseşte în ultimul nod al
nivelului p, atunci numărul de noduri vizitate este

(f p 1  1)
1  f  f 2  ...  f p

(f  1)
Atunci numărul mediu de noduri vizitate va fi
p 1 p 1
(f  1 ) (p  1 ) (f  fp  f  p  2 )
 
2(f - 1) 2 2(f  1)
adică pentru valori mari ale lui f şi p este aproximativ f p/2. Prin urmare, căutarea în adâncime are de
a
asemenea complexitatea O(f p).
32 1
1 c
Căutarea iterativă în adâncime
213
1 32
b
32
drum_5(N,S,C,Max_dem,Max):- 2 32 2
2 3 23 2 3
d 3 e f 3 g
3
3 3 3
3 33 3 11
h i j k

Fig.20. Căutarea iterativă în adâncime


drum(N,S,C,Max_dem,Max).
drum_5(N,S,C,_,Max):-
Max1=Max+1,
drum_5(N,S,C,Max1,Max1).

drum(N,[N|C],C,_,_):-stare_finala(N).
drum(N,S,C,Max_dem,Max):-
Max_dem>0,
succesor(N,N1),
not(apartine(N1,C)),
Max_dem1=Max_dem-1,
drum(N1,S,[N|C],Max_dem1,Max).

Apelând din nou la arborele din fig.5 avem


?-drum_5(a,S,[],1,1)
S=[f,c,a]
S=[j,e,b,a]

Spaţiul utilizat de căutarea iterativă în adâncime este O(p), deoarece la fiece iteraţie are loc
căutarea în adâncime. Mai mult ca atât, contrar aparenţei, complexitatea timpului nu e mai mare decât
complexitatea timpului pentru la căutările în adâncime sau în lărgime.
Într-adevăr, numărul total de noduri explorate de căutările sterile până la nivelul p este
p 1
( f i 1  1 ) 1 p 1 p 1


i 0 ( f  1 )

( f  1)
[ f ( 
i 0
f i
)  
i 0
1] 

1 f p 1 f p 1  fp  f  p
 [ f( ) p] 
Adăugând
( f  1 ) la acest
f  1număr numărul ( f mediu
 1 ) 2 de noduri examinate la ultimul nivel, obţinem
p 1 p 1
f  fp  f  p f  fp  f  p  2

( f  1 )2 2( f  1 )
Deoarece numărul de noduri creşte exponenţial la fiecare nivel, cel mai mult timp efectiv este
consumat la ultimul nivel. Astfel timpul e dominat de
( f  1 ) f p 1
2( f  1 ) 2

pe când pentru căutarea în adâncime timpul era dominat de

f p 1
2( f  1 )

Deci raportul dintre timpul consumat de căutarea iterativă în adâncime şi timpul consumat de căutarea
în adâncime este

( f  1)
adică căutarea iterativă în
( f adâncime
 1) are aceeaşi complexitate ca şi căutarea în adâncime.

12
Tabelul din fig.21 este o totalizare comparativă a tehnicilor de căutare oarbă, unde simbolurile
reprezintă
 f – factorul de ramificare
 p – adâncimea soluţiei
 m – adâncimea maximală a arborelui de căutare
 l – limita de adâncime

Căutare
Evaluare Adâncime Iterativă
Lărgime Adâncime
Limitată Adâncime
Timp fp fm fl fp
p
Spaţiu f m l p
Admisibilă? Da Nu Nu Da
Completă? Da Nu Da, dacă l>=p Da

Fig.21. Eficienţa comparativă a căutărilor oarbe

13

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