Documente Academic
Documente Profesional
Documente Cultură
Euristica
Euristica
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).