Upload
others
View
6
Download
0
Embed Size (px)
Citation preview
INTRODUCTION À L'INTELLIGENCE ARTIFICIELLE ET LA THÉORIE DE JEUX
WIESLAW ZIELONKAWWW.IRIF.UNIV-PARIS-DIDEROT.FR/~ZIELONKA
http://www.irif.univ-paris-diderot.fr/~zielonka
PROBLÈMES DE RECHERCHEJeu de Taquin
• états
• état initial
• actions
• transitions (état,action) → état
• coût de chemin
• teste de l'état final, état → true, false
1 23
4
65
7
8
1 2
4 65
7 8
3
Etat initial
suite d'actions
Etat final
PROBLÈME DE HUIT DAMES
PROBLÈMES DE RECHERCHE
État initial : échiquier vide (ou échiquier avec 8 dames dans les positions quelconques).
Action - ajouter une dame sur une position vide
PLANIFICATION DE VOYAGE AVION
difficile :
• contraintes date de depart,
• changement d'avion (sur un trajet A → B → C l'avion A → B doit arrivé avant le depart de l'avion B → C)
• le coût
• la durée totale
LE PROBLÈME DE COMMIVOYAGEUR
Faire le tour de toutes les villes en passant par chaque ville une seule fois. Minimiser la longueur totale du trajet. NP-complet.
ALGORITHME GÉNÉRIQUE - TREE-SEARCH
Les feuilles de l'arbre de recherche forment une frontière. On ne mémorise pas les noeuds déjà visités dont toutes les arêtes sortantes ont déjà été examinées.
fonction tree-search(problème) retourne solution ou échec n = new noeud(état_init); frontière = { n }; loop do si frontière vide retourner échec n = élément de la frontière; supprimer n de la frontière; if n.état est un état but alors retourner solution pour chaque action a faire nouvel_état = transition(n.état, a) m = new noeud(nouvel_état) ajouter m dans la frontière fait end loop
ALGORITHME GÉNÉRIQUE — GRAPHE-SEARCH
fonction graph-search(problème) retourne solution ou échec n = new noeud(état_init); frontière = { n }; closed_set = {}; loop do si frontière vide retourner échec n = élément de la frontière supprimer n de la frontière if n.état est un état but alors retourner solution ajouter n dans closed_set pour chaque action a faire nouvel_état = transition(n.état, a) si nouvel_état dans un noeud de la frontière ou dans un noeud de closed_set alors continue m = new noeud(nouvel_état) ajouter m dans la frontière fait end loop
Quelle structure pour stocker les noeuds dans la frontière?
QUELLE FILE ?
• FIFO — first in first out, file habituelle
• LIFO — last in first out, pile
• file de priorité
IMPLÉMENTER LA FRONTIÈRE COMME UNE FILE
• créer_file() — retourne une file vide
• est_vide(file) — retourne true si la file vide
• premier(file) — retourne le premier élément (celui avec le coût minimal)
• supprimer_premier(file) — supprime le premier élément de la file
• insérer(file, élément) — ajouter un élément dans la file
INFRASTRUCTURE POUR LE PROBLÈME DE RECHERCHE
• n.état — état du noed
• n.parent — le parent du noeud
• n.action — l'action qui appliquée au parent donne l'état du nouer
• n.coût le coût du chemin de la racine jusqu'au noeud
fonction créer_noeud(Noeud parent, Action action) retourne Noeud n = new noeud() n.état = transition(parent.état, action) n.action = action n.coût = parent.coût + coût(parent.état,action) n.parent = parent
INFRASTRUCTURE POUR LE PROBLÈME DE RECHERCHE
fonction créer_noeud_initial(État état) retourne Noeud n = new noeud() n.état = état n.action = null n.coût = 0 n.parent = null
TREE-SEARCH
fonction tree-search(problème) retourne solution ou échec
n = créer_noeud_initial(état_initial)
frontière = créer_file()
loop do
si est_vide(frontière) retourner échec
n = premier(frontière); supprimer_premier(frontière);
if n.état est un état but alors retourner n
pour chaque action a faire
nouveau_noeud = créer_noeud(n, a)
insérer(frontière,nouveau_noeud)
fait
end loop
CRITÈRES DE PERFORMANCES
• algorithme complet ? Oui, s'il trouve une solution quand elle existe.
• l'algorithme optimal ? est-ce que la solution trouvée est optimale?
• complexité en temps et espace
RECHERCHE EN LARGEUR
• coût(état,action) est 1
• la file : FIFO, arrêter de que la solution trouvé (teste de but avant de mettre le noeud dans la frontière et non pas à la sortie de la frontière)
• Est-ce que l'algorithme est complet ?
• Optimal?
• complexité : si chaque sommet possède b fils et la solution se trouve à distance d de la racine alors le nombre de noeuds générés
b+b^2+b^3+…+b^d = O(b^d)
RECHERCHE EN LARGEUR
b = 10 (facteur de branchement)
un million de noeuds par seconde, mémoire par noeud 1000 octets
profondeur noeuds temps mémoire
8 10^8 2 minutes 103 GB
10 10^10 3 heures 10 TB
12 10^12 13 jours 1 petabyte
14 10^14 3.5 année 99 petabytes
16 10^16 350 ans 10 exabytes
UNIFORM COST SEARCH
• file = file de priorité
• le coût coût(état,action) doit être positif
• Trouve toujours le plus court chemin donc complet et optimal.
• Il est très important que le teste de terminaison au moment ou un noeud sort de la frontière (si le teste à l'entrée de la frontière l'algorithme n'est plus optimal).
RECHERCHE EN PROFONDEUR
• utilise LIFO (une pile)
• ni complet ni optimal
• quel coût en espace ?
• une variante : backtracking search - on garde que le sommet courant, son parent, parent de parent etc.
ITERATIVE DEEPENING DEPTH-FIRST SEARCH
limited_depth_first_search(k) — fait la recherche en profondeur jusqu'au niveau k et retourne soit une solution soit échec
deepening_depth_first_search() for i=1 to infinity do solution = limited_depth_first_search(k) si solution != échec alors retourner solution done
RECHERCHE INFORMÉE (AVEC AIDE DE HEURISTIQUE)
• appelé BEST_FIRST_SEARCH
• la fonction heuristique h(n) — le coût estimé de chemin le plus court de sommet n jusqu'au but
• g(n) — le coût de chemin le plus court de sommet initial vers le sommet n (calculé par l'algorithme)
• f(n) — la fonction d'évaluation, à chaque iteration on cherche dans la frontière le sommet n avec f(n) minimal
HEURISTIQUE
pour le plus court chemin entre les ville h(n) - la distance à vol d'oiseau de la ville n jusqu'à la ville destination
ALGO DE RECHERCHE GLOUTON (GREEDY BEST-FIRST SEARCH)
• on prend f(n) = h(n) et on utilise la file de priorité où pour chaque sommet n on stocke la valeur h(n)
• à chaque étape on prend de la file de priorité le sommet n avec f(n)=h(n) minimal
• le coût du chemin de sommet source vers n n'est pas pris en compte
• la version tree-like de l'algorithme n'est pas complète
• la version graph-like est complète mais pas optimale
ALGO COÛT UNIFORME
• si f(n)=g(n), c'est-à-dire on n'utilise pas la heuristique alors la recherche de coût uniforme (déjà étudiée)
ALGORITHME A^* - MINIMISER LE COÛT TOTAL
• dans chaque sommet n on stocke g(n) et f(n)=g(n)+h(n)
• la file de priorité pour les valeurs f(n), à chaque étape on choisit un noeud avec f(n) minimal
INFRASTRUCTURE POUR L'ALGORITHME A^*
• n.état — état du noed
• n.parent — le parent du noeud
• n.action — l'action qui appliquée au parent donne l'état du nouer
• n.coût — le coût du chemin de la racine jusqu'au noeud, c'est g(n)
• n.f — la valeur f(n), la file de priorité selon les valeur n.f
fonction créer_noeud(Noeud parent, Action action) retourne Noeud n = new noeud() n.état = transition(parent.état, action) n.action = action n.coût = parent.coût + coût(parent.état,action) n.parent = parent n.f = n.coût + h(n.état)
INFRASTRUCTURE POUR L'ALGORITHME A^*
fonction créer_noeud_initial(État état) retourne Noeud n = new noeud() n.état = état n.action = null n.coût = 0 n.parent = null n.f = 0
ALGORITHME A^*
Le même que tree-search avec les modifications sur les deux transparents précédents et avec la fille de priorité qui retourne à l'appel
premier(file)
le noeud n avec n.f minimal
HEURISTIQUE ADMISSIBLE
la fonction heuristique h est admissible si pour chaque sommet n
h(n)
HEURISTIQUE CONSISTANTE
Une heuristique est consistante si elle satisfait l'inégalité de triangle:
pour chaque couple de sommets n et m et action a telle que
m=transition(n,a) on a
h(n)
OPTIMALITÉ DE A^*
• Si la heuristique h est admissible alors la version tree-search de l'algorithme A^* est optimale.
• Si la heuristique h est consistante alors la version graph-searche de l'algorithme A^* est optimale.
COMMENT TROUVER LES HEURISTIQUES OPTIMALES?
• en assouplissant les conditions (ajoutant les actions)
• en travaillant avec des sous-problèmes