INF431 - Départements

Transcription

INF431 - Départements
INF431
Révisions
Sujet proposé par Renaud Keriven
Version: 109:488M
1
1.1
Approfondissement itératif, exploration guidée et jeu de taquin
Préambule
Le jeu de taquin est constitué d’un plateau carré, subdivisé en seize cases, sur lequel on pose quinze
pièces carrées numérotées de un à quinze. Il reste donc une case libre ou trou. Le seul mouvement ou
coup autorisé consiste à faire glisser l’une des pièces adjacentes au trou vers celui-ci, ce qui revient à
échanger leurs positions respectives. Une fois le jeu mélangé, il s’agit de rétablir la position de départ.
De façon abstraite, on peut voir l’espace des configurations du jeu de taquin comme un graphe où
chaque sommet représente une configuration et où les successeurs d’un sommet sont les configurations
obtenues grâce à un coup quelconque. Chaque sommet a donc deux, trois ou quatre successeurs. Le jeu
consiste alors à trouver un chemin à travers ce graphe entre un sommet de départ et un sommet d’arrivée
fixés.
La difficulté, d’un point de vue algorithmique, réside dans la grande taille du graphe. Le nombre
de configurations possibles, donc le nombre de sommets du graphe, est de 16!, c’est-à-dire environ
2.1013 . On démontre mathématiquement [1] que le graphe est divisé en deux composantes connexes,
dont le nombre de sommets est donc de l’ordre de 1013 . Il est clair qu’un tel graphe ne peut être logé
entièrement dans la mémoire vive d’une machine actuelle. Par conséquent, un algorithme de recherche
de plus courts chemins classique sera inutilisable du fait de sa complexité en espace. Comment faire ?
1.2
Modèle et premières solutions
Pour généraliser la présentation du problème, on se place dans le cadre suivant.
Soient : (i) S un ensemble fini d’états s ; (ii) O un ensemble d’opérations o permettant de passer
de certains états à certains autres ; (iii) Os ⊆ O l’ensemble des opérations applicables en un état s ;
(iv) un état initial s0 ∈ S et un ensemble S1 ⊆ S d’états cibles. On écrit s0 = o(s) si l’on passe de
s à s0 en appliquant o ∈ Os . Soit seq = (o1 , . . . , on ) une séquence d’opérations, on écrit s0 = seq(s)
pour s0 = (on ◦ · · · ◦ o1 )(s) avec par convention l’identité pour la séquence vide. Une telle séquence
est dite valide pour s0 si on a bien oi ∈ O(o1 ,...,oi1 )(s0 ) pour tout 1 ≤ i ≤ n. On appelle problème la
recherche d’une séquence d’opérations permettant de passer de l’état initial à l’un des états cibles. Une
telle séquence est appelée solution du problème. Elle est dite optimale si elle est de longueur minimale.
On appelle facteur de branchement la quantité b définie comme étant le cardinal maximal des ensembles Os . (En toute rigueur, les cardinaux des ensembles Os sont des variables aléatoires indépendantes et identiquement distribuées de moyenne b.) On note d la longueur des solutions optimales. Un
algorithme de recherche, ou simplement une recherche, est un algorithme qui fournit une solution au
problème. Un algorithme de recherche est dit complet s’il retourne une valeur quand d est finie, c’està-dire quand il existe bien une séquence d’opérations menant à la cible1 . Il est dit optimal si la solution
retournée est optimale. Dans toute la suite, on suppose évidemment que S est trop grand pour être mémorisé. On s’interdit même de marquer les états s rencontrés, que ce soit directement sur le graphe
1 On raconte que l’inventeur du taquin avait promis 1000$ à qui résoudrait son casse-tête en partant de la configuration qu’il
proposait... et qu’il avait volontairement choisie dans la mauvaise composante connexe ! Vous pouvez faire la même chose aujourd’hui en retournant une pièce d’un Rubik’s Cube – 12 composantes connexes – avant de le mélanger et de le soumettre à la
sagacité de votre petit neveu qui vient d’apprendre les formules par coeur.
1
puisqu’il n’est pas mémorisé, ou indirectement avec une table de hachage, partant du principe que les
états sont plus coûteux à mémoriser que les séquences d’opérations pour les problèmes considérés.
On commence par étudier quelques algorithmes bien connus. Le premier d’entre eux sera la recherche en largeur d’abord.
Question 1 Ecrivez le pseudo-code BFS(s0 , S1 ) d’une recherche inspirée d’un parcours de graphe en
largeur d’abord et dont vous choisirez le type de retour. Est-elle complète ? Optimale ? Quelle en est la
complexité asymptotique en espace quand d tend vers l’infini ? Et en temps ? Commentez.
On suppose pour la question suivante que d est finie et connue et l’on envisage une recherche en
profondeur d’abord.
Question 2 Ecrivez le pseudo-code DFS(s0 , S1 , d) d’une recherche inspirée d’un parcours de graphe
en profondeur d’abord. Est-elle complète ? Optimale ? Quel en est la complexité en espace ? Et en
temps ? Conclusion ?
On ne suppose désormais plus que d est connue.
Question 3 Pourquoi ne peut-on pas utiliser DFS(s0 , S1 , dmax ) avec un majorant dmax de d ? Proposez alors une solution, quitte à être moins efficace en temps. Ecrivez son pseudo-code IDFS(s0 , S1 ).
Montrez complétude et optimalité. Précisez ses complexités.
Dans le cas où la cible S1 est un singleton {s1 } (taquin, Rubik’s Cube, etc.), il existe une astuce
pour ramener la complexité en temps à O(bd/2 ).
Question 4 La voyez-vous ? Décrivez-en le principe. Que devient la complexité en espace ? Est-on
toujours dans le cadre fixé ?
1.3
Exploration guidée : algorithme A?
La complexité en temps de IDFS étant en réalité trop élevée, même pour un jeu comme le taquin,
on cherche à améliorer l’efficacité de la recherche. Pour cela, on s’intéresse, de façon indépendante
dans cette section, à l’utilisation d’heuristiques. Formellement, une heuristique est simplement une
fonction sur S à valeurs entières. Le rôle d’une heuristique est d’être une bonne estimation du nombre
minimum d’opérations séparant un état donné des états cibles S1 . On parle alors de recherche guidée.
Pour appréhender les choses plus concrètement, on considère le problème sous un jour différent : (i) les
états sont des villes ; (ii) les opérations sont des directions à prendre pour rejoindre les villes voisines ;
(iii) on attribue un coût strictement positif à chaque opération, qui sera ici la distance à parcourir pour
passer de la ville courante à sa voisine ; et (iv) on recherche maintenant la séquence d’opérations de
moindre coût et non plus de moindre cardinal. Il s’agit donc désormais de trouver le plus court chemin
d’une ville à un ensemble de villes cibles, en conservant les contraintes précédentes, notamment qu’on
ne peut pas mémoriser le graphe mais seulement des séquences d’opérations. Cela revient à voyager
vers des villes cibles sans carte, sans mémoire des villes traversées, et avec juste dans chaque ville :
(i) l’information des distances aux villes voisines et (ii) une estimation des distances aux villes cibles.
Cette analogie contient bien entendu comme cas particulier ce qui a été vu jusqu’ici en fixant toutes les
distances à 1.
Question 5 Une heuristique h(s) sera dite admissible si elle sous-estime le coût minimal h? (s) restant
jusqu’à la cible, c’est-à-dire si h(s) ≤ h? (s) . Donnez une heuristique admissible dans le cas des villes.
L’utilisation la plus simple d’une heuristique consiste à utiliser l’algorithme BFS en remplaçant la
file F par une file de priorité, et à choisir systématiquement d’explorer une séquence seq qui minimise
h(seq(s0 )). On espère ainsi trouver plus rapidement une solution.
Question 6 Pourquoi procéder ainsi n’est-il pas une bonne idée ?
Au contraire, l’algorithme A? propose une utilisation correcte de l’heuristique. On parle de choix du
meilleur d’abord ou best-first search. L’idée est la suivante : on conserve le principe d’utiliser BFS avec
une file de priorité, pour explorer en premier non plus une séquence de moindre heuristique, mais une
séquence seq qui minimise f (seq) = g(seq) + h(seq(s0 )), où g(seq) est le coût de seq.
2
Question 7 Montrez que, si h est admissible, alors l’algorithme A? est complet et optimal.
En théorie, rien n’assure que A? se comporte mieux que BFS, mais en pratique il est souvent beaucoup plus efficace. Une façon de voir les choses est la suivante : la recherche se propage par contours
à f constant. Dans le cas de BSF (h = 0), ces contours sont des cercles. Avec A? , ils se déforment en
directions des éléments de S1 . Cette efficacité en temps s’accompagne aussi d’une efficacité en espace,
la file étant réduite, puisque toutes les séquences d’une longueur donnée ne sont plus explorés.
Question 8 Dans le cas du taquin, donnez deux heuristiques admissibles. Quelle est la meilleure ?
1.4
Combinaison : IDA?
Si A? suffit pour le taquin, il n’en va pas de même pour le Rubik’s Cube par exemple. L’algorithme
IDA? [2] mixe les idées de IDFS et de A? .
Question 9 Comment procède-t’il à votre avis ? (On ne demande pas de preuve d’optimalité).
Question 10 Si f possède une certaine propriété, alors IDA? se révèle inefficace. Trouvez laquelle.
Qu’en concluez-vous pour chacun des problèmes rencontrés ?
Question 11 Enfin, quel reste à votre avis la principale perte de temps de toutes les méthodes rencontrées ? Voyez vous une solution ?
2
Numéroter les composantes connexes
Soit G = (S, A) un graphe orienté de sommets S et d’arcs A. On note a → b s’il existe un arc
de a vers b et a →∗ b s’il existe un chemin de a à b. On appellera composante (faiblement) connexe
de G une composante connexe du graphe non orienté sous-jacent à G. L’objectif est de numéroter les
composantes connexes, c’est-à-dire de créer une table numéro[] indexée par les sommets, telle que
numéro[a] = numéro[b] si et seulement si a et b sont dans la même composante.
Question 12 Dans un graphe non orienté, donner une solution une solution de complexité linéaire visà-vis de la taille du graphe.
Question 13 Même question pour un graphe orienté.
Graphe de fonction Soit f une fonction d’un ensemble S vers lui-même. Par définition, le graphe de
f contient exactement les arêtes x → y telles que y = f (x). Par exemple, le graphe suivant possède 2
composantes connexes :
3l
H
H
?
0l
2l
8l- 7l 5l
*
H
H
9l
H
H
l
l
6
1
I
* @
H
@ 4l
H
x
f (x)
0
5
1
6
2
0
3
0
4
1
5
7
6
1
7
5
8
7
9
1
Le graphe d’une fonction possède la propriété suivante : pour tous a, b appartenant à la même composante connexe, il existe un sommet c tel que a →∗ c et b →∗ c.
Question 14 Démontrer cette propriété.
Question 15 On suppose l’ensemble S fini. En utilisant la propriété précédente, donner un algorithme
pour numéroter les composantes, dont la complexité est linéaire vis-à-vis de la taille du graphe.
3
Références
[1] Aaron F. Archer. A modern treatment of the 15 puzzle. American Mathematical Monthly, 106:793–
799, novembre 1999.
[2] Richard E. Korf. Iterative-Deepening-A* : An Optimal Admissible Tree Search. In IJCAI, pages
1034–1036, 1985.
4