PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 SOMMAIRE Description du projet .........................................................................................................................1 Applications .....................................................................................................................................1 Solution approchée ..........................................................................................................................2 Algorithmes génétiques .....................................................................................................................2 Grands principes et définitions ........................................................................................................2 Performances et applications ...........................................................................................................2 Et concrètement ? ............................................................................................................................3 Carte ............................................................................................................................................3 Individus ......................................................................................................................................3 Adaptation....................................................................................................................................4 Initialisation (« génèse ») ............................................................................................................4 Grandes étapes d'une itération .........................................................................................................5 Arrêt de l'algorithme....................................................................................................................5 Sélection ..........................................................................................................................................5 Croisement .......................................................................................................................................6 Mutation ...........................................................................................................................................7 Travail demandé ................................................................................................................................7 Programme .......................................................................................................................................7 Paramètres........................................................................................................................................8 Rapport ............................................................................................................................................8 Contraintes techniques ......................................................................................................................9 Soutenance ..........................................................................................................................................9 Dès maintenant ! ..............................................................................................................................9 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Description du projet Un voyageur de commerce doit visiter un certain nombre de villes (n, pour ne pas se mouiller). Il veut le faire en parcourant le moins de distance possible et sans repasser deux fois par la même ville, sauf la première (il aimerait bien rentrer chez lui à la fin!). Il faut donc trouver le bon ordre de visite de ces villes. Ce problème apparemment simple est en fait très difficile à résoudre car le nombre de possibilités est (n 1)! , donc croît très vite avec le nombre de villes. On parle d'explosion 2 combinatoire. Voici un petit aperçu de cette explosion (en comptant une micro-seconde pour l'étude d'une possibilité) : n Nombre de possibilités Temps de calcul 5 12 Micro-seconde 10 181440 Dixième de seconde 15 43 milliards Dizaine d'heures 20 60.1015 Milliers d'années 25 310.1021 Milliards d'années Notre problème : parmi autant de possibilités, comment trouver la meilleure ? Applications Dans le cas général, on ne considère pas une simple distance géographique (éloignement entre deux villes) mais un coût qui peut refléter la difficulté ou le prix de la liaison entre deux points. Ce problème trouve des applications concrètes dans l'industrie, dans la logistique bien sur (approvisionnements successifs de différents clients avec le même camion) mais aussi, par exemple, dans la fabrication des cartes électroniques complexes (optimiser les mouvements des perceuses). Le Voyageur de Commerce L1 2007/2008 1 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Solution approchée Pour des problèmes de ce type, il faut bien souvent abandonner l'idée d'avoir la « meilleure solution possible » et se contenter d'une « très bonne solution ». Dans ce projet, à partir d'un fichier contenant les coordonnées d'une série de villes, vous devrez calculer une solution acceptable à l'aide d'un algorithme un peu particulier : un algorithme génétique. Algorithmes génétiques Grands principes et définitions Les algorithmes génétiques sont inspirés de la théorie de l'évolution et des principes de la génétique. L'idée est de partir de différentes solutions possibles d'un problème et de les améliorer en les “croisant” et en en faisant “muter”. Régulièrement, les individus sont “évalués” et certains sont éliminés. On retrouve ainsi les concepts : d'individu : une solution possible du problème ; de population : tous les individus pris en compte simultanément ; de reproduction : croisement de deux individus pour en produire de nouveaux ; de mutation : modification aléatoire d'un individu ; d'adaptation à l'environnement : évaluation d'un individu par rapport à l'objectif ; de sélection naturelle : élimination aléatoire de certains individus (moins l'individu est adapté, plus il a de chances d'être éliminé). Performances et applications Tout comme l'évolution naturelle, ce type d'algorithme laisse une large place au hasard. Cette technique est étonnamment efficace. Elle permet de trouver rapidement de très bonnes solutions à des problèmes réputés difficiles, comme le voyageur de commerce. Par contre, il n'y a pas moyen de savoir si notre meilleure solution est la meilleure solution... mais on s'en passera ! Le Voyageur de Commerce L1 2007/2008 2 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Les algorithmes génétiques sont couramment utilisés dans l'industrie pour traiter des problèmes trop difficiles à résoudre par les méthodes traditionnelles. Ainsi, Dassault les a utilisés pour concevoir des ailes d'avions de combat dont l'écho radar est le plus faible possible : plus l'écho est faible, et plus l'avion est « furtif » ! Et concrètement ? Carte Un fichier « carte » sera le point de départ du programme. Ce fichier texte contient la liste des villes avec leur nom et leurs coordonnées. La première ligne du fichier contient juste un entier : le nombre de villes du fichier. Ensuite, chaque ligne décrit une ville avec trois informations séparées par des séries de tabulations (caractère '\t') : tout d'abord le nom (au plus 20 caractères), puis deux réels, l'abscisse et l'ordonnée. Individus Un algorithme génétique manipule des individus, qui sont des solutions possibles du problème à résoudre. Dans notre cas, un individu est un ordre possible pour visiter les n villes. Si on attribue à chaque ville un numéro (de 0 à n-1 par exemple), un individu est alors réduit à un tableau de n entiers. Vous aurez un ensemble d'individus à gérer simultanément (votre population), il s'agira donc d'un ensemble de tableaux de même taille. Cette population sera un tableau à deux dimensions. Remarque : le nombre de villes est variable suivant les exécutions (dépend du fichier carte), et le nombre d'individus dans la population dépend du paramétrage de l'algorithme, vous aurez donc à faire des allocations dynamiques. Le Voyageur de Commerce L1 2007/2008 3 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Adaptation L'adaptation d'un individu est donnée par la somme des distances entre les villes successives (sans oublier la distance entre la dernière et la première !). Plus cette distance est importante, moins l'individu est adapté. Ainsi, pour l'individu {0,3,1,2}, la distance du parcours est d0,3 + d3,1 + d1,2 + d2,0. Le meilleur individu de la population est, bien sur, celui qui a la distance totale la plus faible. Initialisation (« génèse ») Au départ, vous créerez des individus aléatoirement, avec la fonction rand(). Cela vous donnera la première « génération ». N'oubliez pas d'initialiser le générateur de nombres pseudo aléatoires avec la fonction srand(). Attention, chaque individu doit contenir une fois et une seule chaque ville ! Et ensuite... Croisements Mutations Sélection Bouillon de culture Effectif : X/2 Génération t Effectif : X Le Voyageur de Commerce Génération t+1 Effectif : X L1 2007/2008 4 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Grandes étapes d'une itération Une itération de l'algorithme génétique commence avec X individus. Cruelle (mais nécessaire) loi de l'évolution, la sélection réduit la population à X/2 individus. Après croisements, on obtient de nouveau X individus. Sur ces X individus, t.X subissent une mutation, le nombre d'individus reste constant. Tous les individus ont la même probabilité d'être mutés. Le paramètre 0 <t <1 est appelé taux de mutation. Après les croisements et les mutations, on obtient une nouvelle génération. Cas particulier (favoritisme) : si on n'y prend pas garde, le meilleur individu peut disparaître lors du processus de sélection ou lors de la mutation... or il serait dommage de perdre notre meilleure proposition ! Dans ce cas, il faut sacrifier un autre individu au hasard pour pouvoir sauver le favori ! Arrêt de l'algorithme L'algorithme s'arrête au bout d'un certain nombre d'itérations, fixé au départ. Sélection Il faut évaluer chaque individu de la population courante. On ne souhaite garder que la moitié des individus. Il existe deux méthodes pour faire cette sélection. Un paramètre de l'algorithme (l'élitisme) indique laquelle suivre : méthode élitiste : on ne conserve que la meilleure moitié des individus; méthode par tournoi : on choisit deux individus au hasard et on les laisse se battre... le plus adapté gagne, l'autre est supprimé. Si le hasard le veut, un individu peut participer à plusieurs tournois, et ainsi être conservé en plusieurs exemplaires ! Indication : pour la seconde méthode, si un individu est conservé plusieurs fois, il ne suffit pas d'avoir plusieurs pointeurs sur le même individu, il faut plusieurs copies du même individu. Le Voyageur de Commerce L1 2007/2008 5 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Croisement Juste après l'étape de sélection, les individus survivants sont répartis en couple aléatoirement. Chaque couple est ensuite passé à l'opérateur de croisement. L'opérateur de croisement prend en entrée deux individus et donne, en sortie, deux individus « enfants » qui reprennent des caractéristiques de leurs deux « parents ». Son action exacte est déterminée par des paramètres aléatoires. Ce croisement permet le « brassage génétique », afin d'essayer de concentrer dans le même individu les caractéristiques les plus intéressantes. Indications : dans notre cas, on appelle la fonction de croisement avec deux paramètres entiers tirés aléatoirement : la première position à faire l'objet du croisement (début, 0 ≤ i < n ) et le nombre de villes croisées (largeur, 1≤ j ≤ n-i ). La partie croisée du premier parent est injectée dans le deuxième enfant à la même position, et inversement. Cela donne deux enfants temporaires où il peut y avoir des villes en double : il faut alors remplacer les doublons par les villes manquantes, en respectant l'ordre de l'autre parent. Ainsi chaque enfant hérite de l'ordre des villes de chaque parent. Voici un exemple avec 7 villes, le croisement débute à i = 1 pour une largeur j = 3. Parents Enfants temporaires croisement Enfants {4,6,2,5,0,1,3} remplacement {4,1,4,2,0,1,3} {6,1,4,2,0,5,3} {0,1,4,2,5,3,6} {0,6,2,5,5,3,6} {0,6,2,5,1,3,4} Largeur de croisement j=3 Début de croisement i=1 Dans le premier enfant temporaire, 4 et 1 sont en double : ils sont remplacés par 6 et 5 (villes manquantes, dans l'ordre du premier parent). De même pour le second enfant pour 5 et 6. La partie croisée doit rester intacte. Cette fonction « croisement » est délicate. Pour faciliter les tests, vous devez avoir une fonction qui prend en paramètre les début et largeur de croisement. Il sera plus facile de vérifier que la fonction fait bien ce que vous voulez ! Le Voyageur de Commerce L1 2007/2008 6 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Mutation L'opérateur de mutation prend en entrée un individu et donne, en sortie, cet individu modifié d'une manière aléatoire. C'est ce qui permet d'apporter de la nouveauté à la population et d'explorer de nouvelles solutions. Dans notre cas, le plus simple est de permuter deux villes tirées au hasard. Par exemple : {0,6,2,5,1,3,4} → {0,1,2,5,6,3,4} Inversion des villes en position 1 et 4. Travail demandé Programme Vous devez réaliser un programme offrant les possibilités suivantes : charger un fichier « carte » et en stocker toutes les informations, ou indiquer si le format du fichier est incorrect ; afficher le contenu du fichier carte précédemment chargé ; paramétrer l'algorithme (voir la rubrique « Paramètres » ci-après) ; lancer l'algorithme génétique avec les paramètres courants et afficher la solution finale ; enregistrer dans un fichier la meilleure solution, sous forme d'une liste de noms de ville, après avoir laissé le choix de la ville de départ. vous pouvez également proposer un graphique (en mode texte) représentant l'évolution de l'adaptation du meilleur individu au fil des itérations, une carte avec les positions des villes, d'autres opérateurs de croisement ou de mutation... à condition que la partie obligatoire soit faite. Le Voyageur de Commerce L1 2007/2008 7 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Paramètres L'utilisateur pourra, s'il le souhaite, paramétrer l'algorithme génétique ainsi : la cardinalité de la population (X) : nombre d'individus dans la population (par exemple, 10, 50, 100...). Plus elle est élevée, plus l'algorithme sera lent, mais plus il aura de chances de trouver une bonne solution ; le taux de mutation (t) : proportion d'individus subissant une mutation à chaque itération ; l'élitisme : indique la méthode de sélection ; le nombre d'itérations. Vous devrez proposer des valeurs par défaut pour chacun de ces paramètres. Rapport Votre rapport doit introduire clairement le problème et l'algorithme utilisé. Vous expliquerez le découpage du projet en modules et la représentation interne des différentes données (distances, noms et coordonnées des villes, population...). Vous détaillerez la programmation des différentes étapes de l'algorithme génétique (sélection, croisement, mutation). Un chapitre constituera le mode d'emploi de votre logiciel et donnera des exemples d'utilisation. Un chapitre sera consacré aux tests unitaires, notamment pour : l'opérateur de mutation; l'opérateur de croisement; l'évaluation d'un individu; la lecture d'un fichier carte; le calcul des distances; la génération d'un nombre aléatoire (vérification statistique d'un grand nombre d'appels). Enfin, vous indiquerez les difficultés rencontrées et votre répartition des tâches. En annexe, vous inclurez un CD contenant les sources (non compressées), l'exécutable et un fichier carte d'exemple (15 villes minimum !). Le Voyageur de Commerce L1 2007/2008 8 PROGRAMMATION EN LANGAGE C L1 Année 2007 - 2008 Contraintes techniques utilisation des fichiers texte ; tableaux à 2 dimensions ; allocation dynamique ; structures ; fonctions; tests unitaires. Soutenance La soutenance du projet se fera en salle de TP. Vous remettrez le rapport (avec CD) lors de la soutenance. La soutenance comportera une partie “test unitaire” où l'enseignant vous demandera de présenter un programme de test en le justifiant, et de l'exécuter pour montrer son bon déroulement. Le déroulement de votre programme sera testé avec un fichier de villes fourni par l'enseignant en charge de la soutenance. Dès maintenant ! Le projet est à réaliser impérativement en binôme. Constituez vos binômes dès maintenant et informez-en vos délégués. Un TP d'avancement est programmé le 7 mai 2008. La soutenance aura lieu le 28 mai 2008. Les listes des binômes devront être communiqués à M. Flasque par les délégués au plus tard le 2 Mai 2008. Le Voyageur de Commerce L1 2007/2008 9