Vous êtes sur la page 1sur 48

Cours IA et Apprentissage automatique

 De nombreux problèmes peuvent être représentés sous la


forme d’un graphe ou d’un arbre
 Résoudre ces problèmes Chercher la solution (But)
Trouver un chemin dans le graphe/l’arbre (Etat initial ->
But)

 Exemples : GPS, Recherche d’itinéraires, Jeux Vidéo, Jeux


d’échec,...
 Un problème de recherche peut être vu comme un graphe orienté (ou un arbre) où les
noeuds sont des états accessibles depuis l’état initial et où les arcs sont des actions.
 Un problème de recherche est défini par :
 Un état initial
 Un ensemble d’actions
 Une fonction de successeur, qui définit l’état résultant de l’exécution d’une action dans un état
 U n ensemble d’états buts
 Une fonction de coût, associant à chaque action un nombre non-négative (le côut de l’action)

 Une solution sera un chemin de l’état initial à un état but.


 Une solution est optimale si la somme des coûts des actions du chemin est minimale
parmi toutes les solutions du problème.
• Etat : Les configurations des huit tuiles dans les neuf cases de la grille.
• Etat initial : N’importe quel état pourrait être choisi comme l’état
initial.
• Action : la position du carré vide : haut, bas, gauche, droite
• Fonction de successeur: spécifie les états résultants des différentes
actions.
• Test de but : L’état but est unique et fixé au début´ du jeu ( il s’agit en Etat 1 Etat 2
général de remettre les nombres dans l’ordre).
Action: droite
• Coût de l’action : Chaque déplacement d’une tuile a coût de 1
 La plupart des algorithmes de recherche suivent à peu près le
même schéma :
 Commencer par l’état initial et puis exécuter les étapes suivantes
en boucle jusqu’`a terminaison :
– s’il n’y a plus d’états à traiter, renvoyer échec
sinon
choisir un des états à traiter (?)
– si l’état est un état but, renvoyer la solution correspondante
sinon
supprimer cet état de l’ensemble des états à traiter, et
le remplacer par ses états successeurs (?)
 Complexité en temps: Combien du temps prend l’algorithme
pour trouver la solution ?
 Complexité en espace: Combien de mémoire est utilisée lors
de la recherche d’une solution ?
 Complétude: Est-ce que l’algorithme trouve toujours une
solution s’il y en a une ?
 Optimalité: Est-ce que l’algorithme renvoie toujours des
solutions optimales ?
 Recherche non informée
 La recherche non informée utilise seulement des informations disponibles
dans la définition du problème
 N’utilise pas des informations internes à l’état (e.g. qualité de l’état)
 Recherche informée
 La recherche informée, également appelée recherche heuristique, utilise des
informations ou des estimations spécifiques sur le problème pour guider la
recherche.
 Explore les nœuds selon une évaluation de leur qualité ou de leur promesse.
Algorithmes :

 Recherche en largeur d’abord (Breadth-first search)


 Recherche de coût uniforme (Uniform-cost search)
 Recherche en profondeur d’abord (Depth-first search)
 Recherche en profondeur limitée (Depth-limited search)
 Recherche en approfondissement itératif (Iterative deepening search)

Comment les noeuds sont insérés et retirés dans la liste ?


Principe :
 Le nœud racine est développé en premier,
ensuite tous les successeurs du nœud racine
sont développés, puis leurs successeurs…

 Tous les nœuds sont développés à une


profondeur donnée dans l'arbre de recherche
avant que les nœuds au niveau suivant ne
soient développés.
Fonction Rech_Largeur (NœudI, But) : Trouvé, Echec
Debut
Frontière  NoeudI // ajout au sommet de la file
Tant que (Frontière  Vide)
NoeudC  Frontière.retirer () // Au sommet
si (NoeudC.etat = But) renvoyer Trouvé
// Ajout de tous les successeurs
Pour chaque Expansion (NoeudC)
Frontière  Frontière + Expansion (NoeudC) // A la fin
Fin tant que
renvoyer Echec
Fin
G

F C
A
Nœud
initial B
G A B D H D

H F
D E G B K E G

C E K Solution
But
G A C K A C F
Fonction Rech_Largeur (NœudI, But) : Trouvé, Echec
Debut
Frontière  NoeudI // ajout au sommet de la file
ListeVisités  Null
Tant que (Frontière  Vide)
NoeudC  Frontière.retirer () // Au sommet
si (NoeudC.etat = But) renvoyer Trouvé
ajouter (ListeVisités , NoeudC )
Pour chaque Expansion (NoeudC)  ListeVisités
Frontière  Frontière + Expansion (NoeudC)
Fin Pour
Fin tant que
renvoyer Echec
Fin
b: nombre de branchements maximal de l’arbre de recherche
d: profondeur de la meilleure solution

 Complexité en temps: O(bd)


 Complexité en espace: O(bd)
 Complétude: oui
 Optimalité: oui

Gourmande en espace et en temps!


Principe :
 Prendre en compte le coût dans la recherche en largeur
 Dans la file de priorité : chaque état est associé au coût qu’il a
fallu dépensé pour l’atteindre depuis l’état initial
 La file est triée selon le coût de chaque état (du moins coûteux
vers le plus coûteux)
 Si coût de chaque arc = 1, alors recherche à coût uniforme =
recherche en largeur d'abord
Fonction Rech_CoutU (NœudI, But) : Trouvé, Echec
Debut
Frontière  NoeudI // ajout au sommet de la file
ListeVisités  Null
Tant que (Frontière  Vide)
NoeudC  Frontière.retirer () // Au sommet
si (NoeudC.etat = But) renvoyer Trouvé
ajouter (ListeVisités , NoeudC )
Pour chaque Expansion (NoeudC ) ListeVisités
Frontière  Frontière + Expansion (NoeudC)
Fin Pour
Trier (Frontière) // Trier selon le coût croissant du chemin à partir de l’état initial
Fin tant que
renvoyer Echec
Fin
G 0

F 10 C 5
5 A
10
Nœud
initial 10 5 B 20
G A B 15 D H 20 D 10
10 10
10 5
5 H 10 F 20
D K 40 E 15
5 5 5 20
E K But
C 20
10 10 K Solution
: valeur positive très petite
b: nombre de branchements maximal de l’arbre de recherche
C*: profondeur de l’arbre de recherche

 Complexité en temps: O(bC*/)


 Complexité en espace: O(bC*/)
 Complétude: oui (si coût de chaque branche > = )
 Optimalité: oui
Principe :

 Démarrer de la racine et explorer le


premier chemin de ses successeurs
jusqu'au moment où le sommet n'a
plus de successeurs non visités.

 Ensuite remonter d'un niveau pour


vérifier s'il ne reste pas de sommets à
visiter et ainsi de suite.
Fonction Rech_Profondeur (NœudI, But) : Trouvé, Echec
Debut
Frontière  NoeudI // ajout au sommet de la file
ListeVisités  Null
Tant que (Frontière  Vide)
NoeudC  Frontière.retirer () // Au sommet
si (NoeudC.etat = But) renvoyer Trouvé
ajouter (ListeVisités , NoeudC )
Pour chaque Expansion (NoeudC)  ListeVisités
// Ajout au sommet de la pile
Frontière  Expansion (NoeudC)+Frontière
Fin Pour
Fin tant que
renvoyer Echec
Fin
G

F C
A
Nœud
initial B
G A B D H

H F
D E

C E K
But
C K Solution
Fonction Rech_Profondeur (Nœud, But) : Trouvé, Echec
Debut
si (Noeud.etat = But) renvoyer Trouvé
ajouter (ListeVisités , Noeud )
Pour chaque Expansion (Nœud) ListeVisités
Res = Rech_Profondeur (Expansion(Nœud), But)
si (Res = Trouvé) renvoyer Trouvé
Fin Pour
renvoyer Echec
Fin
b: nombre de branchements maximal de l’arbre de recherche
m: profondeur maximale de l’arbre de recherche

 Complexité en temps: O(bm)


 Complexité en espace: O(b ×m)
 Complétude: Oui
 Optimalité: Non
Principe :
 C’est une variation de l'algorithme de parcours en profondeur où
la profondeur maximale de recherche est limitée à une valeur
prédéfinie pour économiser du temps
 L'algorithme de recherche limitée peut manquer des solutions
potentielles si elles se trouvent au-delà de la profondeur limite
 C'est un compromis entre l'exhaustivité de la recherche et la
réduction des ressources utilisées.
Fonction Rech_Prof_Lim (Nœud, But, Limit) : Trouvé, Echec
Debut
if (Limit <= LimitMax)

si (Noeud.etat = But) renvoyer Trouvé

ajouter (ListeVisités , Noeud)


Pour chaque Expansion (Nœud) ListeVisités
Res = Rech_Prof_Lim (Expansion(Nœud), But, Limit+1)
si (Res = Trouvé) renvoyer Trouvé
Fin Pour

sinon
renvoyer Echec
Fin
b: nombre de branchements maximal de l’arbre de recherche
l: limite de la recherche

Complexité en temps: O(bl)


Complexité en espace: O(b ×l)
Complétude: si l>=d
Optimalité: Non
 Principe :
- C’est une variante de l'algorithme de recherche en profondeur qui effectue
plusieurs itérations avec des limites de profondeur croissantes.
- Commencer par une recherche en profondeur avec une profondeur limitée
de 1, puis augmenter progressivement la profondeur limite à chaque
itération jusqu'à ce que le nœud cible soit trouvé.

Combine les avantages du parcours en profondeur en termes d'espace et de


simplicité avec l'approche plus systématique du parcours en largeur
Fonction Rech_Prof_Iter (NœudI, But, LimitMax) : Trouvé, Echec
Début
Pour lim= 1 à LimitMax
Res = Rech_Prof_Lim (NœudI, But, lim+1)
si (Res = Trouvé) renvoyer Trouvé
Fin Pour
renvoyer Echec
Fin
b: nombre de branchements maximal de l’arbre de recherche
d: profondeur du nœud solution

Complexité en temps: O(bd)


Complexité en espace: O(b ×d)
Complétude: Oui
Optimalité: Oui
Largeur Coût Profondeur Profondeur Approff.
d’abord uniforme d’abord limitée Itératif

Temps bd bC*\ Bm Bl Bd

Espace bd bC*\ b×m b×m b×d


Complétude Oui Oui Oui Non Oui
Optimalité Oui Oui Oui Oui Oui
 La recherche informée, également appelée recherche
heuristique, utilise des informations ou des estimations
spécifiques sur le problème pour guider la recherche.
 Explore les nœuds selon une évaluation de leur qualité ou de
leur promesse.
 Algorithmes :
 Best-First search (BFS)
 A* search
 Recursive best-first search (RBFS)
 Simplified memory-bounded A* (SBA*)
Principe:

 Choisit le meilleur nœud suivant à explorer selon une fonction


d'évaluation spécifique appelée « fonction heuristique » .
 Cette fonction attribue une valeur à chaque nœud en fonction
de son potentiel à mener à la solution : h(n).
 Privilégie toujours l'exploration des nœuds avec les valeurs de
fonction heuristique les plus faibles, car cela représente la
meilleure estimation de la proximité de la solution.
Fonction Rech_BFS (NœudI, But) : Trouvé, Echec
Debut
Frontière  NoeudI // ajout au sommet de la file avec h(n)
Tant que (Frontière  Vide)
NoeudC  Frontière.retirer () // Au sommet la valeur la plus faible de h(n)
si (NoeudC.etat = But) renvoyer Trouvé
Pour chaque Expansion (NoeudC)
Frontière  Frontière + Expansion (NoeudC) // avec h(n)
Fin Pour
Trier (Frontière) // Trier selon la valeur croissante de la fonction heuristique h(n)

Fin tant que


renvoyer Echec
Fin
G (10)
(10) (10)
F C (10)
A
Nœud (10)
(10)
initial B (20)
G A D (5)

(5) (0)
H (10)
D E

(10) C E K (0)
But
(15) A K (0)
(10)
b: nombre de branchements maximal de l’arbre de recherche
m: profondeur maximale de l’arbre de recherche

 Complexité en temps: O(bm)


 Complexité en espace: O(bm)
 Complétude: Non
 Optimalité: Non
Principe:
 RBFS est un algorithme de recherche basé sur la priorité
 Gère une file de priorité (ou une liste ordonnée) de nœuds à explorer, en privilégiant
toujours le nœud le plus prometteur en fonction d'une estimation du coût f(n) jusqu'à
l'objectif tout en restant dans une approche récursive pour explorer les successeurs de
manière sélective.
 f(n) = h(n) + g(n) Coût estimé de la solution la moins couteuse à travers n
h(n) : Fonction heuristique
g(n) : Fonction coût

Permet de trouver une solution en minimisant le nombre de nœuds explorés, tout en


évitant le problème de la limitation de mémoire d'une recherche en largeur ou d'une
recherche en profondeur complète.
fonction Rech-RBFS (NoeudC, f limit , But): Trouvé, Tant que (vrai )
Echec Meilleur ←Min( Sucesseurs) // le meilleur
Début
avec f le plus bas
Si (NoeudC.etat = But) retourner Trouvé si Meilleur .f > f limit retourner (Echec)
// Générer les sucesseurs alternative ←Second-plus-Basse-f
Successeurs ←vide (Sucesseurs)
Pour chaque Succ (NoeudC) resultat f ←RBFS(Meilleur , min( f limit,
Successeurs ← Succeurs+ Succ (NoeudC)
alternative), But )
Si (Successeurs = Vide) retourner Echec Si (resultat = Succes) retourner (Trouvé)
Fin Tant que
Pour chaque s dans Successeurs Fin
s.f ←max(s.g + s.h, NoeudC.f )
Fin Pour

trier (Sucesseurs) // ordre croissant de f 37


b: nombre de branchements maximal de l’arbre de recherche
m: profondeur maximale de l’arbre de recherche

 Complexité en temps: O(bm)


 Complexité en espace: O(bm)
 Complétude: Non
 Optimalité: Non
Principe :
 Combine les avantages de la recherche meilleure d'abord (Best-First
Search) et de la recherche uniforme en coût (Uniform Cost Search).
 Utilise la fonction heuristique pour guider la recherche vers les parties les
plus prometteuses de l'espace d'état, tout en s'assurant que le coût total
du chemin parcouru jusqu'à présent est minimisé.
 f(n) = h(n) + g(n) Coût estimé de la solution la moins couteuse à travers n
 h(n) : Fonction heuristique
 g(n) : Fonction coût
Notations:

 Open-list : Liste des noeuds à explorer


 Closed-list: Liste des noeuds déjà traités (testés)
 n.g : Côut depuis le noeud initial jusqu’à n
 n.h : Valeur de la fonction heuristique pour n
 n.f = n.g+n.h
Pour chaque NoeudSucc= Expansion (NoeudC)
Algorithme Rech- A* (NoeuI, But): Echec, Si (NoeudSucc  Closed-List)
Trouvé new-g = NoeudI.g +Dist(NoeudC, NoeudSucc)
Début Si (NoeudSucc  Open-List)
NoeudI.g  0 NoeudSucc.g  new-g
NoeudI.f  NoeudI.h NoeudSucc.f  NoeudSucc.g + NoeudSucc.h
Open-List . ajouter ( NoeudI) Open-List.ajouter (NoeudSucc) // trié selon f(n)
Tant que (Opel-List Vide) sinon
Si (new-g < NoeudSucc.g)
NoeudC  Open-List.retirer () // la
NoeudSucc.g  new-g
plus faible de f(n) NoeudSucc.f  NoeudSucc.g + NoeudSucc.h
si (NoeudC.etat = But) Retourner Finsi
Trouvé Finsi
Fin Si
Fin pour
Fin Tant que
Retourner echec 41
Fin
G (10)
10
(10) (20)
F 5 C (15)
5 A
10 5
Nœud (10) 5
(10)
initial 10 5 B (20)
G A (35) B H D (15)
10 (0) 5 20 5
10 (5) 10 5
5 H 10 (25)
D B K E
5 5 5 (45)
20 (40)
E K But 10
(10) C
10 10 (0) K (25)
(10)
b: nombre de branchements maximal de l’arbre de recherche
d: profondeur du nœud solution

 Complexité en temps: O(bd)


 Complexité en espace: O(bd)
 Complétude: Oui
 Optimalité: Oui (si la fonction heuristique est admissible et
consistente et couts de mouvements positifs)
Heuristique Admissible :
 Une heuristique est dite admissible si elle ne surestime jamais
le coût réel pour atteindre l'objectif à partir d'un état donné.
 h(n) ≤ coût réel (optimal) de n à l'objectif.

Heuristique Consistente (ou Monotone) :


 Une heuristique h(n) est considérée comme consistente (ou
monotone) si elle satisfait la condition de consistance suivante
pour chaque paire de nœuds n et n‘ (successeur de n) :
h(n) ≤ coût(n, n') + h(n').
Principe :

 L'objectif de cette approche est de limiter l'utilisation de la mémoire en se


concentrant uniquement sur les nœuds dont les évaluations f sont les plus
prometteuses en termes de recherche de solutions optimales.
 Cela permet d'assurer que l'algorithme n'utilise pas de mémoire excessive
tout en continuant à avancer vers la recherche d'une solution.
 Si la taille de la liste des nœuds à étendre dépasse la limite de mémoire
prédéfinie, supprimer le ou les nœuds de la liste avec le coût total estimé
le plus élevé (coût g + coût h) pour faire de la place aux nouveaux nœuds.
Pour chaque NoeudSucc= Expansion (NoeudC)
Algorithme Rech-SBA* (NoeuI, But): Echec, si (NoeudSucc  Closed-List)
Trouvé new-g = NoeudI.g +Dist(NoeudC, NoeudSucc)
Début si (NoeudSucc  Open-List)
NoeudI.g  0 NoeudSucc.g  new-g
NoeudI.f  NoeudI.h NoeudSucc.f  NoeudSucc.g + NoeudSucc.h
Open-List . ajouter ( NoeudI) si Taille (Open-List > Lim)
Open-List.elaguer() // Enlever le nœud le plus
Tant que (Opel-List Vide) coûteux
NoeudC  Open-List.retirer () // la sinon
plus faible de f(n) si (new-g < NoeudSucc.g)
NoeudSucc.g  new-g
si (NoeudC.etat = But) renvoyer NoeudSucc.f  NoeudSucc.g + NoeudSucc.h
Trouvé Finsi
Finsi
Finsi
Fin pour
Fin Tant que
Renvoyer echec
Fin
 b: nombre de branchements maximal de l’arbre de recherche
 l: limite de la profondeur spécifiée

 Complexité en temps: O(bl)


 Complexité en espace: O(bl)
 Complétude: Non (Oui si la limite >= profondeur de la
solution)
 Optimalité: Non
BFS RBFS A* SBA*

Temps bm bm bd bl

Espace bm bm bd bl
Complétude Non Non Oui Non
Optimalité Non Non Oui* Non

* : Si la fonction heuristique est admissible et consistente et couts positifs

Vous aimerez peut-être aussi