134 lines
4.4 KiB
Prolog
134 lines
4.4 KiB
Prolog
%*******************************************************************************
|
||
% AETOILE
|
||
%*******************************************************************************
|
||
|
||
/*
|
||
Rappels sur l'algorithme
|
||
|
||
- structures de donnees principales = 2 ensembles : P (etat pendants) et Q (etats clos)
|
||
- P est dedouble en 2 arbres binaires de recherche equilibres (AVL) : Pf et Pu
|
||
|
||
Pf est l'ensemble des etats pendants (pending states), ordonnes selon
|
||
f croissante (h croissante en cas d'egalite de f). Il permet de trouver
|
||
rapidement le prochain etat a developper (celui qui a f(U) minimum).
|
||
|
||
Pu est le meme ensemble mais ordonne lexicographiquement (selon la donnee de
|
||
l'etat). Il permet de retrouver facilement n'importe quel etat pendant
|
||
|
||
On gere les 2 ensembles de fa<66>on synchronisee : chaque fois qu'on modifie
|
||
(ajout ou retrait d'un etat dans Pf) on fait la meme chose dans Pu.
|
||
|
||
Q est l'ensemble des etats deja developpes. Comme Pu, il permet de retrouver
|
||
facilement un etat par la donnee de sa situation.
|
||
Q est modelise par un seul arbre binaire de recherche equilibre.
|
||
|
||
Predicat principal de l'algorithme :
|
||
|
||
aetoile(Pf,Pu,Q)
|
||
|
||
- reussit si Pf est vide ou bien contient un etat minimum terminal
|
||
- sinon on prend un etat minimum U, on genere chaque successeur S et les valeurs g(S) et h(S)
|
||
et pour chacun
|
||
si S appartient a Q, on l'oublie
|
||
si S appartient a Ps (etat deja rencontre), on compare
|
||
g(S)+h(S) avec la valeur deja calculee pour f(S)
|
||
si g(S)+h(S) < f(S) on reclasse S dans Pf avec les nouvelles valeurs
|
||
g et f
|
||
sinon on ne touche pas a Pf
|
||
si S est entierement nouveau on l'insere dans Pf et dans Ps
|
||
- appelle recursivement etoile avec les nouvelles valeurs NewPF, NewPs, NewQs
|
||
|
||
*/
|
||
/*affiche_solution(_, nil).
|
||
affiche_solution(Q, U) :-
|
||
U \= nil,
|
||
belongs([U, _, Pere, A], Q),
|
||
affiche_solution(Q, Pere),
|
||
write(A).
|
||
*/
|
||
|
||
affiche_solution(_, _, nil).
|
||
|
||
affiche_solution(Q, Pu, U) :-
|
||
U \= nil,
|
||
belongs([U, _, Pere, A], Q),
|
||
affiche_solution(Q, Pu, Pere),
|
||
write(A),
|
||
write("->").
|
||
|
||
affiche_solution(Q, Pu, U) :-
|
||
U \= nil,
|
||
belongs([U, _, Pere, A], Pu),
|
||
affiche_solution(Q, Pu, Pere),
|
||
write(A),
|
||
write("->").
|
||
|
||
expand(U, LSuc, G) :-
|
||
findall([S, [F, H, G2], U, Rule],
|
||
(rule(Rule, C, U, S),
|
||
G2 is G+C,
|
||
heuristique(S, H),
|
||
F is G2+H),
|
||
LSuc).
|
||
test_expand() :-
|
||
initial_state(U),
|
||
write(U),
|
||
expand(U, L, 0),
|
||
write(L).
|
||
loop_successors([], Ps,Pf,_,Ps,Pf).
|
||
|
||
loop_successors([[S, _, _, _]|LSuc], Ps, Pf, Qs, PsF, PfF) :-
|
||
belongs([S, _, _, _], Qs),
|
||
loop_successors(LSuc, Ps, Pf, Qs, PsF, PfF).
|
||
|
||
|
||
loop_successors([[S, [F, H, G], Pere, A]|LSuc], Ps, Pf, Qs, PsF, PfF) :-
|
||
not(belongs([S, _, _, _], Qs)),
|
||
belongs([S, [Fu, Hu, Gu], PereU, Au], Ps),
|
||
F<Fu,
|
||
suppress([S, [Fu, Hu, Gu], PereU, Au], Ps, Ps2),
|
||
insert([S, [F, H, G], Pere, A], Ps2, Ps3),
|
||
suppress([[Fu, Hu, Gu], S], Pf, Pf2),
|
||
insert([[F, H, G], S], Pf2, Pf3),
|
||
loop_successors(LSuc, Ps3, Pf3, Qs, PsF, PfF).
|
||
|
||
loop_successors([[S, [F, _, _], _, _]|LSuc], Ps, Pf, Qs, PsF, PfF) :-
|
||
not(belongs([S, _, _, _], Qs)),
|
||
belongs([S, [Fu, _, _], _, _], Ps),
|
||
F>Fu,
|
||
loop_successors(LSuc, Ps, Pf, Qs, PsF, PfF).
|
||
|
||
loop_successors([[S, [F, H, G], Pere, A]|LSuc], Ps, Pf, Qs, PsF, PfF) :-
|
||
not(belongs([S, _, _, _], Qs)),
|
||
not(belongs([S, _, _, _], Ps)),
|
||
insert([S, [F, H, G], Pere, A], Ps, Ps2),
|
||
insert([[F, H, G], S], Pf, Pf2),
|
||
loop_successors(LSuc, Ps2, Pf2, Qs, PsF, PfF).
|
||
|
||
main :-
|
||
initial_state(S0),
|
||
heuristique(S0, H0),
|
||
G0 is 0,
|
||
F0 is H0+G0,
|
||
empty(Pf),
|
||
empty(Pu),
|
||
empty(Q),
|
||
insert([[F0,H0,G0], S0], Pf, Pf2),
|
||
insert([S0, [F0,H0,G0], nil, nil] , Pu, Pu2),
|
||
aetoile(Pf2, Pu2, Q).
|
||
|
||
|
||
%*******************************************************************************
|
||
aetoile(nil, nil, _) :-
|
||
write("PAS DE SOLUTION : l'etat final n est pas atteignable").
|
||
aetoile(Pf, Ps , Qs) :-
|
||
suppress_min([_, U], Pf, _),
|
||
final_state(U),
|
||
affiche_solution(Qs, Ps, U).
|
||
aetoile(Pf, Ps, Qs) :-
|
||
suppress_min([[F, H, G], U], Pf, Pf2),
|
||
suppress([U, [F, H, G] , UPere , A], Ps, Ps2),
|
||
expand(U, LSuc, G),
|
||
loop_successors(LSuc, Ps2, Pf2, Qs, PsF, PfF),
|
||
insert([U, [F, H, G], UPere, A], Qs, Qs2),
|
||
aetoile(PfF, PsF, Qs2).
|