* 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?