Vous êtes sur la page 1sur 10

Prolog :

Recherche dans un espace


d'états
Céline Rouveirol
D'après le cours de Tim Smith
http://www.inf.ed.ac.uk/teaching/courses/aipp/

07/11/16 1
Exemple de recherche dans un graphe
link(g,h). A B
link(g,d). Etat C
link(e,d). initial Etat
link(h,f). but
link(e,f).
link(a,e).
link(a,b). D E F
link(b,f).
link(b,c).
link(f,c).
Espace
d'états G H
go(X,X,[X]). | ?- go(a,c,X).
go(X,Y,[X|T]):- X = [a,e,f,c] ? ;
link(X,Z), X = [a,b,f,c] ? ;
go(Z,Y,T). X = [a,b,c] ? ;
no
Algorithme naïf de recherche Résultat de la recherche

07/11/16 2
Représentation de l'espace d'états
link(g,h). A Racine : état
link(g,d). initial
link(e,d).
link(h,f).
E B
link(e,f).
link(a,e).
link(a,b).
link(b,f). D F F C
link(b,c).
link(f,c).
C C

• La représentation abstraite d'un espace d'états est un arbre. Les noeuds


représentent des états.
• Le facteur de branchement indique combien d'états sont atteignables à
partir d'un état qcque. Ce pb a un facteur de branchement moyen de 2.
• La profondeur d'un noeud indique combien de mouvements (actions) ont
été nécessaires pour atteindre ce noeud depuis la racine. ‘C’ a ne
profondeur de 2 ou 3.
07/11/16 3
Implémentation en PROLOG
En Prolog, nous avons besoin de:
• un moyen de représenter un état et les transitions d'un
état à l'autre : link(a,e)
• Un moyen de générer tous les successeurs d'un état
donné
• go(X,Y,[X|T]):- link(X,Z), go(Z,Y,T).

• Un moyen de savoir si on est arrivé dans l'état but.


• go(X,X,[X])
• Un moyen de contrôler le parcours dans l'espace de
recherche.

07/11/16 4
Recherche en profondeur d'abord
A
solve(X,X,[X]).
solve(X,Y,[X|T]):-
link(X,Z),
solve(Z,Y,T). E B

?- solve(a,c,X).
X = [a,e,f,c] ? ;
D F F C
X = [a,b,f,c] ? ;
X = [a,b,c] ? ;
no C C

• Principe : Pour trouver un chemin vers le but, à partir d’un noeud X :


– Si X est un noeud but alors Sol =[X], ou
– S’il existe un noeud Z successeur de X tel qu’il existe un chemin T
de Z vers le noeud but Y, alors Sol = [X | T].
• Utilisation de l'unification/retour arrière de Prolog pour explorer les liens
entre un noeud et ses successeurs
07/11/16 5
Problèmes des cycles
lSi le graphe contient des cycles ou
est non orienté, il faut jouter un
mécanisme de détection de cycle :
-> Stocker le chemin du noeud initial vers le
noeud courant

depthfirst(Path, Node, Solution)‫‏‬


l Path : chemin (liste de noeuds) entre le noeud initial et Node.
l Node : état à partir duquel un chemin vers l’état but doit être trouvé.
l Solution : Path étendu par Node vers le noeud but.
l Prolog :
l Path : liste dans l’ordre inverse des noeuds.

07/11/16 6
Profondeur d'abord et cycles

solve(Node,Solution) :-
depthfirst([],Node, Solution)‫‏‬

% Solution est un chemin acyclique entre Node et le noeud but.

depthfirst(Path,Node,[Node | Path]) :-goal(Node).


depthfirst(Path,Node,Sol) :-
link(Node,Node1),
\+ member(Node1,Path), %éviter le cycle
depthfirst([Node | Path], Node1, Sol).

07/11/16 7
Recherche en largeur d'abord
| ?- solve(a,c,X). A
X = [a,b,c] ? ;
X = [a,e,f,c] ? ;
X = [a,b,f,c] ? ; E B 1er
no

D F F C 2ème

C C 3ème
• Principe : visiter les noeuds les plus proches du noeud de départ.
• Implémentation : maintenir un ensemble de noeuds candidats à chaque
étape (maintenir un ensemble de chemins).
• breadthfirst (Paths,Solution): vrai s’il y a un chemin de l’ensemble des
chemins candidats pouvant être étendu vers les noeuds buts.
• Solution: est un chemin étendu, Paths: une liste de chemins.
• Chaque chemin : liste de noeuds dans l’ordre inverse.
07/11/16 8
Recherche en largeur d'abord

Initialisation: Solutions = [[Noeud]]

Si la tête du premier chemin est un noeud but alors ce chemin est la solution
du problème.
sinon
– enlever le premier chemin de l’ensemble des chemins candidats.
– générer tous les chemins étendus d’un niveau possibles de ce chemin.
– ajouter cet ensemble d’extension a la fin de l’ensemble des candidats.

07/11/16 9
Recherche en largeur d'abord
solve(Start, Solution):-
breadthfirst([[Start]],Solution).

% Solution est le chemin du Start vers Goal.


breadthfirst([[Node | Path] | _],[Node | Path]):-
goal(Node).

breadthfirst([Path | Paths], Solution):-


extend(Path,NewPaths),
append(Paths,NewPaths,Paths1),
breadthfirst(Paths1,Solution).

extend([Node | Path],NewPaths):-
bagof([NewNode,Node | Path],
(link(Node,NewNode),
\+ member(NewNode,[Node | Path])),
NewPaths).
extend(Path,[]).
%bagof 07/11/16
échoue: le noeud n'a pas de successeur. 10

Vous aimerez peut-être aussi