diff --git a/slides/cours_25.md b/slides/cours_25.md index ae1dd4a89999b93656f9424448f058d6d8960ff6..ed8ee2b7b4b6b57242601496540c5bf526388309 100644 --- a/slides/cours_25.md +++ b/slides/cours_25.md @@ -108,3 +108,118 @@ $$ \log(u\cdot v)=\log(u)+\log(v). $$ +# Applications de plus courts chemins + +## Quelles applications voyez-vous? + +. . . + +* Déplacement d'un robot; +* Planificaiton de trajet / trafic urbain; +* Routage de télécommunications; +* Réseau électrique optimal; +* ... + +# Plus courts chemins à source unique + +* Soit un graphe, $G=(V, E)$, une fonction de pondération $w:E\rightarrow\mathbb{R}$, et un sommet $s\in V$ + * Trouver pour tout sommet $v\in V$, le chemin de poids minimal reliant $s$ à $v$. +* Algorithmes standards: + * Dijkstra (arêtes de poids positif seulement); + * Bellman-Ford (arêtes de poids positifs ou négatifs, mais sans cycles). +* Comment résoudre le problèmes si tous les poids sont les mêmes? + +. . . + +* Un parcours en largeur! + +# Algorithme de Dijkstra + +## Avez-vous une idée de comment chercher pour un plus court chemin? + +``` + + + + + + + + + + + +``` + +# Algorithme de Dijkstra + +## Idée générale + +* On assigne à chaque noeud une distance $0$ pour $s$, $\infty$ pour les autres. +* Tous les noeuds sont marqués non-visités. +* Depuis du noeud courant, on suit chaque arête du noeud vers un sommet non visité et on calcule le poids du chemin à chaque voisin et on met à jour sa distance si elle est plus petite que la distance du noeud. +* Quand tous les voisins du noeud courant ont été visités, le noeud est mis à visité (il ne sera plus jamais visité). +* Continuer avec le noeud à la distance la plus faible. +* L'algorithme est terminé losrque le noeud de destination est marqué comme visité, ou qu'on a plus de noeuds qu'on peut visiter et que leur distance est infinie. + +# Algorithme de Dijkstra + +## Pseudo-code (5min, matrix) + +. . . + +```C +tab dijkstra(graph, s, t) + pour chaque v dans graphe + distance[v] = infini + q = ajouter(q, v) + distance[s] = 0 + tant que non_vide(q) + u = min(q, distance) // plus petite distance dans q + si u == t + retourne distance + q = remove(q, u) + pour chaque v dans voisinage(u, q) // voisin de u encore dans q + n_distance = distance[u] + w(i, v) + si n_distance < distance[v] + distance[v] = n_distance + retourne distance +``` + +# Algorithme de Dijkstra + +* Cet algorithme, nous donne le plus court chemin mais... +* ne nous donne pas le chemin! + +## Comment modifier l'algorithme pour avoir le chemin? + +. . . + +* Pour chaque nouveau noeud à visiter, il suffit d'enregistrer d'où on est venu! +* On a besoin d'un tableau `précédent`. + +## Modifier le pseudo-code ci-dessus pour ce faire (3min matrix) + +# Algorithme de Dijkstra + +```C +tab, tab dijkstra(graph, s, t) + pour chaque v dans graphe + distance[v] = infini + précédent[v] = indéfini + q = ajouter(q, v) + distance[s] = 0 + tant que non_vide(q) + u = min(q, distance) // plus petite distance dans q + si u == t + retourne distance + q = remove(q, u) + pour chaque v dans voisinage(u, q) // voisin de u encore dans q + n_distance = distance[u] + w(i, v) + si n_distance < distance[v] + distance[v] = n_distance + précédent[v] = u + retourne distance, précédent +``` + +## Comment faire pour avoir toutes les plus petites distances à tous les autres noeuds? \ No newline at end of file