Vous êtes sur la page 1sur 71

RAPPORT FINAL DE PROJET PARCOURS OPTIMAL DE GRAPHE

REALISE PAR JULIEN LAFONT ET JULIEN TENDERO SOUS LA DIRECTION DE M. ALAIN JOUBERT

ANNEE UNIVERSITAIRE 2008-2009

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Rapport de projet

Page 2 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

REMERCIEMENTS
Nous remercions notre tuteur de projet M. Joubert pour son aide et ses conseils qui nous ont permis d'avancer positivement tout au long de l'laboration de notre application. Les runions rgulires ont effectivement t trs bnfiques pour la conduite de ce projet. Nous remercions galement nos professeurs d'expression-communication qui nous ont guids pour l'laboration du rapport final de projet. Nous remercions enfin nos professeurs en informatiques grce qui nous avons acquis de nouvelles comptences en programmation objet, dveloppement java ; comptences indispensables lors de la conception de ce projet.

Rapport de projet

Page 3 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

SOMMAIRE
Glossaire ....................................................................................................................................................... 5 Introduction.................................................................................................................................................... 7 1) tude et analyse du projet ......................................................................................................................... 8 1.1 Objectifs initiaux ................................................................................................................................... 8 1.2. Analyse UML ....................................................................................................................................... 8 1.3 Approche ergonomique ..................................................................................................................... 12 2) organisation du projet ............................................................................................................................ 115 2.1 Organisation du travail ....................................................................................................................... 15 2.1 Choix des outils de travail .................................................................................................................. 16 3) Prsentation des algorithmes tudis ...................................................................................................... 17 3.1 Algorithme de Dijkstra ........................................................................................................................ 17 3.2. Algorithme de Bellmann-Ford ............................................................................................................ 23 3.3 Algorithme Brute-Force ...................................................................................................................... 27 3.4. Performances des diffrents algorithmes .......................................................................................... 32 4) Mise en pratique de la programmation..................................................................................................... 35 4.1 Difficultes rencontrees ........................................................................................................................ 35 4.2 Initiative et choix stratgiques ............................................................................................................ 38 5) Rsultats ................................................................................................................................................. 39 5.1 Adquation avec les objectifs initiaux ................................................................................................ 39 5.2 Discussion et amliorations possibles ............................................................................................... 39 Conclusion................................................................................................................................................... 40 Annexes ...................................................................................................................................................... 41 1. 2. 3. Webographie .................................................................................................................................... 41 Analyse UML Complte .................................................................................................................... 42 Code source des algorithmes............................................................................................................ 52

4. captures dcran ................................................................................................................................... 64 5. Fiches de Benchmark .......................................................................................................................... 70 Rapport de projet Page 4 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

GLOSSAIRE
JAVA
Le langage Java est un langage de programmation informatique orient objet, cr par James Gosling et Patrick Naughton employs de Sun Microsystems prsent en 1995 Le langage Java a la particularit dtre multi-plateforme, c'est--dire que les logiciels dvelopps sous ce langage sont utilisables sur plusieurs systmes d'exploitation tels que Microsoft Windows, Mac OS, Linux ainsi que sur plusieurs appareils mobiles.

GRAPHES
GRAPHE SIMPLE ORIENTE Un graphe simple orient G est un couple (S, A), o : S est un ensemble dont les lments sont les sommets ; A est un ensemble de couples (ordonns) de sommets, appels artes.

Pour le graphe de la figure 2 reprsent ci-dessous, on aurait S={1,2,3,4,5} et A={(1,2),(2,3),(3,1),(2,5),(4,5),(5,5)} GRAPHE SIMPLE NON-ORIENTE Un graphe simple non-orient G est un couple (S, A), o : S est un ensemble dont les lments sont les sommets ; A est un ensemble de paires (non ordonnes) de sommets, appeles artes.

MULTIGRAPHE On parle de multi-graphe ou p-graphe quand au plus p artes peuvent relier deux sommets.

Buy SmartDraw!- pu document wit Visit www.smartdraw.c

Rapport de projet

Page 5 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

GRAPHE VALUE: Un graphe est valu si toute arte est associe une valeur (par exemple : un poids, un cot, une distance, ...).

PARCOURS
Un parcours de sommets dans un graphe G est une liste ordonne de sommets de G telle que 2 sommets conscutifs dans la liste sont adjacents dans le graphe. Dans cet exemple, le parcours reprsent par les arrtes en rouge est caractris par la liste de sommets S={6, 4, 5, 1, 2}

Buy SmartDraw!- purchased copies prin document without a watermark . Visit www.smartdraw.com or call 1-800-76

BENCHMARK:
Un test de performance ou benchmark est un test dont l'objectif est de dterminer la performance d'un systme informatique.

L'acception la plus courante de ce terme est celle dans laquelle ces tests vont avoir pour objectif de mesurer les temps de rponse d'un systme en fonction de sa sollicitation. Cette dfinition est trs proche Buy SmartDraw!- purchased copies print de celle de test de charge o l'on mesure le comportement d'un systme en fonction de la charge without a watermark . th document Visit www.smartdraw.com or call 1-800-768-3 d'utilisateurs simultans.

PATHFINDING:
Mot anglais signifiant littralement "Trouver son chemin". Le "pathfinding" dsigne la capacit d'un personnage se dplacer dans l'environnement du monde virtuel d'un point un autre, en vitant les obstacles.

Rapport de projet

Page 6 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

THREAD:
Un thread est une partie des instructions du processus en cours d'excution. Un processus peut contenir un ou plusieurs thread (applications dites multi-threades) s'excutant en quasisimultanit ou simultanment sur les processeurs multi-curs. A la diffrence des processus, les threads partage le mme espace mmoire protg, les mmes ressources et le mme espace mmoire. L'environnement de la JVM ( Machine Virtuelle Java ) est compatible multi-thread. En effet, si votre processeur contient plusieurs curs, un vritable multi-threading sera appliqu, dans le cas contraire il sera simplement mul ( la JVM assigne alternativement la cpu aux diffrents threads )

INTRODUCTION
Dans le cadre de notre projet de seconde anne dIUT, il nous a fallu dvelopper une application permettant didentifier le parcours optimal entre deux sommets dun graphe. cette fin, nous avons tout dabord ralis une application permettant de reprsenter un graphe laide doutils graphiques. Par la suite, nous avons dvelopp le logiciel Simulation de trajet permettant de dterminer le parcours le plus court entre deux points dun plan, et ce, laide de diffrents algorithmes mathmatiques (Dijkstra, Ford-Bellmann, Brute-Force). Enfin, grce aux tests de performance (benchmark) effectus avec le simulateur, nous avons pu dterminer quels sont les algorithmes les plus aptes rpondre au problme. Dans un premier temps, nous prsenterons l'analyse du projet, les objectifs et le cahier des charges initial. Ensuite, nous dfinirons les mthodes mises en place au sein de notre binme pour tirer le meilleur de chacun, et optimiser nos techniques de travail. L'aspect algorithmique sera par la suite abord, avec une analyse dtaille des trois algorithmes intgrs au simulateur. Nous analyserons ensuite les performances de ces diffrentes mthodes de recherche du parcours optimal en les soumettant plusieurs jeux d'essais. Enfin, nous discuterons de l'adquation des objectifs initiaux avec les rsultats obtenus, ainsi que des diffrentes amliorations possibles.

Rapport de projet

Page 7 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

1) TUDE ET ANALYSE DU PROJET


1.1 OBJECTIFS INITIAUX
L'objectif initial de notre projet consistait concevoir une application permettant de dterminer le parcours optimal entre deux sommets d'un graphe. Plusieurs critres pourront tre utiliss pour dfinir la qualit optimale du parcours : il pourra sagir du nombre minimal de sommets traverss, la distance minimale du parcours ( arcs pondrs ), le temps minimum pour rejoindre un sommet, ou mme plusieurs critres cumuls. De plus, plusieurs types de graphes pourront tre tudis, avec ventuellement une gestion des multigraphes. Nous pourrions ainsi modliser une carte routire avec ses diffrents types de routes. Le point capital dans la ralisation de ce projet concerne la partie algorithmique. Notre logiciel devra implmenter un ou plusieurs algorithmes capables de rpondre la problmatique, en optimisant au maximum leurs performances. La fiabilit et l'obligation de rsultat sont videmment des critres indispensables. En outre, il serait intressant de proposer un outil permettant de comparer la puissance des diffrents algorithmes. Enfin, il sera ncessaire de concevoir une application permettant de crer ou de modifier un graph e l'aide d'un diteur graphique. Tout comme le simulateur, cette application devra proposer une interface simple et intuitive, ainsi qu'une aide interactive pour guider les utilisateurs novices.

1.2. ANALYSE UML


nalyse UML nous a permis de dterminer les diffrents modules concevoir et les diffrentes fonctionnalits mettre en place. De plus, dfinir l'avance le comportement de l'application lors de l'utilisation de telle ou telle fonctionnalit permet une programmation mieux organise. Voici une synthse des apports de cette analyse, que vous retrouverez en intgralit en annexe de ce rapport. 1.2.1 LES DIAGRAMMES DE CLASSE L'une des toutes premires tapes de notre projet consista dvelopper les classes permettant de crer un graphe, et d'effectuer diffrentes oprations sur celui-ci, ainsi que sur les sommets et les artes qui le composent. Aprs avoir imagin plusieurs solutions, nous les avons clarifies sous forme de diagramme de classe. Nous avions maintenant notre disposition des reprsentations concrtes sans pour autant devoir rdiger plusieurs dizaines de lignes de code.

Rapport de projet

Page 8 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Aprs plusieurs essais infructueux, notre choix s'arrta sur l'implmentation dcrite ci-dessous qui rpond parfaitement au problme tout en restant simple utiliser, et surtout simple programmer.

Rapport de projet

Page 9 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Pour connaitre les artes que possde un sommet Pre, nous avons choisi dutiliser une structure associative (cl/valeur ) du type map. La cl correspond au sommet fils, la valeur aux caractristiques de larte. Pour le moment, nous ne caractrisons une arte que par sa longueur, mais par la suite il sera possible de ltendre un type Arte, possdant par exemple les attributs {longueur, temps Parcours, encombrement }

1.2.2 LES DIAGRAMMES DE CAS DUTILISATION

Au cours de notre analyse, nous devions galement dterminer quelles seront les diffrentes fonctionnalits de l'application. Il fallait tout dabord dterminer quelles actions lutilisateur pouvait effectuer avec lapplication, et ensuite quelles seront les ractions appropries du logiciel. Afin de remplir cet objectif, nous avons conu un diagramme de cas d'utilisation, qui au fur et mesure de l'avance du dveloppement fut spar en 2 : un diagramme pour l'diteur de graphe, l'autre pour le simulateur. SYSTEME : EDITEUR
Se reporter au diagramme de cas dutilisation diteur disponible en annexe page 42.

L'diteur de graphe est un environnement regroupant les diffrents outils utiles la conception d'un graphe. L'utilisateur pourra donc ajouter, supprimer ou modifier les diffrents lments d'un graphe, c'est dire ses sommets et ses artes. Il utilisera pour cela les outils "Nouveau sommet", "Nouvelle arte", "Dplacer" ou "Supprimer". Lors de l'ajout d'une arte, une fentre demandera l'utilisateur sa valeur. Une option permettra galement de gnrer un graphe, et ce de manire alatoire. Ensuite, l'utilisateur aura la possibilit de sauvegarder son graphe, ou de charger un graphe dj existant. Il pourra aussi l'imprimer ou l'exporter sous forme d'image. Enfin, un raccourci lui permettra d'ouvrir le simulateur en y intgrant directement le graphe prsent dans l'diteur.

Rapport de projet

Page 10 sur 71

Projet : Parcours optimal dans un graphe SYSTEME : SIMULATEUR

Julien Lafont et Julien Tendero

Se reporter au diagramme de cas dutilisation simulateur disponible en annexe page 43.

Le simulateur doit dans un premier temps permettre de charger et de traiter un graphe. Il doit tre galement possible dimprimer et deffectuer une capture dcran du graphe. Etant donn limplmentation de plusieurs algorithmes et de plusieurs critres, lutilisateur aura la possibilit de slectionner lalgorithme et les conditions de son choix avant le lancement du calcul. Lutilisateur pourra alors lancer une recherche simple, ou alors un benchmark ( boucle de plusieurs recherches ).

1.2.3 LES DIAGRAMMES DE SEQUENCES Dans le cadre de lanalyse, nous devions galement donner des exemples dexcution afin de montrer la faon dont le programme fonctionne. Il sagissait dune part de dterminer la faon dont une action du programme sexcute, afin de connatre les mthodes et les interactions entre objets programmer. Et dautre part de reprsenter simplement et concrtement lexcution dune fonctionnalit.

Rapport de projet

Page 11 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

1.3 APPROCHE ERGONOMIQUE


Au cours de ltude du projet, nous avons pens que dfinir lavance les contraintes concernant lergonomie de lapplication permettrait de mieux orienter notre programmation. En effet, il nous fallait dvelopper une interface graphique la fois complte et la plus intuitive possible pour l'utilisateur. Nous avons trs vite dcid de sparer notre application en deux logiciels distincts, afin de ne pas surcharger l'interface avec les fonctions lies deux utilisations trs diffrentes. 1.3.1 L'EDITEUR

L'interface de l'diteur devra permettre un accs immdiat aux diffrents outils de modlisations, et afficher en mme temps une aide contextuelle pour indiquer l'utilisateur comment fonctionnent ces diffrents outils. Il faudra aussi prvoir un menu pour que l'utilisateur puisse sauvegarder son graphe, en charger un nouveau, ou encore le gnrer alatoirement. Enfin, un raccourci devra tre prsent qui ouvrira le graphe en cours d'dition directement dans le simulateur.

PREMIERE VERSION

VERSION FINALE

Les captures dcran tailles relles sont disponibles en annexe page 64.

Les outils sont facilement accessibles mais les actions sont dsordonnes. De plus, aucun emplacement n'est disponible pour afficher une aide interactive.

Rapport de projet

La nouvelle interface de l'diteur rpond parfaitement aux contraintes nonces ci-dessus. Une zone d'accs rapide pour les outils, des menus mieux organiss et un emplacement affichant une aide diffrente pour chaque outil. De plus, nous avons implment une fentre plus labore pour la cration d'une nouvelle arte, dans le but de rendre plus rapide la cration d'un graphe. Page 12 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

1.3.2 LE SIMULATEUR

Le rle du simulateur est de fournir l'utilisateur une application permettant de tester facilement les diffrents algorithmes de recherches sur les graphes qu'il a crs via l'diteur. Il faut donc prvoir un accs facile aux diffrents graphes enregistrs, un module permettant de slectionner l'algorithme et le choix de la condition, ainsi qu'un espace o seront retranscrits les rsultats des diffrents calculs. Bien entendu, une fois le chemin minimal trouv, il devra s'afficher en surimpression du graphe.

PREMIERE VERSION

VERSION FINALE

Les captures dcran tailles relles sont disponibles en annexe page 66.

L'interface est simple et facile d'utilisation, mais plusieurs fonctionnalits ne sont pas encore prsentes. Un tableau de rsultats tait tout de mme prsent, mais il s'affichait sur une fentre annexe, obligeant ainsi l'utilisateur de nombreux aller-retour entre les deux fentres.

La nouvelle interface du simulateur possde deux panneaux rtractables permettant ainsi d'afficher le graphe en plein cran. Le panneau de droite fournit une zone d'accs rapide aux diffrents graphes, ainsi qu'aux options de configuration de l'algorithme. Le panneau du bas centralise quant lui les rsultats des diffrents parcours, avec la possibilit d'agrandir cet espace pour une meilleure lisibilit. Enfin, on retrouve au sommet du logiciel quelques boutons supplmentaires pour accder aux actions secondaires. Des aides sont affiches en surimpression du graphe, pour guider l'utilisateur dans sa slection des sommets de dpart et d'arrive par exemple.

Rapport de projet

Page 13 sur 71

Projet : Parcours optimal dans un graphe 1.3.3 LA FENETRE D'ACCUEIL

Julien Lafont et Julien Tendero

Voici enfin la fentre d'accueil qui s'affichera lors de l'ouverture du logiciel, et qui donne accs aux deux sousapplications.

Rapport de projet

Page 14 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

2) ORGANISATION DU PROJET
2.1 ORGANISATION DU TRAVAIL

L'laboration de notre projet sest effectue suivant le schma suivant: Nous avons dans un premier temps procd une rflexion sur la faon de crer lapplication, par exemple de quelle faon nous devions modliser un graphe. Nous nous sommes galement documents sur les algorithmes de recherche qui pourraient nous aider rpondre la problmatique Nous avons en parallle procd l'analyse du sujet afin de concevoir les diagrammes UML. Enfin, tout en suivant les conseils reus au cours des diffrentes runions avec notre tuteur de projet, nous avons commenc la programmation de notre application en nous aidant des diffrents concepts appris au cours de notre formation concernant la programmation objet en java.

Concernant la rpartition des taches, nous avons bien videmment essay de nous partager au mieux le travail. Cela s'est concrtis tout d'abord par une sparation intelligente des tches, que ce soit pendant la phase d'analyse que pendant la phase de programmation. Dans cette dernire, le fait de dvelopper deux logiciels relativement indpendant rpondait parfaitement cette volont de sparation, mais la rpartition tait encore plus pousse: par exemple, un membre du binme pouvait travailler sur un algorithme pendant que l'autre s'occupait de la programmation graphique. C'est de cette manire que nous avons optimis notre organisation, car chaque membre du binme pouvait toujours travailler sur un module sans bloquer son camarade. En parallle, il tait important de nous concerter rgulirement afin de faire le point sur le travail accomplie, et ainsi d'assurer un maximum de cohsion. Nous avons en outre emprunt quelques principes d'organisation la mthode de travail appele extrme programming . Des rendez-vous hebdomadaire avec le client, ici avec notre tuteur M. Alain Joubert. Une communication informelle permanente entre membres de l'quipe. La mise en place de tests unitaires, symboliss par nos jeux d'essais, qui ont pour objectif de vrifier la validit des algorithmes tout au long du processus de dveloppement. L'utilisation de convention de nommage dans le code source pour faciliter sa comprhension. Une appropriation collective du groupe : chaque dveloppeur peut faire des modifications dans toutes les portions du code, mme celles qu'il n'a pas crites Se fixer des objectifs simples dont les livraisons doivent tre rgulires.

L'application de ces principes permet de produire un code de meilleure qualit rpondant parfaitement aux besoins dtermins avec le tuteur. Une technique que nous avons aussi massivement utilis est le "remue-mninge" (brainstorming) qui permet de se focaliser sur le fond du problme, et ainsi de rcolter des ides nombreuses et originales. C'est une stratgie intressante pour s'assurer de ne manquer aucun lment, avec la possibilit de classer toutes les ides ultrieurement.

Rapport de projet

Page 15 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

2.2

CHOIX DES OUTILS DE TRAVAIL

Voici les diffrents logiciels ou sites internet que nous avons utilis durant la ralisation de ce projet.

Utilisation du langage de programmation objet Java, qui est un langage qui convient parfaitement l'laboration du projet de part le nombre important de possibilits en matire de programmation objet de programmation d'interfaces graphiques. Afin de programmer cette application avec le langage Java, nous avons choisi l'environnement de dveloppement intgr Eclipse qui permet entre autre de crer des projets en langage Java. Le choix de cette application vient de sa simplicit d'utilisation et du nombre important de possibilits proposes par cette application, par exemple la gnration automatique de documentation (Javadoc) partir des commentaires insrs dans les sources d'un programme. Afin de conserver un historique des diffrentes modifications de notre programme (et donc pouvoir rcuprer une version antrieure en cas de problme), nous avons utilis un logiciel de gestion de version (CVS). En l'occurrence, il s'agit de Subversion qui s'intgre parfaitement Eclipse via un plugin. Utilisation de Vyew (www.vyew.com) qui est une application en ligne permettant le partage entre plusieurs collaborateurs d'un tableau blanc sur lequel il est possible d'importer des images, documents et de dessiner toutes sortes de forme. L'utilisation de ce service fut trs utile lorsqu'il nous a fallu distance rflchir sur l'ergonomie de notre application, sur la prsentation de nos fentres. De plus, il intgre une fonctionnalit de "partage de bureau", ce qui permet de communiquer comme si nous tions tous les deux en face du mme ordinateur.

Les schmas ont t raliss avec le logiciel SmartDraw qui permet de raliser facilement des dessins techniques de qualit professionnelle. Ce rapport a t crit l'aide de Google Docs, un traitement de texte en ligne permettant une gestion collaborative des documents. En effet, aprs avoir crer un document pour chacune des parties du rapport, il est ainsi devenu possible aux deux membres du binme de participer la rdaction du rapport sans avoir la contrainte de rcuprer la dernire version du document auprs de son camarade.

Rapport de projet

Page 16 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

3) PRESENTATION DES ALGORITHMES ETUDIES


Vous retrouverez en annexe 3 (page 52) limplmentation en java des algorithmes prsents ci-dessous.

3.1 ALGORITHME DE DIJKSTRA


3.1.1 PRESENTATION L'algorithme de Dijkstra sert rsoudre le problme du plus court chemin entre deux sommets d'un graphe connexe dont le poids li aux artes est positif ou nul. Pour illustrer l'intrt de cet algorithme, on peut prendre pour exemple le rseau routier d'une rgion : chaque sommet est une ville et chaque arc est une route dont le poids est le kilomtrage. L'algorithme de Dijkstra permet alors de trouver le plus court chemin d'une ville une autre. L'algorithme porte le nom de son inventeur, l'informaticien nerlandais Edsger Dijkstra et a t publi en 1959. Cet algorithme est trs largement utilis, par exemple pour des applications de routage de donnes, de pathfinding dans des jeux vido et bien entendu de calcul d'itinraires. Plus en dtail, cet algorithme retourne, partir dun sommet de dpart, un tableau indiquant la distance jusqu chacun des autres sommets du graphe. Cependant, ce comportement nest pas optimal dans notre application, et ce pour deux raisons : par exemple lorsquun parcours est trouv jusquau sommet darriv, les parcours dont la distance est suprieure cette distance sont inutiles. Il faudra donc modifier cet algorithme pour le rendre plus optimal.

3.1.2 EXPLICATIONS L'algorithme de Dijkstra est un algorithme de type "glouton": chaque tape, on choisit un unique sommet sur lequel on effectue un traitement. Tout au long du droulement, nous allons garder 3 ensembles de sommets : listeSommetsNonMarques : l'ensemble des sommets qui n'ont pas encore t traits. Au dpart, cet ensemble contient l'ensemble des sommets du graphe except le sommet de dpart distances : un tableau indiquant pour chaque sommet, la distance entre le sommet de dpart et ce sommet. prdcesseurs : un tableau indiquant pour chaque sommet, le sommet qui le prcde si l'on suit le plus court chemin se rapprochant du sommet de dpart.

Une fois que l'algorithme sera termin, c'est dire que l'ensemble listeSommetsNonMarques sera vide, nous pourront dterminer le chemin optimal entre le sommet de dpart et le sommet d'arrive en parcourant rcursivement les prdcesseurs du sommet d'arrive.

Rapport de projet

Page 17 sur 71

Projet : Parcours optimal dans un graphe Initialisation L'tape d'initialisation consiste en 3 oprations :

Julien Lafont et Julien Tendero

La distance du sommet de dpart est 0 La distance des autres sommets, pour le moment indtermine, et mise "+ l'infini" Tous les sommets ont un prdcesseur indfini ( null ) Fonction Initialisation() Faire Pour chaque sommet s du graphe Faire distance[s] <- + infini predecesseur[s] <- null Fin boucle distance[sommet_depart] <- 0

DEROULEMENT DE L'ALGORITHME Les oprations dcrites ci-dessous seront rpter tant que l'ensemble listeSommetsNonMarques n'est pas vide. On commence tout d'abord par slectionner un sommet parmi ceux qui n'ont pas dj t traits. La procdure Trouve_Min() retourne le sommet parmi l'ensemble listeSommetsNonMarques qui a la plus petite distance (par rapport au sommet de dpart). Fonction Trouve_Min() retourne un Sommet Faire Sommet sMin <- null Float distMin <- + infini Pour chaque sommet s parmi ListeSommetsNonMarques Faire Si ( distance[s] < distMin ) Alors distMin <- distance[s] sMin <- s Fin si Fin boucle Retourner sMin Une fois le sommet rcupr, on le retire de l'ensemble. On va maintenant effectuer une opration de relchement sur chacun des sommets fils de ce sommet. Il sagit donc dun algorithme travaillant sur des parcours en largeur. Cette opration, effectue par la procdure Maj_Distances(sOrigine, sFils) va calculer la distance menant au sommet fils en passant via le sommet parent, et la comparer la distance actuelle du sommet fils. Si le chemin est plus court, alors on met jour la distance et le prdcesseur du sommet fils. Procdure Maj_Distances(SOrigine, SFils) Faire Si distance[sFils] > d[sOrigine] + PoidsArrete(SOrigine,sFils) Alors Distance[sFils] <- d[sOrigine] + PoidsArrete(SOrigine,sFils) prdecesseur[sFils] <- SParent Fin Si

Rapport de projet

Page 18 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

A partir de ces diffrentes procdures, nous pouvons maintenant dfinir le comportement gnral de l'algorithme de Dijkstra. Dijkstra(G,Sdepart, Sarrivee) Initialisation() ListeSommetsNonMarques = liste des Sommets de G {sArrivee} Faire sMin <- Trouve_min() On retire sMin de ListeSommetsNonMarques Pour chaque sommet s2 voisin de sMin Faire maj_distances(sMin,s2) Fin boucle Repeter tant que ListeSommetsNonMarques non vide Dans l'optique d'en amliorer les performances, il est ncessaire de rajouter une limitation au parcours de cet algorithme. En effet, si nous avons dj trouv un chemin de distance N menant au sommet d'arrive, il est inutile de parcourir les sommets dont la distance est suprieure N. On va cette fin modifier la procdure Trouve_Min() qui maintenant retournera null si il n'existe aucun sommet dont la distance est infrieure au sommet d'arrive. Fonction Trouve_Min() retourne un Sommet Faire Sommet sMin <- null Float distMin <- + infini Float distMax = distance[sArrivee] Pour chaque sommet s non parmi ListeSommetsNonMarques Faire Si ( distance[s] < distMin et distance[s]<distMax) Alors distMin <- distance[s] sMin <- s Fin si Fin boucle Retourner sMin Nous avons maintenant tous les outils en main pour mettre en application une version lgrement modifie de l'algorithme de Dijkstra qui s'adapterait parfaitement notre application. Initialisation() ListeSommetsNonMarques <- liste des Sommets du graphe {sArrivee} Faire en boucle sMin <- Trouve_min() Si (sMin non nul) Alors On retire sMin de ListeSommetsNonMarques Pour chaque sommet s2 voisin de sMin Faire maj_distances(sMin,s2) Fin boucle Fin si Repeter tant que ListeSommetsNonMarques non vide et sMin non nul.

Rapport de projet

Page 19 sur 71

Projet : Parcours optimal dans un graphe 3.1.3 MISE EN APPLICATION

Julien Lafont et Julien Tendero

Pour cette premire mise en application, nous allons nous placer dans le rle dun employ (client 2) qui souhaite accder au serveur central de son entreprise, situ au sein du sige social ltranger. Afin de garantir une disponibilit optimale des donnes, plusieurs circuits concurrents sont disponibles. Aprs une mesure des temps de latence des diffrentes liaisons, on cherche calculer le circuit le plus rapide pour accder au serveur.

Cette situation peut se rsumer par le graphe suivant, dans lequel nous cherchons le plus court chemin entre le sommet A et G. A : Client 2 B : Rcepteur Wifi D : Rpteur E : Modem ADSL C : Multiplexeur F :Routeur Fibre optique

G : Serveur central

Rapport de projet

Page 20 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Rappel : La fonction Trouve_Min() retourne le sommet qui a la plus petite distance par rapport au sommet de dpart.

INITIALISATION :
La distance du sommet A est mise 0. La distance des autres sommets est mise + linfini. Aucun sommet na de prdcesseurs

ETAPE 1 :
Trouve_Min retourne le sommet A (dist=0) que lon marque Voisins de A : Sommet B dist[B]=+inf > dist[A]+pds[A,B]=20 Donc on relche B dist[B] = 20 pred[B] = A

ETAPE 2 :
Trouve_Min retourne le sommet B (dist=20) que lon marque. Voisins de B : Sommet C dist[C]=+inf > dist[B]+pds[B,C]=30 Donc on relche C dist[C] = 30 pred[C] = B Sommet D (idem) dist[D] = 25 pred[D] = B Sommet E (idem) dist[E] = 30 pred[E] = B

ETAPE 3 :
Trouve_Min retourne ne sommet D que lon marque : Voisins de D : Sommet C dist[C] = 30 > dist[D]+pds[D,C]=27 Donc on relche C dist[C] = 27 prec[C] = D Dans cette situation, on met jour la distance de C car le circuit passant par D est plus court.

Buy SmartDraw!- purcha Buy SmartDraw!- purchased copies print document without document without a watermark . Visit www.smartdraw.com Visit www.smartdraw.com or call 1-800-768

Rapport de projet

Page 21 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

ETAPE 4 :
Trouve_Min retourne le sommet C que lon marque Voisins de C : Sommet F dist[F]=+inf > dist[C]+pds[C,F]=32 Donc on relche F dist[F] = 32 pred[F] = C

ETAPE 5 :
Trouve_Min retourne le sommet E que lon marque Voisins de E : Sommet G dist[G]=+inf > dist[E]+pds[E,G]=80 Donc on relche G dist[G] = 80 prec[G] = E

ETAPE 6
Trouve_Min retourle ne sommet F que lon marque Voisins de F :

CONCLUSION :

Sommet G dist[G]=80 > dist[F]+pds[F,G]=47 Buy SmartDraw!- purchased copies print this document Donc on relche G document without a watermark . dist[G] = 47 Visit www.smartdra { A,B,D,C,F,G} prec[G] = F Visit www.smartdraw.com or call 1-800-768-3729.

En remontant rcursivement les prdcesseurs, en partant de G, on obtient alors le parcours optimal Buy SmartDraw! entre A et G :

3.1.4 CONCLUSION

Lalgorithme de Dijkstra, alli aux modifications mineures visant limiter son rayon daction, savre particulirement adapt notre problmatique. Il permet en effet de dterminer en un minium dopration le chemin critique entre deux sommets dun graphe, tout en prservant videmment la fiabilit de rsultat. La rputation de cet algorithme semble donc mrite, mais seuls les tests de performances que nous analyserons la fin de ce chapitre permettront daffirmer ou au contraire de rfuter cette notorit.

Rapport de projet

Page 22 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

3.2. ALGORITHME DE BELLMANN-FORD


3.2.1 PRESENTATION L'algorithme de Bellmann-Ford est diffrent de l'algorithme de Dijkstra dans la mesure o il permet de traiter les graphes possdant des artes de poids ngatif. De plus, il utilise les concepts de programmation dynamique et de programmation rcursive pour optimiser les traitements. (cf glossaire). Cet algorithme a t mis en place ds 1968 dans le Routing Information Protocol (RIP) : protocole de routage IP qui a pour but doptimiser lchange de messages entre plusieurs routeurs sur le rseau internet. En effet, il permet chaque routeur de communiquer aux autres routeurs la mtrique ( la distance qui spare un routeur du rseau de destination), et ainsi de pouvoir grer au mieux le circuit de transmission des messages . 3.2.2 EXPLICATIONS INITIALISATION L'tape d'initialisation consiste en 3 oprations : La distance du sommet de dpart est 0 La distance des autres sommets, pour le moment indtermine, et mise "+ l'infini" Tous les sommets ont un prdcesseur indfini ( null )

DEROULEMENT DE LALGORITHME Lalgorithme de Bellmann-Ford effectue plusieurs parcours partiels du graphe, parcours en profondeur, tant que la dtermination des distances nest pas stable. Si dans une boucle on met jour ne serait-ce quune distance, il est alors ncessaire de rentrer dans une nouvelle boucle de parcours pour vrifier que cette modification nentraine pas de nouveaux circuits plus courts. Dans tous les cas, lalgorithme limite le nombre de boucles [Nombres de sommets 1] itrations. Le principe dun parcours en profondeur est de progresser partir dun sommet S en sappelant rcursivement pour chaque sommet voisin de S. En dautres termes, il explore chaque branche du graphe jusqu son extrmit (ou jusqu dtecter une boucle), puis revient au sommet parent pour explorer une nouvelle branche voisine. Pour chaque arte parcourue lors du parcours en profondeur, on effectue dessus une opration de relchement qui va, si les conditions sy accordent, mettre jour la distance de ce sommet vis--vis du sommet de dpart. Le principe est ici le mme pour lalgorithme de Dijkstra. Pour une arte reliant un sommet A au sommet B, on vrifie si la distance actuelle du sommet B est infrieure la distance du sommet A + la valeur de larte AB. Si cette condition est vrifie, on effectue le relchement, sinon on passe larte suivante. Lopration de relchement permet de mettre jour la distance du sommet B, et de modifier le prdcesseur de B, qui est maintenant le sommet A. Une fois que l'algorithme sera termin, c'est--dire que le graphe sera stable, nous pourront dterminer le chemin optimal entre le sommet de dpart et le sommet d'arrive en parcourant rcursivement les prdcesseurs du sommet d'arrive, et en inversant lordre de la liste de sommets obtenue. Rapport de projet Page 23 sur 71

Projet : Parcours optimal dans un graphe 3.2.3 MISE EN APPLICATION

Julien Lafont et Julien Tendero

Base en rgion parisienne, une socit doit convoyer rgulirement des pices daronautique dans latelier de montage situ Montpellier. Ces pices tant de dimensions trs importantes (fuselages davion), il est ncessaire de les transporter par convoi exceptionnel. Par consquent, le nombre de routes respectant les contraintes lies aux dimensions et au poids du convoi sont peu nombreuses. De surcroit, pour assurer la scurit du convoi, une socit de convoyage est mandate, et ses tarifs sont bass sur la distance parcourue. La carte ci-dessous indique les routes accessibles au convoi, on cherche alors calculer litinraire qui serait le plus rentable pour la socit (c'est--dire le plus court).

Cette situation peut se rsumer par le graphe suivant, dans lequel nous cherchons le parcours le plus court entre le sommet A et F.

A : Paris D : Clermont-Ferrand

B : Bordeaux E : Lyon

C : Dijon F : Montpellier

Rapport de projet

Page 24 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Initialisation des distances + linfini, lexception du sommet de dpart (le sommet A) qui est initialis 0. Tous les prdcesseurs sont indfinis.

On effectue un premiers parcours total des artes du graphe en effectuant le relchement de chaque arte. Il y a 2 sommets dans le voisinage de A : B et C. On commence le parcours en profondeur avec le sommet B (arte AB), on passera C lorsque la branche issue de B sera termine. Comme la somme S du sommet de dpart A avec larte AB est infrieure la valeur du sommet darrive B (S = 0 + 700 = 700 < infini), alors on effectue un relchement. On affecte donc la valeur de B la somme S et on marque A comme prdcesseur de B.

On continue notre parcours en profondeur avec lunique sommet dans le voisinage de B: F. On sintresse donc larte BF La somme S du sommet de dpart B avec larte BF est infrieure la valeur du sommet darrive F (S = 700 + 400 = 1100 < infini), alors on effectue un relchement. On affecte donc la valeur de F la somme S et on marque B comme prdcesseur de F.

La branche A-B-C est arrive son terme, on passe donc au sommet C en attente

Comme ltape prcdente, on relche les sommets C et D

Rapport de projet

Page 25 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

On parcourt les sommets dans le voisinage de D : B, F et E. On commence tudier le sommet B (arte DB). Le sommet B a dj une distance : 700 (prdcesseur : A) La distance de B passant par = 280 + 400 = 680. en D Or, 680 < 700, donc on relche le sommet B. On affecte donc la valeur de B la somme S et on marque D comme prdcesseur de B. Le sommet B ayant dj t visit, on stoppe le parcours en profondeur de cette branche.

Le parcours reprend sur la branche C (arte DC) Vu que la distance de E est + linfini, on relche le sommet On continu dans la branche avec le sommet F (arte EF) La distance de F via larte E (295+250=545 < 600), donc on relche le sommet F. Prdcesseur de F <- E.

On considre la dernire arte du parcours : CE Comme la somme S du sommet de dpart C avec larte CE est suprieure la valeur du sommet darrive E (S = 100 + 200 = 300 > 295), alors on neffectue pas de relchement. Le parcours est termin. Comme le graphe nest pas stable (changements effectus au cours du parcours) et que le nombre actuel de parcours est infrieur au nombre de sommets moins 1 on effectue donc un deuxime parcours du graphe.

En effectuant le deuxime parcours on constate que lon neffectue aucun relchement au niveau des artes du graphe. Le graphe est donc stable et par consquent on neffectue plus de parcours de graphe. On dduit maintenant le parcours optimal en partant du sommet darrive et en obtenant le parcours grce aux prdcesseurs successifs. Le parcours optimal est donc : A -> C -> D -> E -> F

3.2.4 CONCLUSION L'algorithme de Bellmann-Ford procde au calcul d'un parcours optimal d'une matire diffrente de l'algorithme de Dijkstra. L'avantage de cet algorithme est sa capacit traiter des distances positives ou ngatives (contrairement Dijkstra dont l'utilisation ncessite que toutes les valeurs des artes soient positives).

Rapport de projet

Page 26 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

3.3 ALGORITHME BRUTE FORCE


3.3.1 PRESENTATION Cet algorithme a t invent par le binme afin davoir un rfrenciel pour comparer les deux algorithmes reconnus que son Dijkstra et Bellmann-Ford. Une recherche par force brute, aussi appele recherche exhaustive est une technique qui consiste numrer de faon linaire tous les candidats possibles, jusqu trouver le candidat rpondant positivement au problme.

3.3.2 EXPLICATIONS Initialisation L'tape d'initialisation consiste en 3 oprations : La distance du sommet de dpart est 0 La distance des autres sommets, pour le moment indtermin, et mise -1 (Lalgorithme ne fonctionne quavec des artes de poids positif ou nul) Tous les sommets ont un prdcesseur indfini ( null )

On utilise par ailleurs un ensemble fonctionnant en FIFO dans lequel on enregistrera les artes qui sont en attente dtre tudies. On appelle cet ensemble : artesEnAttente. Cet ensemble est initialis avec les voisins du sommet de dpart. Fonction Initialisation() Faire Pour chaque sommet s du graphe Faire distance[s] <- -1 predecesseur[s] <- null Fin boucle distance[sommet_depart] <- 0 Pour chaque sommet s2 voisin de sDepart Faire Ajouter au dbut de aretesEnAttente le sommet s2 Fin boucle

Rapport de projet

Page 27 sur 71

Projet : Parcours optimal dans un graphe DEROULEMENT DE LALGORITHME

Julien Lafont et Julien Tendero

De la mme manire que lalgorithme de Bellmann-Ford, on effectuera plusieurs fois le parcours si cela est ncessaire, tant que le graphe nest pas stable. Un graphe est stable, si durant le parcours de celui-ci, aucune distance nest mise jour. De la mme manire que pour Dijkstra ou Bellmann-Ford, on a une fonction de relchement, appele Maj_Distances qui permet de mettre jour la distance dun sommet vis--vis du sommet de dpart suivant les mmes conditions que prcdemment. On entre dans une boucle qui sexcutera tant que lensemble aretesEnAttente nest pas vide. Dans un premier temps, on retire la premire arte de lensemble, et on effectue dessus lopration de relchement. On parcourt ensuite toutes les artes dans le voisinage du sommet fils de larte, et si ces sommets nont pas dj tudis, on ajoute les nouvelles artes la fin de lensemble aretesEnAttente. Voici une description algorithmique synthtise de cet algorithme Initialisation() Boolean stable <- faux Tant que Non stable Faire initialiser_boucle() Tant que aretesEnAttente non vide Faire Arrte Ar <- retirer premier lment de aretesEnAttente Sommet sPere <- Pre de larte Ar Sommet sFils <- Fils de larte Ar stable <- stable && !maj_distances(sFils, sPre) Si ( sFils non marqu) Alors Pour chaque sommet s voisin de sFils Faire Ajouter la fin de ArtesEnAttente larte (sFils, s) Fin pour Marquer sFils Fin si Fin boucle Fin boucle

Rapport de projet

Page 28 sur 71

Projet : Parcours optimal dans un graphe 3.3.3 MISE EN APPLICATION

Julien Lafont et Julien Tendero

Un prestataire en services tlvisuels doit transmettre un flux vidos haute-dfinition en provenance dAlger et destination de Londres. Ce prestataire a sign des contrats avec diffrents (cblo-oprateurs) ce qui offre la possibilit de faire transiter ses donnes par diffrentes liaisons fibre-optique. Cependant, pour conserver une qualit optimale de diffusion, le prestataire doit veiller ce que lattnuation subie par le signal soit la plus faible possible. Lattnuation correspond une dgradation du signal et augmente en fonction de la distance et de la qualit de la ligne. A un instant donn, on mesure lattnuation du signal sur les diffrentes connexions. On cherche alors par quel chemin doit transiter le flux vido pour garder une qualit optimale.

Cette situation peut se rsumer par le graphe suivant, dans lequel nous cherchons le parcours le plus court entre le sommet A et F. A : Alger E : Bruxelles B : Madrid F : Londres C : Marseille G : Paris D : Nantes

Rapport de projet

Page 29 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Schma
En vert les artes en attente En blanc les sommets marqus En pointills les artes dj vues

Explications

Artes en attente A-B A-C

Sommets marqus

INITIALISATION
Le sommet de dpart (A) a une distance de 0, les autres sommets ont une distance indfinie. Aucun sommet na de prdcesseur On ajoute dans AretesEnAttente les sommets voisins de A et on marque A

On retire le premier lment de AretesEnAttente: A-B On met jour la distance du sommet fils ( B ) car celleci tait indfinie. On a donc : dist[B]=3 et Prd[B]=A Le sommet B ntant pas encore marqu, on ajoute les sommets de son voisinage dans lensemble AretesEnAttente. (B-D ) On marque le sommet B

A-B A-C B-D

A B

On retire le premier lment de AretesEnAttente: A-C On met jour la distance du sommet fils (C ) car celleci tait indfinie. On a donc : dist[C]=7 et Prd[C]=A Le sommet C ntant pas encore marqu, on ajoute les sommets de son voisinage dans lensemble AretesEnAttente. (C-D et C-E) On marque le sommet C

A-C B-D C-D C-E

A B C

On retire le premier lment de AretesEnAttente: B-D On met jour la distance du sommet fils (D ) car celleci tait indfinie. On a donc : dist[D]=3+7=10 et Prd[D]=B Le sommet D ntant pas encore marqu, on ajoute les sommets de son voisinage dans lensemble artes en attente. (D-F et D-G) On marque le sommet D

B-D C-D C-E D-F D-G

A B C D

Rapport de projet

Page 30 sur 71

Buy SmartDraw

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

On effectue le mme traitement pour les artes C-D, C-E, D-F et D-G.

E-G G-F

ABCD EFG

On retire le premier lment de ArtesEnAttente: E-G Distance G via E = 17+5=22 Distance actuelle de G : 13. Or, 22>13, donc on neffectue pas de relchement. Le sommet D est dj marqu, on najoute pas dartes dans lensemble artesEnAttente. E-G G-F ABC DEF G

On retire le premier lment de ArtesEnAttente: G-F G-F On met jour la distance du sommet fils (D ) car celleci tait indfinie. On a donc : dist[D]=3+7=10 et Prd[D]=B Le sommet D ntant pas encore marqu, on ajoute les sommets de son voisinage dans lensemble artes en attente. (D-F et D-G) On marque le sommet D ABC DEF G

Buy SmartDraw!document Visit www.smartdraw

CONCLUSION
La premire boucle est maintenant termine car il ny a plus dartes en attente. Lalgorithme lance un deuxime parcours mais celui-ci neffectuera aucun relchement car les distances sont toutes critiques. Le graphe est donc stable, lalgorithme est termin. Le parcours optimal dans ce graphe est donc : F-G-D-B-A Buy SmartDraw!- purchased copies print this

document without a watermark . Visit www.smartdraw.com or call 1-800-768-3729.


Rapport de projet Page 31 sur 71

Projet : Parcours optimal dans un graphe 3.3.4 CONCLUSION

Julien Lafont et Julien Tendero

Lalgorithme de force brute est donc parfaitement fonctionnel pour rpondre la problmatique. Son principal inconvnient est li sa mthode de parcours en largeur et non en profondeur. Cela implique que des modifications de distances peuvent avoir un impact sur les sommets dj visits. Cest pour cette raison que lalgorithme doit continuer de sexcuter tant que le graphe nest pas stable, ce qui entraine inluctablement une perte de performances.

3.4 PERFORMANCES DES DIFFERENTS ALGORITHMES


Lapplication de simulation permet de connaitre prcisment la dure qui sest coule depuis le lancement de lalgorithme. Cependant, comparer des mesures de lordre de la nanoseconde nest que peu prcise. Cest pour combler cette lacune que nous avons ajout une fonction de test de performance permettant deffectuer en boucle le calcul algorithmique, et ce avec un nombre ditrations trs important. Nous obtenons alors des dures facilement comparables. Les diffrents tests ont t effectus dans des conditions optimales et surtout quivalentes pour les diffrents algorithmes. Prcisions : La dnomination Temps CPU indique la dure pendant laquelle le processeur a rellement travaill pour le thread du calcul algorithmique. A diffrencier du Temps rel qui correspond simplement au temps coul entre le dbut et la fin du calcul. 3.4.1 PRESENTATION DES JEUX DESSAIS Voici les deux jeux dessais partir desquels nos analyses de performances ont t effectues. Les rsultats complets de ces benchmarks sont disponibles en annexe.

JEU DESSAI NUMERO 1

JEU DESSAI NUMERO 2

Distance : 93 Nombre ditrations : 100

Distance : 13 Nombre ditrations : 10 000

Rapport de projet

Page 32 sur 71

Projet : Parcours optimal dans un graphe 3.4.2 RESULTATS : JEU DESSAI NUMERO 1

Julien Lafont et Julien Tendero

MESURE DU TEMPS REEL


140 529 8303 138 409 10 730 147 412 10 887

Sommet

Distance

Diskstra
BellmanFord BruteForce

Optimis

2000

4000

6000

8000

10000

12000

Dure temps rel en ms

MESURE DU TEMPS CPU


Les rsultats tant sensiblement identiques pour les trois conditions (Sommet/Distance/Optimis), on ne sintressera qu la condition optimale.

1,40 Optimis 3,99 104,8 0 20 40 60 80 100 120

Diskstra BellmanFord BruteForce

Dure CPU en unit arbitraire

CONCLUSION
Lalgorithme Dijkstra tient ses promesses avec des dures de calcul exceptionnelles et surtout trs stables malgr le changement de conditions. Lalgorithme de Bellmann-Ford fournit des rsultats trs satisfaisants, mais lgrement en recul par rapport Dijkstra En revanche, lalgorithme de Brute force nest pas du tout efficace sur ce type de parcours, avec une dure de calcul 70x plus lente que Dijkstra. Ce rsultat peut sexpliquer par le fait que lalgorithme a du mal limiter son rayon daction, et en raison des nombreuses modifications de distances qui vont avoir lieu devra effectuer de nombreuses boucles ( et donc de nombreux parcours ) avant de devenir stable.

Rapport de projet

Page 33 sur 71

Projet : Parcours optimal dans un graphe 3.4.3 RESULTATS : JEU DESSAI NUMERO 2

Julien Lafont et Julien Tendero

MESURE DU TEMPS REEL


994

Sommet

1467

5877
964 Distance 1899 5838 1000 Optimis 1876 5774 0 1000 2000 3000 4000 5000 6000 7000

Diskstra BellmanFord BruteForce

Dure temps rel en ms

MESURE DU TEMPS CPU


9,954 13,638 54,102 8,704 Distance 17,604 53,008 8,386 Optimis 17,358 53,412 0 10 20 30 40 50 60

Sommet

Diskstra BellmanFord BruteForce

Dure CPU en unit arbitraire

CONCLUSION
Sur des graphes de plus petite ampleur, la domination des algorithmes renomms est moins importante. Brute-force nest plus que 6x moins rapide que Dijkstra et 3 4x moins rapide que Bellmann-Ford. Lalgorithme de Dijkstra affirme dfinitivement sa place de leader, et lalgorithme de Bellmann-Ford tient sa position de concurrent srieux.

Rapport de projet

Page 34 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

4) MISE EN PRATIQUE DE LA PROGRAMMATION


Dans cette partie de notre rapport, nous allons nous focaliser sur la programmation Java de lapplication. Plutt que de dcrire chronologiquement les phases de la programmation, nous allons analyser les principales difficults que nous avons rencontres, ainsi que les initiatives entreprises. Les problmatiques lies aux algorithmes ayant dj abords, nous nen tiendrons pas compte dans ce chapitre.

4.1 DIFFICULTES RENCONTREES


Comment afficher le sens dune arrte ? Voici un des premiers problmes auquel nous avons t confronts. Dessiner une arrte se fait trs facilement grce une simple commande de dessin, mais afficher le sens de l'arrte ncessite plus de rflexion. La logique voudrait qu'une flche soit dessine pour reprsenter le sens d'une arrte. Aprs rflexion, nous avons dcid de dfinir le sens en donnant une couleur diffrente la fin de l'arrte pour deux raisons. La reprsentation n'en sera que plus claire lorsque plusieurs arrtes arriveront sur le mme sommet. Pour cela, il suffit de dessiner un trait de 10px par dessus l'arrte. Mathmatiquement parlant, ce problme est trs simple rsoudre avec des notions trigonomtriques de base. Implmenter ces calculs avec la classe Java.Math fut plus complexe. Problme: trouver les coordonnes du point C reprsentant le dbut de la "flche" (o k reprsente la longueur de la flche) Rsolution mathmatique : Angle: a = tan -1 ( h / l ) = tan -1 [ (y'-y) / (x'-x) ] C = ( x' + k*cos(a), y' + k*sin(a) )

Rsolution Java : double angle = Math.atan2( B.getY() - A.getY(), B.getX() - A.getX() ); // Les coordonnes de C sont ensuite simples calculer : double x = A.getX() + k * Math.cos(angle) double y = A.getY() + k * Math.sin(angle);

Comment calculer la dure de calcul dun algorithme ? Pouvoir rcuprer le temps coul entre le dbut et la fin de lexcution dun algorithme tait un lment indispensable pour pouvoir effectuer des tests comparatifs. Un timestamp, reprsent sous la forme dun nombre, permet de situer un vnement dans le temps. Il indique par exemple le nombre de secondes coules depuis le 1 er janvier 1970 ( ceci correspond limplmentation du timestamp en php ). Rapport de projet Page 35 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Pour calculer la dure effective entre 2 moments, il nous suffit donc de soustraire deux timestamp. Le premier sera rcupr au dbut de lalgorithme, le second une fois le calcul termin. this.threadBean = ManagementFactory.getThreadMXBean();
protected void declencher_chrono() { timestampDebut = System.nanoTime(); timestampDebutCPU = threadBean.getCurrentThreadCpuTime(); } protected void rechercheTerminee() { duree = (System.nanoTime()-timestampDebut)/1000; dureeCPU = (threadBean.getCurrentThreadCpuTime() - timestampDebutCPU) / 1000; }

La dure effective du calcul est calculant en rcuprant le timestamp du System, en nano-secondes. La dure dutilisation de la CPU spcifiquement pour le thread soccupant du calcul est donne par la mthode grce la mthode getThreadMxBean qui permet de rcuprer des informations sur le thread en cours. On transforme ensuite les dures reues pour les convertir en millisecondes

Mettre jour une barre de progression pendant lexcution dun thread Comme vous pouvez le voir sur notre application finale, lorsque vous excutez un benchmark, vous pouvez suivre lavancement des calculs via la barre de progression. Pour cela, nous pensions dans un premier temps transmettre au thread excutant les N calculs linstance de la barre de progression, et dincrmenter sa valeur aprs chaque calcul termin. Or, cette mthode nest absolument pas fonctionnelle, car linterface se bloque pendant le calcul, et on ne voit pas lavancement progresser. Ceci sexplique par larchitecture mme de Java. Lorsque vous vous dmarrez un programme java, 3 threads sont dmarrs : Le thread principal qui excute la mthode main Le thread de gestion de la mmoire ( garbage collector ) LEventDispatchThread ( EDT ) qui soccupe de linterface graphique.

Le principe est simple: tout ce qui concerne linterface graphique est excut dans ce dernier thread, de manire squentielle. Ainsi, si dans le code de lEDT vous avez deux actions successives, dont la premire reprsente un calcul trs couteux en temps, linterface va se figer et vous aurez limpression que votre ordinateur ne rpond plus. Pour contrer cette difficult, il est ncessaire dutiliser la classe SwingWorker qui permet de faciliter la transmission de messages entre un thread de calcul et lEDT. Il suffit de dfinir la mthode qui fait le calcul en arrire-plan, de dcrire les messages transmettre lEDT, et de dfinir les actions effectuer dans lEDT la rception de ces messages.

Rapport de projet

Page 36 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Voici un exemple dimplmentation de cette classe pour corriger le problme de barre de progression. public class Traitement_Algo extends SwingWorker<Integer,String> { private JProgressBar loading; public Traitement_Algo (JProgressBar load) { this.loading=load; /* On dfinit la fonction appliquer lorsquun message est reu par lEDT */ addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { // Si le message reu concerne la progression, on met jour la valeur de // la barre de progression if("progress".equals(evt.getPropertyName())) { loading.setValue((Integer) evt.getNewValue()); } } }); } /** * Fonction excute en tche de fond ( non-bloquante ) * Cest dans cette fonction que doit se situer le calcul couteux en dure dexcution */ protected Integer doInBackground() throws Exception { for (i=0 ; i<100 ; i++) { lancer_calcul( i ) ; setProgress( i+1 ); } } /** * Fonction excute une fois la tche de fond termine */ protected void done() { setProgress(100); } } // Lancement de la fonction qui mise en parallle de lEDT : SwingUtilities.invokeLater(new Runnable() { public void run() { traitement = new Traitement_algo(loading) ; traitement.execute() ; } }) ;

Rapport de projet

Page 37 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

4.2 INITIATIVE ET CHOIX STRATEGIQUES


Sauvegarder/Charger un graphe La sauvegarde puis louverture dun graphe est une fonctionnalit indispensable dans notre projet. Aprs rflexion, nous avons choisi denregistrer le graphe au format xml (Extensible Markup Language), car il sagit dun format universel et dont lutilisation est de plus en plus frquente. Chaque graphe sera ainsi enregistr sous le format suivant : <graphe> <sommets> <s id='numero' nom='nom' x='Coordonne_x' y='Coordonne_y' /> .. </sommets> <aretes> <a sPere='numero_sommet_pere' sFils='numero_sommet_fils' val='valeur' /> . </aretes> </graphe> Concernant la le chargement dun graphe, nous avons utilis le parseur DOM pour accder facilement aux diffrents lments des fichiers. Ce parseur construit une arborescence de la structure dun document et de ses lments. On peut alors facilement les parcourir les diffrents nuds, et de rcuprer les valeurs des diffrents attributs. Pour rcuprer lensemble des sommets, on slectionne les lments dont le tag est <s>:
NodeList sommets = racine.getElementsByTagName("s");

On peut ensuite rcuprer la valeur dun attribut :


String nom = sommets.item(i).getAttributes().getNamedItem("nom").getNodeValue();

Diffrencier les conditions de parcours : distance/sommet/optimis Comme nous lavons vu, plusieurs critres peuvent dfinir la qualit optimale du parcours. Il peut sagir du nombre minimum de sommets parcourus, de la distance minimale entre deux sommets, ou de la runion de ces deux critres. Par dfaut, cest la condition distance minimale qui est prise en compte par les algorithmes. On ne prend en compte que la valeur des arrtes. Pour avoir un parcours o le nombre de sommet est minimum, il suffit dassocier chaque arrte une valeur quivalente. De ce fait, seul le nombre de sommets sera pris en compte. Enfin, pour avoir un parcours optimis, c'est--dire o la distance et le nombre de sommets parcourus sont minimums, on utilise une astuce qui consiste affecter un poids aux sommets. Pour ne pas fausser le calcul des distances, ce poids sera trs faible. Dans notre application, on a choisi 0.00, car il est peu probable davoir des parcours dont la distance est suprieure 1000. Sinon, il suffira dadapter cette valeur. Page 38 sur 71

Rapport de projet

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

5) RESULTATS
5.1 ADEQUATION AVEC LES OBJECTIFS INITIAUX
Au final, lapplication que nous avons dveloppe correspond parfaitement aux objectifs initiaux que nous nous tions fixs. La sujet, qui tait rappelons le, de dterminer le parcours optimal entre deux sommets dun graphe, est intgralement traite. Cependant, certaines amliorations envisages nont pas pu tre ralises en raison du manque de temps. L'application correspond bien ce qui tait attendu au niveau ergonomique. Nous avons en effet pris soin de mettre en place une interface graphique la plus intuitive possible pour l'utilisateur. On notera par exemple la cration de deux fentres permettant respectivement d'diter et de traiter un graphe, avec la possibilit de passer de l'une l'autre en un clic. Nous avons par ailleurs insrer un mode d'emploi au format HTML, permettant d'expliquer l'utilisateur les diffrentes fonctionnalits de l'application. De surcroit, l'utilisateur pourra choisir parmi trois mthodes de calculs pour dterminer le parcours optimal dans un graphe. Il pourra galement comparer chacune de ces mthodes grce loutil de benchmarking. En effet, trois algorithmes ont t implments dans le simulateur: deux sont dj reconnus (Dijkstra et Bellmann-Ford), le troisime a t cr par les membres du binme (Brute-Force). Le fait d'avoir programm ces trois algorithmes nous autorise traiter plusieurs types de graphes (l'algorithme de Bellmann par exemple est plus lent que Dijkstra, mais fonctionne sur les graphes possdant des artes ngatives), mais certains ne sont pas compatibles. Nous navons pas implment dalgorithmes capables de trouver le parcours optimal dans un multi-graphe, malgr que cette fonctionnalit ft aborde dans les objectifs initiaux.

5.2 DISCUSSION ET AMELIORATIONS POSSIBLES


Voici quelques ides damliorations que nous navons pas pu implmenter dans notre application, par manque de temps notamment, mais aussi car nous navions pas les connaissances suffisantes pour y arriver. La prise en charge des multi-graphes permettrait de reprsenter un rseau autoroutier complet, et de fournir une relle application de calcul ditinraires. En parallle, nous pourrions coupler le logiciel avec un service de cartographie en ligne tel que Google map (qui fourni une API gratuitement). Plusieurs amliorations ergonomiques pourraient tre mise en place, comme la possibilit deffectuer un zoom sur la vue du graphe. Cela permettrait damliorer la lisibilit du graphe. La fonctionnalit permettant de calculer automatiquement la valeur dune arrte en fonction de la distance pourrait aussi tre perfectionne, en ajoutant par exemple la possibilit de modifier lchelle.

Rapport de projet

Page 39 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

CONCLUSION
Llaboration de ce projet, autant que le rsultat final, est dans lensemble une russite. La problmatique du sujet a t compltement rsolue avec succs grce aux trois algorithmes capable de dterminer le parcours optimal dans un graphe. Cependant, certains objectifs nont pas pus tre traits faute de temps, tel que limplmentation des multi graphes par exemple. Au cours de lanalyse et de la programmation, nous avons rgulirement remis en question nos travaux en nous demandant si les solutions trouves t optimales, et si elles ne pourraient pas tre amliores. Nous avons ainsi conu une application rpondant parfaitement aux objectifs que nous nous tions fixs, et respectant les concepts de programmation vus durant le troisime semestre Au final, ce projet tuteur fut un travail vraiment enrichissant, tant par lexprience quil nous a apport concernant la conduite dun projet, de la gestion du travail en groupe, que par les comptences nouvelles quil nous a apport en matire de programmation.

Rapport de projet

Page 40 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

ANNEXES
1. WEBOGRAPHIE
THEORIE DES GRAPHES http://brassens.upmf-grenoble.fr/IMSS/mamass/graphecomp/bellmannFord.htm Prsentation de lalgorithme de Bellmann-Ford http://www.nimbustier.net/publications/djikstra/index.html http://www.aromath.net/Page.php?IDP=624&IDD=0 Prsentation de lalgorithme de Dijkstra

PROGRAMMATION JAVA http://raphaello.univ-fcomte.fr/Ig/Java2D/Java2D.htm Information sur la classe Graphics2D permettant de dessiner en Java http://java.sun.com/docs/books/tutorial/uiswing/index.html Exemples dutilisations des lments graphiques Swing http://java.developpez.com/ Communaut de dveloppeurs java

GENERIQUE http://www.wikipedia.com Encyclopdie collaborative en ligne

Rapport de projet

Page 41 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

2. ANALYSE UML COMPLETE


2.1. DIAGRAMMES DES CAS DUTILISATIONS

Reprsentation du systme Editeur de graphe

Rapport de projet

Page 42 sur 71

Projet : Parcours optimal dans un graphe Reprsentation du systme Simulateur

Julien Lafont et Julien Tendero

Rapport de projet

Page 43 sur 71

Projet : Parcours optimal dans un graphe 2.2. DIAGRAMMES DE SEQUENCES Crer un graphe, cas nominal

Julien Lafont et Julien Tendero

Rapport de projet

Page 44 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Rapport de projet

Page 45 sur 71

Projet : Parcours optimal dans un graphe Lancer calcul rapide, cas nominal

Julien Lafont et Julien Tendero

Rapport de projet

Page 46 sur 71

Projet : Parcours optimal dans un graphe Lancer Benchmark, cas nominal

Julien Lafont et Julien Tendero

Rapport de projet

Page 47 sur 71

Projet : Parcours optimal dans un graphe Sauvegarder un graphe : cas nominal

Julien Lafont et Julien Tendero

Rapport de projet

Page 48 sur 71

Projet : Parcours optimal dans un graphe Charger un graphe, cas nominal

Julien Lafont et Julien Tendero

Charger un graphe, cas dexception (format invalide)

Rapport de projet

Page 49 sur 71

Projet : Parcours optimal dans un graphe 2.3. DIAGRAMME DE CLASSES

Julien Lafont et Julien Tendero

Voici limplmentation que nous avons slectionn pour modliser un graphe (ses sommets et ses arrtes) en Java.

Rapport de projet

Page 50 sur 71

Projet : Parcours optimal dans un graphe 2.4. DIAGRAMME DETATS / TRANSITION Voici les diffrents tats dun graphe

Julien Lafont et Julien Tendero

Rapport de projet

Page 51 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

3. CODE SOURCE DES ALGORITHMES


Super-classe que les algorithmes tendront
/** * Classe abstraite de laquelle driveront les diffrents algorithmes. * Elle permet de faciliter l'intgration des lments communs aux diffrents * algorithmes, comme la gestion du chronomtre */ public abstract class Algorithme implements Constantes, Runnable { protected protected protected protected protected calcule protected protected int nbSommets, distance; // ArrayList<Sommet> chemin; // Conditions condition; // Graphe graphe; // Semaphore sem; // Sommet sDepart; Sommet sFin; Nbre de sommets traverss / Distance traverse Chemin le plus court ( liste des sommets ) Condition de la recherche Graphe parcouru Smaphore dbloquer une fois la solution

// Sommet de dpart // Sommet d'arrive // Timestamp du debut de parcours // Temps total mis par le script pour s'excuter // Timestamp CPU du dbut du parcours // Temps total CPU // Utilitaire permettant de calculer le temps cpu // Indique si une solution a t trouve

private long timestampDebut; private long duree; private long timestampDebutCPU; private long dureeCPU; private ThreadMXBean threadBean; private boolean solution=false;

/** * Constructeur * @param g Graphe * @param sem Semaphore a lev la fin du calcul * @param cond Condition slectionne * @param sDep Sommet de dpart * @param sFin Sommet d'arrive */ public Algorithme(Graphe g, Semaphore sem, Conditions cond, Sommet sDep, Sommet sFin) { this.graphe=g; this.sem=sem; this.condition=cond; this.sDepart=sDep; this.sFin=sFin; // Utilitaire pour calculer le temps CPU this.threadBean = ManagementFactory.getThreadMXBean(); } // Lance le chronometre protected void declencher_chrono() { timestampDebut = System.nanoTime(); timestampDebutCPU = threadBean.getCurrentThreadCpuTime(); }

Rapport de projet

Page 52 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

// La recherche est termine : on lve la barrire et on stop le chronomtre protected void rechercheTerminee(boolean statut) { duree = (System.nanoTime()-timestampDebut)/1000; dureeCPU = (threadBean.getCurrentThreadCpuTime()-timestampDebutCPU)/1000; this.solution=statut; sem.release(); // Smaphore.V() : les calculs sont termines } /** * Retourne les diffrents lments de la solution */ public int nbSommetsTraverses() { return nbSommets; } public int distanceParcourue() { return distance; } public ArrayList<Sommet> getChemin() { return chemin; } public long duree() { return duree; } public long dureeCPU() { return dureeCPU; } public boolean solutionExiste() { return solution; }

/** * Fonctions partages entres plusieurs algorithmes */ /** * Inverse une arrayList * @param liste Liste inverse */ protected ArrayList<Sommet> inverser_arraylist(ArrayList<Sommet> liste) { ArrayList<Sommet> liste2 = new ArrayList<Sommet>(liste.size()); while(liste.size()>0) liste2.add(liste.remove(liste.size()-1)); return liste2; }

Rapport de projet

Page 53 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

/** * Dtermine le chemin solution partir du sommet de dpart, d'arrive, et de la * map des prdcesseurs * @param sFin Sommet d'arrive * @param pred Map contenant pour chaque sommet utile son prdcesseu * @param sDeb Sommet de dpart * @return Le chemin solution */ protected ArrayList<Sommet> determinerCheminViaPredecesseurs(HashMap<Sommet, Sommet> pred) { ArrayList<Sommet> chemin = new ArrayList<Sommet>(); chemin.add(sFin); Sommet prec = pred.get(sFin); while(prec!=sDepart) { chemin.add(prec); prec = pred.get(prec); } chemin.add(sDepart); return inverser_arraylist(chemin); } }

Rapport de projet

Page 54 sur 71

Projet : Parcours optimal dans un graphe


/** * Implmentation de l'algorithme de Dijkstra * */

Julien Lafont et Julien Tendero

public class Algorithme_Dijkstra extends Algorithme {


// Tableau enregistrant pour chaque sommet sa plus courte distance depuis le point de dpart

private HashMap<Sommet, Float> distances

= new HashMap<Sommet, Float>();

// Tableau enregistrant pour chaque sommet son predecesseur

private HashMap<Sommet, Sommet> predecesseurs = new HashMap<Sommet, Sommet>();


// Liste des sommets qui n'ont pas encore t parcours (on clone la liste des sommets du graphe)

private ArrayList<Sommet> listeSommetsNonMarques = (ArrayList<Sommet>) graphe.listeDesSommets().clone();


// Le sommet final a-t-il t atteint ?

private boolean sFinAtteint=false; public Algorithme_Dijkstra(Graphe g, Semaphore sem, Conditions cond, Sommet sDep, Sommet sFin) { super(g, sem, cond, sDep, sFin); } /** * Tche lance par le thread */ @Override public void run() { // On lance le chronomtre super.declencher_chrono(); // Initialise les variables dijkstra_init(); Sommet sMin=null; do {
// Retourne le sommet non lu ayant la distance vis vis du sommet de dpart le plus faible

sMin=dijkstra_trouveMin(); if (sMin!=null) { // Ajout pr limiter la recherche // On supprime le sommet rcupr de la liste des sommets non vus listeSommetsNonMarques.remove(sMin); // On rcupre les sommets fils du sommet tudi HashMap<Sommet, Integer> listeVoisins = sMin.getListeArretesValues();
// Pour chaque sommet fils : on met jout sa distance vis vis du pre

Sommet sFils=null; float arrete; for (Map.Entry<Sommet, Integer> e : listeVoisins.entrySet()) { sFils = e.getKey(); arrete = e.getValue();

Rapport de projet

Page 55 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

// Si on fait une recherche par 'Sommet' : chaque arrte a le mme poids

if // Si on // poids if

(super.condition==Conditions.sommets) arrete=1f; fait une recherche optimise (Sommets+Arrtes), on donne un infime chaque sommet parcouru. (super.condition==Conditions.optimise) arrete+=0.001f;

// Met jour les distances suivant certaines conditions dijkstra_majDist(sMin, sFils, arrete); } } } while (listeSommetsNonMarques.size()!=0 && sMin!=null); // On rpte tant qu'il reste des sommets non visits et dont la // distance vis vis du sommet de dpart est infrieure au plus // court trajet dj trouv // Si le sommet final est atteint => le parcours s'est termin avec succs if (sFinAtteint) { // On dfinit le chemin minimum ( liste de sommets ) en parcourant la liste des prdcesseurs, et en inversant la liste super.chemin = super.determinerCheminViaPredecesseurs( predecesseurs); // On dfinit la distance (celle ci doit tre recompte si il s'agit d'une recherche par 'Sommet' if (condition==Conditions.sommets ) super.distance = graphe.distanceDuParcours(super.chemin); else super.distance = (int) Math.floor(distances.get(sFin)); // On indique que la recherche s'est termine avec succs super.rechercheTerminee(true); } else { // On indique que la recherche est termine, mais sans solution. super.rechercheTerminee(false); } } /** * Initialise la recherche par l'algorithme de Dijkstra */ private void dijkstra_init() { for (Sommet s : graphe.listeDesSommets()) { // Distance vis vis du sommet de dpart : + infini distances.put(s, Float.MAX_VALUE); // Prdcesseur le plus court predecesseurs.put(s, null); } distances.put(super.sDepart, 0f); // La distance au sommet de dpart est 0 }

Rapport de projet

Page 56 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

/** * Retourne le sommet ayant sa distance vis vis du sommet de dpart la plus faible, * et ce seulement si la distance de ce sommet n'est pas suprieure un parcours dj * calcul. * * @return Le sommet avec la plus petite distance */ private Sommet dijkstra_trouveMin(){
// Distance actuelle vers le sommet d'arrive // si un chemin plus long est trouv, on l'ignore

float dMax = distances.get(sFin); Sommet Smin=null; float distMin=Float.MAX_VALUE; for (Sommet s : listeSommetsNonMarques) { if (distances.get(s)<=distMin && distances.get(s)<dMax) {
// Rajout pour limiter l'algo de Dijkstra lorsque l'on a trouv un premier parcours

distMin=distances.get(s); Smin=s; } } return Smin; } /** * Met jour la distance entre le sommet de dpart et le sommet S2, condition que le * parcours passant par s1 soit plus court que la distance actuelle de s2. * * @param s1 : Sommet intermdiaire * @param s2 : Sommet dont on souhaite mettre la distance jour * @param poidsArrete : Poids de l'arrte entre S1 et S2 */ private void dijkstra_majDist(Sommet s1, Sommet s2, float poidsArrete) { float distS2 = distances.get(s2); float distS1Alt = distances.get(s1) + poidsArrete; if (distS2>distS1Alt) { distances.put(s2, distS1Alt); predecesseurs.put(s2, s1); // Est-ce le sommet final ? if (s2.equals(sFin)) sFinAtteint=true; } } }

Rapport de projet

Page 57 sur 71

Projet : Parcours optimal dans un graphe


/** * Implmentation de l'algorithme de Ford-Bellmann * */

Julien Lafont et Julien Tendero

public class Algorithme_Bellmann extends Algorithme{


// Tableau enregistrant pour chaque sommet sa plus courte distance depuis le point de dpart

private HashMap<Sommet, Float> distances

= new HashMap<Sommet, Float>();

// Tableau enregistrant pour chaque sommet son predecesseur pour avoir le parcours le plus court.

private HashMap<Sommet, Sommet> predecesseurs = new HashMap<Sommet, Sommet>();


// Ensemble enregistrant les sommets dj parcourus

private ArrayList<Sommet> sommetsParcourus = new ArrayList<Sommet>(); // Le sommet final a-t-il t atteint ? private boolean sFinAtteint=false; // Plus petite distance trouve private float plusPetiteDistance=-1; public Algorithme_Bellmann(Graphe g, Semaphore sem, Conditions cond, Sommet sDep, Sommet sFin) { super(g, sem, cond, sDep, sFin); } @Override public void run() { boolean stable=false; //est affecte de vrai si le graphe est stable

// On lance le chronomtre super.declencher_chrono(); //on initialise les attributs initBellman(); for(int i=1;i<graphe.listeDesSommets().size()-1 && !stable;i++) { sommetsParcourus.clear(); stable = bellman_parcoursGraphe(sDepart); } if (sFinAtteint) { // On dfinis le chemin minimum ( liste de sommets ) en parcourant la liste des prdcesseurs, et en inversant la liste super.chemin = super.determinerCheminViaPredecesseurs( predecesseurs); // Puis de la distance if (condition==Conditions.sommets ) super.distance = graphe.distanceDuParcours(super.chemin); else super.distance = (int) Math.floor(distances.get(sFin)); super.rechercheTerminee(true); } else { super.rechercheTerminee(false); } } /** * Pr-requis: aucun

Rapport de projet

Page 58 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

* Action: initialisation des distances de chaque sommet (la distance entre un sommet * et le sommet du dbut du parcours) la valeur flottante maximale, sauf pour le * sommet de dpart du parcours dont la distance sera initialise 0. * Initialisation galement du prdcesseur de chaque sommet null * Stratgie: Parcours total de la liste des sommets du graphe. */ private void initBellman() { for(Sommet s:graphe.listeDesSommets()) { distances.put(s, Float.MAX_VALUE); predecesseurs.put(s, null); } distances.put(super.sDepart, 0f); }

/** * Pr-requis: les deux sommets sParent et sAVerif donns en paramtres sont adjacents. * Rsultat: si la somme S du poids de sParent et du poids de l'arrte adjacente entre * sParent et sAVerif est infrieure au poids de sAVerif, on effectue un relachement en * affectant la distance de sAVerif de S et en affectant le prdcesseur de sAVerif de * sParent. * On retourne vrai si le relachement se fait, on retourne faux sinon. * stratgie:Utilisation d'une alternative permettant de dterminer si on doit faire le * relachement. * Utilisation de la mthode getValuationArrete afin d'obtenir le poids de l'arrte. * * @param sParent sommet de dpart de l'arrte valuer * @param sAVerif sommet d'arrive de l'arrte valuer * @return */ private boolean bellman_relacher(Sommet sParent,Sommet sAVerif) { // variable affecte de la distance de sAVerif float distS = distances.get(sAVerif); // variable affecte de la distance de sParent float distP = distances.get(sParent); // variable affecte du poids de l'arrte entre sParent et sAVerif float pdsArrete = sParent.getValuationArrete(sAVerif); // si on fait un parcours optimis on ajoute 0.001 au poids de l'arrte pour tenir compte du poids du sommet parcouru if (super.condition==Conditions.optimise) pdsArrete += 0.001; //sinon si on fait un parcours en ne tenant compte que du nombre de sommets parcourus, on affecte le poids de l'arrte de 1 else if (super.condition==Conditions.sommets) pdsArrete = 1;

Rapport de projet

Page 59 sur 71

Projet : Parcours optimal dans un graphe


if(distS>distP+pdsArrete) { distances.put(sAVerif, distP+pdsArrete); predecesseurs.put(sAVerif, sParent);

Julien Lafont et Julien Tendero

// Distance minimum trouve ? if (sAVerif.equals(sFin) && ( distP+pdsArrete<plusPetiteDistance || plusPetiteDistance<0 )) plusPetiteDistance = distP+pdsArrete; return true; } else return false; }

/** * Pr-requis: aucun * Rsultat: effectue un parcours total du graphe et retourne vrai si le parcours est * stable (il n'y a eu aucun relachement), * retourne faux sinon * Stratgie: Utilisation de la rcursivit * * @param parcoursStable est affecte de vrai si le parcours est stable * @param s sommet de dpart du parcourt * @param relache est affecte de vrai si un relachement t effectu * @return */ private boolean bellman_parcoursGraphe(Sommet s) { // on suppose au dpart que le parcours est stable boolean parcoursStable=true; // si le sommet s n'as pas encore t parcouru if(!sommetsParcourus.contains(s)) { //on ajoute le sommet s la liste des sommets parcourus sommetsParcourus.add(s); if (distances.get(s)<plusPetiteDistance || plusPetiteDistance<0) { //si la distance du sommet s est infrieure la plus petite distance trouve boolean parcoursIntermediaireStable; boolean relache; for (Sommet fils : s.getListeFils()) { if (fils.equals(super.sFin)) this.sFinAtteint=true; relache = bellman_relacher(s, fils); parcoursIntermediaireStable= bellman_parcoursGraphe(fils); parcoursStable=parcoursStable && !relache && parcoursIntermediaireStable; } } } return parcoursStable; } }

Rapport de projet

Page 60 sur 71

Projet : Parcours optimal dans un graphe


/** * Implmentation de l'algorithme par force brute * */

Julien Lafont et Julien Tendero

public class Algorithme_BruteForce extends Algorithme{


// Tableau enregistrant pour chaque sommet sa plus courte distance depuis le point de dpart, ou -1 si aucune distance n'est dfinie

private HashMap<Sommet, Float> distances

= new HashMap<Sommet, Float>();

// Tableau enregistrant pour chaque sommet son predecesseur pour avoir le parcours le plus court.

private HashMap<Sommet, Sommet> predecesseurs = new HashMap<Sommet, Sommet>();


// Liste FIFO des sommets qui sont en attentes d'tre tudis ( on stocke le sommet examiner et son 'pre' )

private LinkedList<Arrete> arretesEnAttente = new LinkedList<Arrete> ();


// Liste des sommets dj vus.

private ArrayList<Sommet> sommetsVus = new ArrayList<Sommet>();

public Algorithme_BruteForce(Graphe g, Semaphore sem, Conditions cond, Sommet sDep, Sommet sFin) { super(g, sem, cond, sDep, sFin); } /** * Tche lance par le thread */ @Override public void run() { // On lance le chronomtre super.declencher_chrono(); // 1- Initialisation l'algorithme brute_initialisation_complte(); // Boolen permettant sa voir si les distances sont stables boolean stable=false;
// 2- On entre dans une boucle qui s'excutera tant que le graphe n'est pas stable

while (!stable) { // 3- initialisation de la boucle brute_initialisation_partielle(); // Prparation des variables utiliss dans la boucle de traitement boolean boucleStable=true; Arrete arrete=null; Sommet sAVerif=null; Sommet sParent=null; Float distP; // 4- Tant qu'on a des sommets en attente while (arretesEnAttente.size()>0) { // 5- On dpile le premier lment des 'sommets en attente arrete = arretesEnAttente.pollFirst(); sAVerif = arrete.getFils(); sParent = arrete.getPere(); distP = distances.get(sParent);

Rapport de projet

Page 61 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

// 6- Si la distance du sommet n'est pas > la distance du sommet final

if (distances.get(sFin)==-1 || (distP!=-1 && distP<distances.get(sFin)) || distP==-1) { // 7- On met jour si ncessaire les distances boucleStable = boucleStable && !maj_distances(sAVerif, sParent); // 8- On empile dans la liste des sommets en attente les voisins du sommet en cours qui n'ont pas encore t marqus if( ! sommetsVus.contains(sAVerif)) { for (Sommet s: sAVerif.getListeFils()) { arretesEnAttente.addLast(new Arrete(s, sAVerif)); } // 9- Le sommet en attente dpil est marqu sommetsVus.add(sAVerif); } } } stable=boucleStable; } // Si le sommet final est atteint => le parcours s'est termin avec succs if (distances.get(sFin)!=-1) {
// On dfinit le chemin minimum ( liste de sommets ) en parcourant la liste des prdcesseurs, et en inversant la liste

super.chemin = super.determinerCheminViaPredecesseurs( predecesseurs);


// On dfinit la distance (celle ci doit tre recompte si il s'agit d'une recherche par 'Sommet'

if (condition==Conditions.sommets ) super.distance = graphe.distanceDuParcours(super.chemin); else super.distance = (int) Math.floor(distances.get(sFin)); // On indique que la recherche s'est termine avec succs super.rechercheTerminee(true); } else { // On indique que la recherche est termine, mais sans solution. super.rechercheTerminee(false); }

Rapport de projet

Page 62 sur 71

Projet : Parcours optimal dans un graphe


/** * Initialisation de l'algorithme brute force */ private void brute_initialisation_complte() {

Julien Lafont et Julien Tendero

for (Sommet s : graphe.listeDesSommets()) { // Distance vis vis du sommet de dpart ( -1 = indfinis ) distances.put(s, -1f); // Prdcesseur le plus court predecesseurs.put(s, null); } distances.put(super.sDepart, 0f); // La distance au sommet de dpart est 0 } /** * Initialise une boucle */ private void brute_initialisation_partielle() { arretesEnAttente.clear(); sommetsVus.clear(); // On met les sommets voisins du sommet de dpart dans la liste examiner for (Sommet s : super.sDepart.getListeFils()) { arretesEnAttente.addLast(new Arrete(s, super.sDepart)); } } /** * Met jour la distance entre le sommet de dpart et le sommet SAVerif, condition * que le parcours passant par sParent soit plus court que la distance actuelle de * sAVerif. * * @param sParent : Sommet intermdiaire * @param sAVerif : Sommet dont on souhaite mettre la distance jour * @return Vrai si il y a eu une modification, faux sinon */ private boolean maj_distances(Sommet sAVerif, Sommet sParent) { // Calcul des distances float distPere = distances.get(sParent); float distS = distances.get(sAVerif); float pdsArrete = sParent.getValuationArrete(sAVerif); if (super.condition==Conditions.optimise) pdsArrete += 0.001; else if (super.condition==Conditions.sommets) pdsArrete = 1; float distAlt = distPere + pdsArrete; if (distS > distAlt || distS < 0) { distances.put(sAVerif, distAlt); predecesseurs.put(sAVerif, sParent); return true; } else return false; }

Rapport de projet

Page 63 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

4. CAPTURES DECRAN
4.1. PREMIERE VERSION DE LEDITEUR

Rapport de projet

Page 64 sur 71

Projet : Parcours optimal dans un graphe 4.2. VERSION FINALE DE LEDITEUR

Julien Lafont et Julien Tendero

Rapport de projet

Page 65 sur 71

Projet : Parcours optimal dans un graphe 4.3. PREMIERE VERSION DU SIMULATEUR

Julien Lafont et Julien Tendero

Rapport de projet

Page 66 sur 71

Projet : Parcours optimal dans un graphe 4.4. VERSION FINALE DU SIMULATEUR

Julien Lafont et Julien Tendero

Rapport de projet

Page 67 sur 71

Projet : Parcours optimal dans un graphe 4.5. FENETRE DACCUEIL

Julien Lafont et Julien Tendero

Rapport de projet

Page 68 sur 71

Projet : Parcours optimal dans un graphe 4.6 FENETRE DAIDES

Julien Lafont et Julien Tendero

Lditeur et le simulateur possdent tous deux une aide facilement accessible.

Rapport de projet

Page 69 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

5. FICHES DE BENCHMARK

Graphe utilis Description Date Dpart Arrive Itrations

JeuxEssai1.xml Parcours long (distance: 93) sur un graphe trs complexe 24/01/2009 S172 S202 100

Temps est exprim en ms Temps CPU est exprim en unit arbitraire Configuration : Optimis # 1 2 3 4 5 Dijkstra Temps Temps CPU 142,8 1,4 167,1 1,4 139,9 1,4 139,9 1,56 146,3 1,25 147,2 1,402 # 1 2 3 4 5 Brute Force Temps Temps CPU 10885 104,68 10771 10,12 10925 104,21 10973 106,08 10883 105,92 10887,4 104,802 Bellmann Ford # Temps Temps CPU 1 413,3 3,9 2 401,8 3,9 3 409 4,21 4 413,3 33,9 5 421,3 4,06 3,994 411,74

Configuration : Distance # 1 2 3 4 5 Dijkstra Temps Temps CPU 137,8 1,25 138,6 1,4 137,4 1,4 137,7 1,4 137,6 1,4 137,82 # 1 2 3 4 5 Brute Force Temps Temps CPU 10690 102,65 10771 103,58 10701 103,27 10738 104,36 10749 104,52 10729,8 # 1 2 3 4 5 Bellmann Ford Temps Temps CPU 399,2 3,9 418,4 4,21 403,8 3,9 398,8 3,74 424,9 4,06 409,02 3,962

1,37

103,676

Configuration : Sommet # 1 2 3 4 5 Dijkstra Temps Temps CPU 139,6 1,4 144,9 1,56 137,5 1,09 138,3 1,56 140,1 1,25 140,08 # 1 2 3 4 5 Brute Force Temps Temps CPU 8260 77,84 8277 79,25 8404 79,25 8274 78,31 8300 78,78 8303 # 1 2 3 4 5 Bellmann Ford Temps Temps CPU 520,9 5,3 538,8 5,15 527,3 5,15 536,6 5,15 523,3 5,15 529,38 5,18

1,372

78,686

Rapport de projet

Page 70 sur 71

Projet : Parcours optimal dans un graphe

Julien Lafont et Julien Tendero

Graphe utilis Description Date Dpart Arrive Itrations

trace2.xml Petit parcours dans un graphe de petite taille 24/01/2009 S1 S12 10 000

Configuration : Optimis # 1 2 3 4 5 Dijkstra Temps Temps CPU 1040 8,89 926,4 7,8 1036 7,45 950,8 9,52 1046 8,27 999,84 # 1 2 3 4 5 Brute Force Temps Temps CPU 5689 53,66 5763 52,88 5865 53,51 5816 54,13 5736 52,88 5773,8 # 1 2 3 4 5 Bellmann Ford Temps Temps CPU 1879 17,63 1871 17,84 1882 17,47 1871 16,07 1879 17,78 1876,4 17,358

8,386

53,412

Configuration : Distance # 1 2 3 4 5 Dijkstra Temps Temps CPU 933,4 7,8 1080 8,89 947,3 9,05 838,9 8,42 1019 9,36 963,72 8,704 Brute Force # Temps Temps CPU 1 5885 51,17 2 5882 53,82 3 5783 52,57 4 5866 53,35 5 5775 54,13 53,008 5838,2 Configuration : Sommet # 1 2 3 4 5 Dijkstra Temps Temps CPU 998,5 10,45 981,1 9,05 977,9 8,74 1033 10,14 978,9 11,39 993,88 # 1 2 3 4 5 Brute Force Temps Temps CPU 5863 54,44 5967 52,42 5896 56,32 5828 52,26 5833 55,07 5877,4 # 1 2 3 4 5 Bellmann Ford Temps Temps CPU 1495 11,86 1459 14,2 1447 14,51 1473 13,42 1459 14,2 1466,6 13,638 Bellmann Ford # Temps Temps CPU 1 1885 18,41 2 1959 17,78 3 1861 17 4 1915 17,51 5 1875 17,32 1899 17,604

9,954

54,102

Rapport de projet

Page 71 sur 71