Partie L7 · exercices 45 à 49

Le plus court chemin

L'algorithme de Dijkstra, à la main, animé et en Python

CoursGraphes pondérés

Dans un graphe pondéré, chaque arête porte un nombre, son poids : une distance en km, une durée en minutes, un prix… La longueur d'une chaîne est alors la somme des poids de ses arêtes.

Les GPS et les sites d'itinéraires cherchent la chaîne de plus petit poids entre deux sommets. L'algorithme le plus célèbre pour cela a été inventé par Edsger Dijkstra en 1956.

MéthodeL'algorithme de Dijkstra, version dessin

  1. Au départ : écris 0 sur le sommet de départ et ∞ sur tous les autres.
  2. Choisis le sommet non traité qui a la plus petite valeur : c'est le sommet actif. Entoure-le.
  3. Regarde ses voisins non traités. Pour chacun, calcule : valeur du sommet actif + poids de l'arête.
  4. Si ce nombre est plus petit que la valeur du voisin : remplace la valeur, trace en couleur l'arête qui vient du sommet actif, et raye l'ancienne arête colorée qui arrivait à ce voisin (s'il y en avait une).
  5. Si ce nombre est plus grand ou égal : ne change rien.
  6. Le sommet actif est maintenant traité : encadre sa valeur, elle ne changera plus.
  7. Recommence à l'étape 2 jusqu'à ce que tous les sommets soient traités.

À la fin, la valeur de chaque sommet est sa distance au départ, et les arêtes colorées forment les plus courts chemins.

3 2 2 1 4 5 5 5 2 2 A B C F E D
Graphe de la fiche méthode : distances depuis A.

Exemple : le graphe de la fiche méthode, depuis A

  1. Départ : 0 sur A, ∞ sur tous les autres sommets.
  2. Sommet actif A. B reçoit 3 et E reçoit 2 : on trace A–B et A–E.
  3. Sommet actif E (car 2 < 3). F reçoit 2 + 5 = 7 et D reçoit 2 + 5 = 7 : on trace E–F et E–D. Vers B : 2 + 5 = 7, plus grand que 3, rien à faire.
  4. Sommet actif B (3). Vers F : 3 + 1 = 4 < 7, on raye E–F et on trace B–F. Vers D : 3 + 4 = 7, égalité, rien à faire. Vers C : 3 + 2 = 5, on trace B–C.
  5. Sommet actif F (4). Vers D : 4 + 2 = 6 < 7, on raye E–D et on trace F–D.
  6. Sommet actif C (5). Vers D : 5 + 2 = 7, pas mieux que 6, rien à faire.
  7. Dernier sommet D (6) : terminé.

Pour aller de A à D : A–B–F–D, longueur 6. Pour aller en C : A–B–C, longueur 5.

Vigilance

En cas d'égalité (par exemple B → D donne 7, comme E → D), on ne change rien : l'ancien chemin est aussi court.

Une valeur encadrée (sommet traité) ne change plus jamais.

Voir l'algorithme en action

L'animation Dijkstra rejoue l'algorithme pas à pas sur les graphes du cours. En mode pédagogique, c'est toi qui choisis le sommet suivant et qui calcules les distances. Tu peux aussi y construire ton propre graphe.

ExercicesChercher le plus court chemin

EX 45Je m'entraîne 🌶️🌶️application

Exercice 45 — De A à F

3 1 2 2 3 5 1 3 1 A B C D E F
Les nombres sont des distances en kilomètres.
  1. Applique l'algorithme de Dijkstra depuis A, en redessinant le graphe à chaque étape comme dans la méthode.
  2. Quel est le plus court chemin de A à F ? Quelle est sa longueur ?
  3. Vérifie avec l'animation (graphe « TP : de A à F »).
Indice 1

Premier sommet actif : A. Ses voisins B et C reçoivent 3 et 1.

Indice 2

Deuxième sommet actif : C (valeur 1).

📝 réponses dans ton compte rendu, exercice 45

EX 46Je m'entraîne 🌶️🌶️🌶️plusieurs étapes

Exercice 46 — Un dernier pour la route

9 20 12 8 21 11 4 7 5 3 13 9 S A U V I B E
Graphe à sept sommets.
  1. Applique l'algorithme de Dijkstra depuis S, en redessinant le graphe à chaque étape.
  2. Quel est le plus court chemin de S à E ? Sa longueur ?
  3. Le chemin direct S–U fait 20. Pourquoi n'est-il pas utilisé ?
Indice

Un chemin avec plus d'arêtes peut être plus court qu'une arête directe.

📝 réponses dans ton compte rendu, exercice 46

EX 47Je m'entraîne 🌶️🌶️application

Exercice 47 — Mon graphe dans l'animation

Dans l'animation, choisis l'exemple « Un dernier pour la route », passe en mode pédagogique et refais l'algorithme depuis S : c'est toi qui choisis chaque sommet et qui calcules les distances.

Puis, dans « Construire mon propre graphe », invente un graphe de 6 sommets où le chemin le plus court entre deux sommets utilise au moins 4 arêtes. Fais une capture d'écran.

Indice

Dans « Construire mon propre graphe », une ligne = une arête : ses deux sommets et son poids.

📝 réponses dans ton compte rendu, exercice 47

PythonDes itinéraires réels

Le module pyroutelib3 calcule un vrai itinéraire en téléchargeant les rues d'OpenStreetMap, puis en appliquant un algorithme de plus court chemin de la famille de Dijkstra.

  1. Installe le module pyroutelib3 comme tu as installé Folium.
  2. Copie et exécute le programme ci-dessous (il faut une connexion Internet : le premier calcul peut prendre une minute).
itineraire.py
import folium
import pyroutelib3

# le réseau des chemins piétons, téléchargé au fur et à mesure
graphe = pyroutelib3.osm.LiveGraph(pyroutelib3.osm.FootProfile())

depart = graphe.find_nearest_node((44.16213, 4.617122))
arrivee = graphe.find_nearest_node((44.163942, 4.611689))
chemin = pyroutelib3.find_route_without_turn_around(graphe, depart.id, arrivee.id)
points = [graphe.get_node(n).position for n in chemin]

carte = folium.Map(location=[44.163, 4.614], zoom_start=16)
folium.PolyLine(points, color="red", weight=5).add_to(carte)
folium.Marker(points[0], popup="Départ").add_to(carte)
folium.Marker(points[-1], popup="Arrivée").add_to(carte)
carte.save("itineraire.html")
EX 48Je m'entraîne 🌶️🌶️application

Exercice 48 — Mon itinéraire

  1. Exécute le programme et ouvre itineraire.html. Combien de points la variable points contient-elle ? (Ajoute print(len(points)).)
  2. Modifie le programme pour tracer un itinéraire à pied de ton choix, par exemple de la gare au lycée.
  3. Remplace FootProfile() par CarProfile(). Le trajet change-t-il ? Pourquoi ?
  4. Compare la longueur de ton trajet à pied avec celle donnée par l'outil Itinéraire de cartes.gouv.fr.
Indice

FootProfile suit les chemins piétons, CarProfile les routes ouvertes aux voitures (et leurs sens interdits).

💾 NOM_Prenom_ex48.py

EX 49Je m'entraîne 🌶️🌶️🌶️🌶️défi

Exercice 49 — Dijkstra en Python

Défi : voici un programme qui applique l'algorithme de Dijkstra. Le graphe est un dictionnaire : pour chaque sommet, la liste de ses voisins avec le poids de l'arête.

dijkstra.py
graphe = {
    "A": {"B": 3, "E": 2},
    "B": {"A": 3, "C": 2, "D": 4, "E": 5, "F": 1},
    "C": {"B": 2, "D": 2},
    "D": {"B": 4, "C": 2, "E": 5, "F": 2},
    "E": {"A": 2, "B": 5, "D": 5, "F": 5},
    "F": {"B": 1, "D": 2, "E": 5},
}

def dijkstra(graphe, depart):
    distance = {s: float("inf") for s in graphe}
    venant_de = {s: None for s in graphe}
    distance[depart] = 0
    a_traiter = list(graphe)
    while a_traiter:
        actif = min(a_traiter, key=lambda s: distance[s])
        a_traiter.remove(actif)
        for voisin, poids in graphe[actif].items():
            if distance[actif] + poids < distance[voisin]:
                distance[voisin] = distance[actif] + poids
                venant_de[voisin] = actif
    return distance, venant_de

def chemin(venant_de, arrivee):
    etapes = [arrivee]
    while venant_de[etapes[0]] is not None:
        etapes.insert(0, venant_de[etapes[0]])
    return "-".join(etapes)

distance, venant_de = dijkstra(graphe, "A")
for s in distance:
    print(s, distance[s], chemin(venant_de, s))
  1. Exécute le programme : retrouves-tu les résultats de la fiche méthode ?
  2. Modifie le dictionnaire pour qu'il représente le graphe de l'exercice 45, et vérifie ta réponse.
  3. Fais de même pour le graphe de l'exercice 46.
Indice

Chaque arête apparaît deux fois dans le dictionnaire : une fois dans chaque sens.

💾 NOM_Prenom_ex49.py

Synthèse

  • Dans un graphe pondéré, la longueur d'une chaîne est la somme des poids.
  • Dijkstra : on fixe à chaque étape le sommet non traité le plus proche du départ, et on améliore ses voisins.
  • Les GPS utilisent des algorithmes de la même famille sur le graphe des routes.