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