Algorithmes de recherche g´en´eriquesfelipe/IFT3335-Automne2008/MySlides/… · 1Je ne programme...
Transcript of Algorithmes de recherche g´en´eriquesfelipe/IFT3335-Automne2008/MySlides/… · 1Je ne programme...
Algorithmes de recherche generiques
Il est toujours possible d’ecrire a la piece un algorithme derecherche pour un besoin specifique. Il est cependant plusproductif d’ecrire sa boıte a outil d’algorithmes de recherche”generique”. Nous devons pour cela definir :
• Une facon d’exprimer le probleme
• Une ou plusieurs facons de representer une frange
• Une structure permettant d’encoder un nœud de l’arbrede recherche
• Les algorithmes de recherche !
En cours nous avons vu des interfaces de chacune de cescomposantes. Reste a les mettre en œuvre.
Une approche generique. . .
Pro : meilleure conception, utilisabilite accrue
Cons : plus de code a ecrire !
Prenons Java comme langage d’implementation1.
Nous avons besoin de manipuler un etat, et ce quelque soit leprobleme. Soit IState une interface permettant de manipulerdes etats de maniere polymorphique.
interface IState { }
1Je ne programme pas Java, aussi, je ne suis pas au fait des facilitestemplate offertes par les nouveaux compilateurs et qui devraient etre iciexploitees pour un code plus generique.
Les interfaces
Tous les problemes seront manipules via cette interface :
interface IProblem {public IState INIT();public boolean GOAL( IState state );public LinkedList< Triplet > SUCCESSOR_FN(IState state);
}
ou Triplet est une structure permettant de stocker :<action,nouvel-etat,step-cost>.
Les interfaces
Nous allons manipuler differents types de frange (qui definirontle type de recherche effectuee).
interface IFrange {
public Node REMOVE_FIRST();
public boolean EMPTY();
public void INSERT_ALL(LinkedList <Node> l);
public void INSERT(Node n);
}
Representation d’un nœud
class Node {private Node parent;private IState etat;private int path_cost,profondeur;private String action;
public IState STATE() {return etat;}public int PATH_COST() {return path_cost;}public int DEPTH() {return profondeur;}public Node PARENT() {return parent;}public String ACTION() {return action;}
public Node(IState state, Node parent, String action,int costChemin, int depth) {}
public Node(IState state) {}}
Il existe probablement plus simple
class Triplet {private IState state;private String action;private int step_cost;
public Triplet(IState state_,String action_, int sc_) {state = state_;action = action_;step_cost = sc_;
}
public IState getState() {return state;}public String getAction() {return action;}public int getStepCost() {return step_cost;}
}
Largeur d’abord ≡ FIFO
class FIFO implements IFrange {private LinkedList < Node > frange;
public FIFO() { frange = new LinkedList <Node>(); }public Node
REMOVE_FIRST() { return frange.removeLast(); }public boolean EMPTY() { return frange.size() == 0;}public void
INSERT_ALL(LinkedList <Node> l) {frange.addAll(0,l);}public void INSERT(Node n) { frange.addFirst(n);}
}
Outils pour tous les solveurs
class ISolver {protected void SOLUTION(Node node) { ... }
protected LinkedList< Node >EXPAND(IProblem problem, Node node) {
LinkedList< Node > succs = new LinkedList< Node >();for ( Triplet t : problem.SUCCESSOR_FN(node.STATE()) )
succs.add(new Node(t.getState(), node, t.getAction(),
node.PATH_COST() + t.getStepCost(),node.DEPTH() + 1));
return succs;}
}
L’algorithme de recherche
class TreeSearch extends ISolver {
public TreeSearch(IProblem problem, IFrange fringe) {
fringe.INSERT(new Node(problem.INIT()));do {
Node node = fringe.REMOVE_FIRST();
if (problem.GOAL(node.STATE())) { SOLUTION(node); }fringe.INSERT_ALL(EXPAND(problem,node));
}while (fringe.EMPTY() == false);
}}
Et enfin ... le probleme !Un etat
class StateAspirateur implements IState {
private boolean dirty [];private int pos_x; // la position du robot
public StateAspirateur(int x, boolean dirt []) {dirty = new boolean [dirt.length];System.arraycopy(dirt,0,dirty,0,dirt.length);pos_x = x;
}
public int getPos() {return pos_x;}public boolean [] getDirtLocation() { return dirty; }
Et enfin ... le probleme !Un etat
public boolean allClean() {for (int i=0; i<dirty.length; ++i)
if (dirty[i]) return false;return true;
}public void setDirtLocation(int pos, boolean dirt) {
dirty[pos] = dirt;}
public String toString() {String s = "";for (boolean b : dirty) s += ((b? "D":".") + " ");return "pos=" + pos_x + " dirt=[ " + s + "]";
}} // StateAspirateur
Et enfin ... le probleme en lui meme !class ProblemAspirateur implements IProblem {
private static final int N = 8;private static final int STEP_COST = 1;
public IState INIT() {boolean dirty[] = {true, false, true, true, true, true, true, false};return new StateAspirateur(1,dirty);
}public boolean GOAL(IState state) {
return ((StateAspirateur) state).allClean();}public LinkedList< Triplet >
SUCCESSOR_FN( IState istate ) {StateAspirateur state = (StateAspirateur) istate;LinkedList<Triplet> succs = new LinkedList<Triplet> ();
Et enfin ... le probleme en lui meme !Le probleme
// action 1 : aspirerif (state.getDirtLocations[state.getPos()]) {
succs.add(new Triplet(
new StateAspirateur( state.getPos(),state.getDirtLocations()),
"Aspire", STEP_COST ));StateAspirateur etat =
(StateAspirateur) succs.getLast().getState();etat.setDirtLocation(state.getPos(),false);
}
Et enfin ... le probleme en lui meme !Le probleme
if (state.getPos() > 0)succs.add( // action 2 : aller a gauche
new Triplet(new StateAspirateur(state.getPos()-1,
state.getDirtLocations()),"Gauche", STEP_COST ));
if (state.getPos() < (N-1) )succs.add( // action 3 : aller a droite
new Triplet (new StateAspirateur(state.getPos()+1,
state.getDirtLocations()),"Droite", STEP_COST ));
return succs;} // SUCCESSOR-FN
Aspirateur
graph-search tree-searchC? d e m c C? d e m c
fifo 13 13 823 13 918 13 13 97579 13 226778lifo 28 28 76 31 101 boucle infinie
C? cout de la solution d profondeur de la solutione nœuds etendus c nœuds creesm profondeur max
Aspirateur en largeur, Tree-SearchSolution de cout : 13.0 profondeur : 13nodes extended : 97579 max depth : 13 created nodes : 226778
pos=1 dirt=[ D . D D D D D . ]action Gauche -> pos=0 dirt=[ D . D D D D D . ]action Aspire -> pos=0 dirt=[ . . D D D D D . ]action Droite -> pos=1 dirt=[ . . D D D D D . ]action Droite -> pos=2 dirt=[ . . D D D D D . ]action Aspire -> pos=2 dirt=[ . . . D D D D . ]action Droite -> pos=3 dirt=[ . . . D D D D . ]action Aspire -> pos=3 dirt=[ . . . . D D D . ]action Droite -> pos=4 dirt=[ . . . . D D D . ]action Aspire -> pos=4 dirt=[ . . . . . D D . ]action Droite -> pos=5 dirt=[ . . . . . D D . ]action Aspire -> pos=5 dirt=[ . . . . . . D . ]action Droite -> pos=6 dirt=[ . . . . . . D . ]action Aspire -> pos=6 dirt=[ . . . . . . . . ]
Cannibale
regles et jeu :http:
//www.novelgames.com/flashgames/game.php?id=54
graph-search tree-searchC? d e m c C? d e m c
fifo 11 11 29 11 31 11 11 11852 11 26893lifo 11 11 21 11 28 boucle infinie
C? cout de la solution d profondeur de la solutione nœuds etendus c nœuds creesm profondeur max
Cannibale en largeur, Graph-SearchSolution de cout : 11 profondeur : 11 nodes extended : 29max depth : 11 created nodes : 31
Rive 1 M3 C3 ~~~ M0 C0action [1 each] Rive 2 M2 C2 ~~~ M1 C1action [1 miss] Rive 1 M3 C2 ~~~ M0 C1action [2 cann] Rive 2 M3 C0 ~~~ M0 C3action [1 cann] Rive 1 M3 C1 ~~~ M0 C2action [2 miss] Rive 2 M1 C1 ~~~ M2 C2action [1 each] Rive 1 M2 C2 ~~~ M1 C1action [2 miss] Rive 2 M0 C2 ~~~ M3 C1action [1 cann] Rive 1 M0 C3 ~~~ M3 C0action [2 cann] Rive 2 M0 C1 ~~~ M3 C2action [1 cann] Rive 1 M0 C2 ~~~ M3 C1action [2 cann] Rive 2 M0 C0 ~~~ M3 C3
Arad→Bucharest
graph-search tree-searchC? d e m c C? d e m c
fifo 450 3 16 3 21 450 3 24 3 64lifo 607 5 10 4 14 boucle infiniepqueue 418 4 24 4 31 418 4 53 5 132
C? cout de la solution d profondeur de la solutione nœuds etendus c nœuds creesm profondeur max
g-search(pqueue), t-search(pqueue) : 418arad→sibiu→rimnicu→pitesti→bucharest
Arad→Bucharest
graph-search tree-searchC? d e m c C? d e m c
fifo 450 3 16 3 21 450 3 24 3 64lifo 607 5 10 4 14 boucle infiniepqueue 418 4 24 4 31 418 4 53 5 132
C? cout de la solution d profondeur de la solutione nœuds etendus c nœuds creesm profondeur max
g-search(fifo), t-search(fifo) : 450arad → sibiu → fagaras → bucharest
Note : largeur d’abord n’est pas optimal ici
Arad→Bucharest
graph-search tree-searchC? d e m c C? d e m c
fifo 450 3 16 3 21 450 3 24 3 64lifo 607 5 10 4 14 boucle infiniepqueue 418 4 24 4 31 418 4 53 5 132
C? cout de la solution d profondeur de la solutione nœuds etendus c nœuds creesm profondeur max
g-search(lifo) : 607arad→zerind→oradea→sibiu→fagaras→bucharest
Arad→Bucharestrecherche informee
graph-search(p-queue) C? d e m cf(n) = path cost(n) 418 4 24 4 31f(n) = h(n) 450 3 4 3 10f(n) = path cost(n) + h(n) 418 4 6 4 16
C? cout de la solution d profondeur de la solutione nœuds etendus c nœuds creesm profondeur max