TP_IA_Barnabe_Faure/TP1/aetoile.pl

134 lines
4.4 KiB
Prolog
Raw Blame History

%*******************************************************************************
% 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).