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