Résolution de problèmes par l`exploration

Transcription

Résolution de problèmes par l`exploration
Résolution de problèmes
par l'exploration
Jérôme Champavère
jerome.champavere @ lifl.fr
http://www.grappa.univ-lille3.fr/~champavere/?page=Enseignement
Exemples de problèmes
●
●
●
Jeu d'échecs
–
Recherche parmi un ensemble de déplacements
–
Trouver un déplacement qui améliore le positionnement
Itinéraire
–
Recherche parmi un ensemble de chemins
–
Trouver un chemin qui minimise la distance à parcourir
Preuve de théorème
–
Recherche parmi un ensemble d'étapes de raisonnement
–
Trouver un raisonnement qui permet de prouver le théorème
Terminologie
●
●
État : description du monde relativement au problème
considéré
Espace des états (ou espace de recherche) : ensemble
de tous les états possibles
●
Action : opération permettant de changer d'état
●
Chemin : séquence d'états reliés par des actions
●
●
Exploration : processus de calcul qui consiste à
déterminer une séquence d'actions permettant
d'atteindre une solution
Stratégie : choix de la prochaine action à entreprendre
dans le processus d'exploration
Résolution de problèmes
Itinéraire
●
Problème : aller de Lyon à Bordeaux
Itinéraire
●
États : être dans une ville
●
But à atteindre : être à Bordeaux
●
●
Action possible : se déplacer de ville en ville en
suivant les routes existantes
Solution : une séquence de villes-étapes qui
mènent à Bordeaux en partant de Lyon
Résoudre un problème
●
●
Formuler le problème : décider des états et des
actions à considérer étant donné un but
Explorer l'espace de recherche : déterminer
une séquence d'actions qui permet d'atteindre
le but
Bien formuler
●
Problème : l'échiquier écorné
Définition d'un problème
●
●
État initial : ÊtreÀ(Lyon)
Description des actions possibles avec une ensemble d'opérateurs pouvant
être appliqués à un état pour générer des successeurs
–
–
–
–
–
●
●
Nord(ÊtreÀ(Lyon)) = ÊtreÀ(Dijon)
SudEst(ÊtreÀ(Lyon)) = ÊtreÀ(Grenoble)
Sud(ÊtreÀ(Lyon)) = ÊtreÀ(Marseille)
SudOuest(ÊtreÀ(Lyon)) = ÊtreÀ(Montpellier)
Ouest(ÊtreÀ(Lyon)) = ÊtreÀ(Clermont-Ferrand)
Test de but qui détermine si le but est atteint : ÊtreÀ(Bordeaux)
Fonction de coût de chemin qui assigne un valeur numérique (non négative)
à chaque chemin selon les actions réalisées, correspondant à la somme
des coûts des actions individuelles le long du chemin, appelés coûts d'étape
Solution d'un problème
●
Chemin qui part de l'état initial pour mener à un
état final correspondant au but
–
–
●
[ÊtreÀ(Lyon) ; ÊtreÀ(Clermont-Ferrand) ;
ÊtreÀ(Limoges) ; ÊtreÀ(Bordeaux)]
[ÊtreÀ(Lyon) ; ÊtreÀ(Montpellier) ; ÊtreÀ(Toulouse) ;
ÊtreÀ(Bordeaux)]
Solution optimale : celle qui a le coût de chemin
minimal parmi toutes les solutions
Niveau d'abstraction
●
Supprimer des détails de la représentation
–
–
●
●
On laisse tomber le paysage, la météo, la radio, …
On conserve le minimum nécessaire pour la
résolution du problème d'aller de Lyon à Bordeaux
Abstraire également les actions
Abstraction valide si on peut projeter la solution
dans le monde réel, utile si elle simplifie la
réalisation des actions de la solution
Environnement de résolution
●
●
●
●
Statique : la formulation et la résolution du problème
ne tiennent pas compte de modifications susceptibles
de survenir dans l'environnement
Observable : l'état initial et l'effet de toutes les actions
sont connus
Discret : il est possible d'énumérer les actions
alternatives étant donné un état
Déterministe : les solutions aux problèmes se
présentent sous la forme de séquences uniques
d'actions
Exemples de problèmes
—
Problèmes jouets et
problèmes du monde réel
Jeu de taquin à 8 pièces
Configuration initiale
Configuration finale
Jeu de taquin à 8 pièces
●
●
●
●
●
●
État : emplacement des huit pièces et de la case
vide
État initial : n'importe quel état
Actions : déplacement de la case vide (haut, bas,
gauche, droite)
But : l'état correspond à la configuration finale
Coût du chemin : chaque action coûte 1, donc
nombre d'étapes qui composent le chemin
Abstraction : on ne représente pas les détails relatifs
aux manipulations physiques
Les 8 dames
Disposition inappropriée
Solution
Les 8 dames
●
●
Formulation incrémentale
–
État : toute disposition de 0 à 8 dames sur l'échiquier
–
État initial : pas de dame sur l'échiquier
–
Action : poser une dame sur l'une des cases vides
–
But : huit dames sur l'échiquier et aucune menacée
Optimisation
–
–
●
État : disposition de n dames (0 ≤ n ≤ 8), une par colonne à partir de la
gauche des n colonnes occupées, sans qu'aucune dame n'en menace
une autre
Action : poser une dame sur une case appartenant à la colonne la plus
à gauche sans que celle-ci ne soit menacée
Formulation complète : 8 dames sur l'échiquier et déplacement
de celles-ci
Problèmes du monde réel
●
Recherche d'un trajet
–
Routage dans les réseaux informatiques
–
Systèmes de synchronisation dans les transports en commun
–
Navigation d'un robot
●
Itinéraires touristiques
●
Voyageur de commerce
●
Agencement de VLSI
●
Ordonnancement automatique de l'assemblage d'objets
complexes
●
Conception de protéines de synthèse
●
Recherches Internet
Recherche de solutions
—
Arbre de recherche
Arbre de recherche
Lyon
Dijon
Strasbourg
Lyon
Grenoble
Paris
Marseille
Montpellier
Clermont
Arbre de recherche
Lyon
Dijon
Strasbourg
Lyon
Grenoble
Paris
Marseille
Montpellier
Clermont
Arbre de recherche
Lyon
Dijon
Strasbourg
Lyon
Grenoble
Paris
Marseille
Montpellier
Clermont
Arbre de recherche
●
●
●
●
Racine de l'arbre : nœud de recherche
correspondant à l'état initial
Développer l'état courant en appliquant toutes
les actions possibles : génère un nouvel
ensemble d'états
Stratégie d'exploration pour choisir l'état à
développer
Distinction arbre de recherche / espace des
états
Nœud de recherche
●
Structure de données
–
–
–
–
–
●
●
État : l'état de l'espace des états auquel le nœud correspond
Nœud parent : le nœud de l'arbre de recherche qui a généré ce nœud
Action : l'action qui a été appliquée au parent pour générer le nœud
Coût du chemin : le coût g(n) du chemin depuis l'état initial jusqu'au
nœud
Profondeur : le nombre d'étapes que compte le chemin depuis l'état
initial
Distinction nœud / état
Frontière : collection des nœuds feuilles générés mais non encore
développés
Nœud de recherche
Nœud
parent
Nœud
ÊtreÀ(Dijon)
État
Action = Nord
Profondeur = 1
Coût de chemin = 194
Notion de frontière
Lyon
Dijon
Strasbourg
Lyon
Grenoble
Paris
Marseille
Montpellier
Clermont
Algorithme général d'exploration
Entrées : un problème et une stratégie
Sortie
: une solution, ou échec
initialiser l'arbre de recherche avec l'état initial du problème
itérer
si il n'y a pas de candidat à développer alors
retourner échec
choisir un nœud à développer en appliquant la stratégie
si le nœud contient un état final alors
retourner la solution qui correspond
sinon
développer le nœud
ajouter les nœuds du résultat dans l'arbre de recherche
Mesure de performance
●
●
●
●
Complétude : est-ce que l'algorithme garantit
d'obtenir une solution lorsqu'il en existe une ?
Optimalité : est-ce que la stratégie trouve la
solution optimale ?
Complexité en temps : quelle est la durée pour
l'obtention d'une solution ?
Complexité en espace : de combien de
mémoire faut-il disposer pour effectuer
l'exploration ?
Complexité
●
Quantités à prendre en compte
–
–
–
●
●
b : facteur de branchement (nombre maximal de
successeurs d'un nœud donné)
d : profondeur du nœud but le moins éloigné
m : longueur maximale d'un chemin dans l'espace
des états (possiblement infinie)
Temps exprimé par rapport au nombre de
nœuds générés pendant l'exploration
Espace : nombre maximal de nœuds conservés
en mémoire
Stratégies d'exploration
●
Choix d'un ordre pour développer les nœuds
●
Exploration non informée (ou aveugle)
–
–
●
Pas d'information sur les états
Générer des successeurs et distinguer état final /
non final
Exploration informée (ou heuristique)
–
Déterminer si un état non final est « plus
prometteur » qu'un autre
Stratégies d'exploration
non informée
Stratégies d'exploration
non informée
●
Exploration en largeur d'abord
●
Exploration à coût uniforme
●
Exploration en profondeur d'abord
●
Exploration en profondeur limitée
●
Exploration itérative en profondeur
●
Exploration bidirectionnelle
Exploration en largeur d'abord
●
●
Développement de tous les nœuds au niveau n
avant ceux du niveau n+1
Frontière implémentée par une file FIFO (firstin-first-out)
Exploration en largeur d'abord
A
A
B
D
C
E
F
B
G
D
C
E
A
C
E
G
A
B
D
F
F
B
G
D
C
E
F
G
Exploration en largeur d'abord
●
Complétude : oui (si b est fini)
●
Optimalité : pas nécessairement
●
d
Complexité en temps et en espace : O(b )
Profondeur Nœuds
Temps
Mémoire
1 téraoctet
8
10⁹
31 heures
12
10¹³
35 ans
10 pétaoctets
Exploration à coût uniforme
●
●
●
Développement du nœud qui a le coût de
chemin le plus faible
File triée par coût croissant
Équivalent à l'exploration en largeur d'abord si
tous les coûts d'étape sont égaux
Exploration à coût uniforme
A
1
10
5
S
B
15
5
G
5
C
Exploration à coût uniforme
A
1
10
5
S
A,1
B
5
G
S,0
1
15
5
C
Contenu de la file
2
B,5
3
C,15
Étape
# nœuds
développés
[(S,0)]
Développe (S,0)
[(A,1);(B,5);(C,15)]
Développe (A,1)
1
[(B,5);(G,11);(C,15)]
Développe (B,5)
2
[(G,10);(G,11);(C,15)]
Ø
Développe (G,10)
G,11
3
4
G,10
4
Exploration à coût uniforme
●
●
●
Complétude : oui, si le coût de chaque étape
est ≥ à une constante positive ε
Optimalité : oui, car les nœuds sont développés
dans l'ordre du coût croissant de leur chemin
⌈ C * / ⌉
Complexité en temps et en espace : Ob
(où C* est le coût de la solution optimale)

Exploration en profondeur d'abord
●
●
●
Développement du nœud le plus profond de la
frontière de l'arbre de recherche
Frontière implémentée par une pile (ou file)
LIFO (last-in-first-out)
Alternative : fonction récursive
Exploration en profondeur d'abord
A
A
B
D
C
E
F
B
G
D
C
E
A
C
E
G
A
B
D
F
F
B
G
D
C
E
F
G
Exploration en profondeur d'abord
●
Complétude : non (chemin possiblement infini)
●
Optimalité : non
●
Complexité en espace
●
–
O(bm)
–
O(m) avec backtracking
m
Complexité en temps : O(b )
Exploration en profondeur limitée
●
Limite de profondeur l
●
Nœuds à la profondeur l non développés
●
Résout le problème du chemin infini
●
Équivalent à profondeur d'abord si l = ∞
function DLS(problème,limite)
nœud ← CRÉÉR-NŒUD-ÉTAT-INITIAL(problème)
return DLS-REC(nœud,problème,limite)
function DLS-REC(nœud,problème,limite)
interruption_survenue ← false
if TEST-ÉTAT-FINAL(problème,ÉTAT(nœud)) then
return SOLUTION(nœud)
else
if PROFONDEUR(nœud) = limite then
return interruption
else
foreach successeur in DÉVELOPPER(nœud,problème) do
résultat ← DLS-REC(successeur,problème,limite)
if résultat = interruption then
interruption_survenue ← true
else
if résultat ≠ échec then
return résultat
if interruption_survenue else
return interruption
else
return échec
Exploration en profondeur limitée
●
Complétude : non (cas l < d)
●
Optimalité : non
●
Complexité en espace : O(bl)
●
l
Complexité en temps : O(b )
Exploration itérative en profondeur
●
●
●
Variante itérative de l'exploration en profondeur
limitée
Augmentation graduelle de la limite jusqu'à
atteindre un nœud but
Nœud but atteint lorsque la profondeur limite
vaut d (profondeur du nœud but le moins
profond)
Exploration itérative en profondeur
Limite = 0
A
A
A
A
Limite = 1
B
C
A
B
C
A
B
C
B
C
Limite = 2
A
A
B
D
C
E
F
A
B
G
D
C
E
F
A
B
G
D
C
E
F
B
G
D
C
E
F
G
Exploration itérative en profondeur
function IDS(problème)
for profondeur = 0 to ∞ do
résultat ← DLS(problème,profondeur)
if résultat ≠ interruption then
return résultat
Exploration itérative en profondeur
●
●
Complétude : oui (si b est fini)
Optimalité : oui (si toutes les étapes ont le
même coût)
●
Complexité en espace : O(bd)
●
Complexité en temps : O(bd)
–
–
Nombre de nœuds générés par IDS (b=10 et d=5) :
50+400+3000+20000+100000=123450
Nombre de nœuds générés par largeur d'abord :
10+100+1000+10000+100000+999990=1111100
Exploration bidirectionnelle
●
●
Exécution de deux explorations simultanées
–
En aval depuis l'état initial
–
En amont à partir du but
Arrêt lorsque les deux explorations se
rencontrent au milieu
S
G
Exploration bidirectionnelle
S
G
Exploration bidirectionnelle
●
Complétude et optimalité : oui pour des coûts
d'étapes uniformes et si les deux explorations
sont en largeur d'abord
●
Complexité en temps et en espace : O(bd/2)
●
Nombre de nœuds générés pour d=6 et b=10
–
Exploration bidirectionnelle : 22 000
–
Exploration en largeur standard : 11 111 100
Comparaison des stratégies
d'exploration non informée
Critère
Largeur
Coût
d'abord uniforme
Profondeur
d'abord
Profondeur
limitée
Itérative en Bidirectionnelle
profondeur (si applicable)
oui1
oui1,2
non
non
oui1
oui1,4
Temps
O(bd)
Ob⌈ C * / ⌉
O(bm)
O(bl)
O(bd)
O(bd/2 )
Espace
O(bd)
Ob⌈ C * / ⌉
oui
O(bm)
O(bl)
O(bd)
O(bd/2 )
non
non
oui3
oui3,4
Complète
Optimale
oui3
b : facteur de branchement
d : profondeur de la solution la moins profonde
m : profondeur maximale de l'arbre de recherche
l : profondeur limite
¹ si b est fini
² si les coûts des étapes sont ≥ ε avec ε positif
³ si les coûts d'étapes sont tous identiques
⁴ si les deux directions utilisent un exploration en largeur d'abord
Éviter les répétitions d'états
Répétition d'états
●
●
Possibilité de perdre du temps à développer
des états déjà rencontrés et développés
Parfois inévitable (actions réversibles)
●
Grille rectangulaire : chaque état a 4 successeurs
●
L'arbre de recherche a 4d feuilles, états répétés compris
●
Pour un état donné, ≈2d2 états distincts en d étapes
●
Pour d=20, 109 nœuds mais seulement 800 états distincts !
Algorithme d'exploration en graphe
function GRAPH-SEARCH(problème)
nœuds_fermés ← Ø
nœuds_ouverts ← {CRÉÉR-NŒUD-ÉTAT-INITIAL(problème)}
loop
if VIDE(nœuds_ouverts) then
return échec
nœud ← CHOISIR(nœuds_ouverts)
if TEST-ÉTAT-FINAL(problème,ÉTAT(nœud)) then
return SOLUTION(nœud)
if nœud ∉ nœuds_fermés then
nœuds_fermés ← nœuds_fermés ∪ {nœud}
nœuds_ouverts ← nœuds_ouverts ∪
DÉVELOPPER(nœud,problème)
Stratégies d'exploration en graphe
●
●
Exploration en largeur d'abord
–
Optimalité avec des coûts d'étape constants
–
Optimalité avec une exploration à coût uniforme
Exploration en profondeur d'abord
–
–
Besoins en mémoire non linéaires
Optimalité avec une exploration itérative en
profondeur si le meilleur chemin est mis à jour
Exercices
Les missionnaires et les cannibales
●
Trois missionnaires et trois cannibales sont du même côté d'une rivière, à côté d'un
bateau qui ne peut contenir qu'une ou deux personnes. Trouvez un moyen pour que
tout le monde se retrouve sur l'autre rive sans que le nombre de missionnaires à un
endroit donné ne soit jamais inférieur au nombre de cannibales au même endroit.
–
–
–
Formulez précisément le problème en ne fournissant que les éléments nécessaires pour
garantir une solution valide. Tracez un diagramme complet de l'espace des états.
Implémentez et résolvez le problème de manière optimale en utilisant un algorithme
d'exploration approprié. Est-ce une bonne idée de détecter les répétitions d'états ?
Selon vous, étant donné la simplicité de l'espace des états, pourquoi la résolution de ce
problème a-t-elle posé tant de difficultés ?
Distance entre deux pages Web
●
●
Écrivez un programme qui prend en entrée les
URL de deux pages Web et qui retourne un
chemin composé de liens permettant d'aller de
l'une à l'autre. Quelle est la stratégie
d'exploration appropriée ? L'exploration
bidirectionnelle est-elle une bonne idée ?
Pourrait-on utiliser un moteur de recherche
pour implémenter une fonction successeur ?
Sur le même thème, voir :
Six Degrees of Wikipedia