diff --git a/df.md b/df.md new file mode 100644 index 0000000000000000000000000000000000000000..196b8ea75952b5bab929c4a1d9a3dabf364bcb35 --- /dev/null +++ b/df.md @@ -0,0 +1,89 @@ +--- +author: +- Dijkstra et Floyd - algorithmes de plus cours chemins +title: Cours de programmation séquentielle +autoSectionLabels: false +autoEqnLabels: true +eqnPrefix: + - "éq." + - "éqs." +chapters: true +numberSections: false +chaptersDepth: 1 +sectionsDepth: 3 +lang: fr +documentclass: article +papersize: A4 +cref: false +urlcolor: blue +toc: false +--- + +# Préambule + +Ce travail pratique est organisé en plusieurs parties traitant la notion de recherche de plus court chemin dans +un graphe. Il faudra implémenter les algorithmes de Floyd et de Dijkstra que vous avez vus en cours. +Vous appliquerez ces algorithmes sur un graphe représentant +un certain nombre de lignes ferroviaires suisses. +Finalement, une partie graphique vous sera demandée pour rendre le travail un peu plus ludique. + +Dans cette deuxième partie, vous aurez besoin des structures de données que vous avez implémenté ces dernières semaines: la liste et file d'adjacence, ainsi que la file de priorité. + +# L'algorithme de Dijkstra + +L'algorithme de Dijkstra permet de déterminer le plus court chemin entre deux points d'un graphe: le sommet de *départ* et le sommet *d'arrivée*. + +Dans cette section nous allons décrire +l'algorithme en général, puis voir comment l'implémenter (lisez donc toute la section). + +## L'algorithme en général + +Il s'agit d'un algorithme qui améliore itérativement le calcul de la distance entre les sommets +d'un graphe. Nous avons en premier lieu une étape d'initialisation: + +1. Nous marquons tous les sommets +du graphe comme non visités. +2. Pour chaque sommet, assigner une distance "infinie" à chaque sommet non visité. Le sommet de départ a une distance nulle. + +La boucle de mise à jour des distances se passe comme suit: + +1. Pour le sommet courant, calculer leurs distances provisoires passant par le sommet courant. Comparer la distance provisoire avec la distance actuellement stockée dans le sommet. Si celle-ci est plus petite remplacer la valeur stockée par celle nouvellement calculée. +2. Lorsque nous avons visité tous les sommets voisins du sommet courant, marquer le sommet comme visité. Un sommet marqué comme visité ne sera jamais plus visité. +3. Si le sommet de destination a été marqué comme visité, ou si les distances avec tous les sommets non visités sont infinies[^1] l'algorithme est terminé. +4. Passer au sommet voisin non visité avec la distance la plus faible et recommencer au point 1. + +## Implémentation + +L'algorithme le plus efficace (et également le plus simple) pour trouver le plus cours chemin entre un sommet de départ et tous les autres sommets d'un graphe utilise une file de priorité min. + +Le pseudo-code est donné par + +```C +void dijkstra(graph g, int src, int num, int dist[num], int prev[num]) { + dist[src] = 0; // all other distances are INT_MAX + prev[src] = -1; // previous node is undefined + queue_init(q, (source, 0)); + + !queue_is_empty(q) { + p = queue_pop(q); + for v in the neighborhood of p { + d_new = dist[v] + ditsance(p, v); + if (d_new < dist[v]) { + dist[v] = d_new; + prev[v] = p; + queue_push(q, (v, d_new)); + } + } + } +} +``` + +Il faut noter que la priorité est donnée par la distance totale depuis le sommet de départ. +La distance entre `src` et tous les autres sommets +est dans le tableau `dist`. Le parcours entre `src` +et un sommet `v`, est obtenu à l'aide du tableau +`prev` en suivant les indices en partant de `prev[v]`. + + + +[^1]: Cela veut dire qu'il n'y a pas de chemin entre le sommet de départ et celui d'arrivée. \ No newline at end of file