Algorithmes de recherche g´en´eriquesfelipe/IFT3335-Automne2008/MySlides/… · 1Je ne programme...

Post on 26-Aug-2020

0 views 0 download

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