Sunteți pe pagina 1din 4

Căutarea euristică

Căutarea alpină
Predicatul alpina(Drumuri, Drum) este adevărat dacă Drum este lista de noduri ce leagă nodul
iniţial de cel final. El este apelat alpina([[0,Initial]],Solutie), unde Initial este nodul de start şi zero
este valoarea euristică nodului iniţial. Valoarea zero este irelevantă, deoarece este un singur nod de la
care pornim.
alpina([[_,Nod|Drum]|_],[Nod|Drum]):-
stare_finala(Nod).
alpina([Drum|Drumuri],Sol):-
findall(NouDrum,alegere_urmator_nod(Drum,NouDrum),NoiDrumuri),

NoiDrumuri este lista drumurilor posibile formate prin extinderea drumului Drum (fără bucle).
inserare_toate(NoiDrumuri,[],DrumuriSortate),
concatenare(DrumuriSortate,Drumuri,ToateDrumurile),
alpina(ToateDrumurile,Sol).

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

Predicatul inserare_toate(Drumuri1,Drumuri2,Drumuri3) este adevărat dacă Drumuri3 este


rezultatul inserării Drumuri1 în Drumuri2. Dacă Drumuri1 şi Drumuri2 sunt sortate, atunci lista
Drumuri3 de asemenea este sortată.
inserare_toate([],Drumuri,Drumuri).
inserare_toate([Drum|Drumuri],Drumuri2,Drumuri3):-
inserare_1_drum(Drum,Drumuri2,Drumuri4),
inserare_toate(Drumuri,Drumuri4,Drumuri3).

Predicatul inserare_1_drum(Drum,Drumuri2,Drumuri3) este adevărat dacă Drumuri3 este


rezultatul inserării Drum în Drumuri2. Dacă lista Drumuri2 este sortată, atunci şi Drumuri3 va fi
sortată.
inserare_1_drum(Drum,[],[Drum]).
inserare_1_drum([E|Drum],[[E2|Drum2]|Drumuri],[[E|Drum],[E2|Drum2]|Drumuri2]):-
E<=E2.
inserare_1_drum([E|Drum],[[E2|Drum2]|Drumuri],[[E2|Drum2]|Drumuri2]):-
E>E2,
inserare_1_drum([E|Drum],Drumuri,Drumuri2).
Căutarea lacomă

2 8 3 1 2 3

1 6 4  8 4

7 5 7 6 5

Fig.9.
5
2 8 3
1 6 4
7 5

6 4 6
2 8 3 2 8 3 2 8 3
1 6 4 1 4 1 6 4
7 5 7 6 5 7 5
5
4
2 3
1 8 4
7 6 5

3
2 3
1 8 4
7 6 5

2
1 2 3
8 4
7 6 5

1 2 3
8 4
7 6 5

Fig.78.

Predicatul lacoma1(Drumuri, Drum) este adevărat dacă Drum este lista de noduri ce leagă
nodul iniţial de cel final. El este apelat lacoma([[0,Initial]],Solutie), unde Initial este nodul de start şi
zero este valoarea euristică nodului iniţial.
lacoma1([[_,Nod|Drum]|_],[Nod|Drum]):-
stare_finala(Nod).
lacoma1([Drum|Drumuri],Sol):-
findall(NouDrum,alegere_urmator_nod(Drum,NouDrum),NoiDrumuri),
inserare_toate(NoiDrumuri,Drumuri,Drumuri2),
lacoma1(Drumuri2,Sol).
Predicatele alegere_urmator_nod/2 şi inserare_toate/3 sunt aceleaşi ca şi în căutarea alpină

Următorul program Prolog este încă o posibilă implementare a căutării lacome. Aici se
utilizează predicatele predefinite assert/1 şi retrect/1. Similar programului largime_2/2 este şi
predicatul agenda. Ultimul, însă are încă un argument adiţional pentru reprezentarea valorii nodului.
Să menţionăm că predicatul preferinta/6 are două triplete de argumente, fiecare triplet reprezentând
acelaşi lucru ca argumentele predicatului agenda/3 numai că ele se referă la cele două noduri ce
trebuie comparate spre a fi ales unul din ele.
Lacoma2(I,G):-
ad_stare(I,[]),
repetare, alegere_stare(S,P),
ad_succesor(S,P),
agenda(S,G,E),retract(agenda(S,G,E)).

ad_succesor(S,_):-satre_finala(S),!.
ad_succesor(S,P):-
succesor(S,S1),
ad_stare(S1,P),fail.
ad_succesor(S,P):-
retract(agenda(S,P,E)),
assert(utilizat(S)),fail.

ad_stare(S,P):-
not(utilizat(S)),
not(agenda(S,P1,E)),
euristica(S,E1),
assert(agenda(S,[S|P],E1)),!.

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

alegere_stare(S,P):-
agenda(S,P,E),not(superior(S,P,E)),!.

superior(X1,Y1,E1):-
agenda(X2,Y2,E2),X1<>X2,
preferinta(X2,Y2,E2,X1,Y1,E1).

preferinta(_,_,E1,_,_,E2):-E1<E2.

Acelaşi program implementează căutarea în adâncime, dacă ultima clauză este substituită cu
praferinta(_,_,_,_,_,_):-fail.

şi implementează căutarea în lărgime dacă ultima clauză e substituită cu


perferinta(_,Y1,_,_,Y2,_):-
lungime(Y1,L1),
lungime(Y2,L2),
L1<L2.

lungime([],0).
lungime([_|C],N):-lungime(C,N1), N is N1+1.
Căutarea A*

Stare
iniţială
0 1 2 3 4
0     
g(n) 1     
2 F    
f(n) 3    I 
n
4     

h(n) Fig.44. Distanţa Manhattan

Stare
finală

Fig.%. Costul total al drumului

Predicatul aaster(Drumuri, Drum,Cost) este adevărat dacă Drum este lista de noduri ce leagă
nodul iniţial de cel final cu costul Cost. El este apelat sub forma aaster([[0,0,Initial]],Solutie,Cost),
unde Initial este nodul de start şi zerourile sunt f-valoarea şi g-valoarea stării iniţiale.
aaster([[_,G,Nod|Drum]|_],[Nod|Drum],G):-
stare_finala(Nod).
aaster ([Drum|Drumuri],Sol,G):-
findall(NouDrum,alegere_urmator_nod(Drum,NouDrum),NoiDrumuri),
inserare_toate(NoiDrumuri,Drumuri,Drumuri2),
aaster(Drumuri2,Sol,G).

Predicatul inserare_toate/3 este acelaşi ca şi în căutarea alpină, iar alegere_urmator_nod/2


are forma
alegere_urmator_nod([F,G,Nod|Drum],[F1,G1,Nod1,F,G,Nod|Drum]):-
succesor(Nod,Nod1),
cost(Nod,Nod1,C),
G1=G+C,
euristica(Nod1,E),
F1=G1+E,
not(apartine(Nod1,[Nod|Drum])).

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