Documente Academic
Documente Profesional
Documente Cultură
Ia3-Căutarea Euristică
Ia3-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])).
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.
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
Stare
finală
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).