Apprentissage interactif de la théorie des graphes
Apprentissage interactif de la théorie des graphes
Guest User
Using app without sign in
Calculateur interactif de plus court chemin
Trouve les plus courts chemins depuis la source vers tous les sommets
Sélectionnez un algorithme et générez les étapes pour commencer la visualisation
L'algorithme de Dijkstra calcule le plus court chemin d'un nœud source vers tous les autres nœuds dans un graphe pondéré à poids d'arêtes non négatifs. Publié par Edsger Dijkstra en 1959, il reste l'algorithme standard de plus court chemin à source unique et la base de la plupart des systèmes de routage pratiques.
L'algorithme maintient une distance provisoire pour chaque nœud, initialement infinie sauf la source à zéro. À l'aide d'une file de priorité, il extrait de façon répétée le nœud non réglé de plus petite distance provisoire, le déclare définitif et relâche chaque arête sortante : si le chemin par le nœud courant est plus court que la distance enregistrée du voisin, celle-ci est mise à jour. Avec un tas binaire, cela s'exécute en O((V + E) log V). Les poids non négatifs sont essentiels ; une arête négative peut invalider des nœuds déjà réglés.
L'algorithme de Dijkstra alimente la navigation GPS, les protocoles de routage internet comme OSPF, les planificateurs de vols et de transports, et l'analyse de latence réseau. Il apparaît aussi dans les jeux pour la recherche de chemin en l'absence d'heuristique. En entretien, c'est la réponse canonique aux questions de plus court chemin pondéré et le point de départ pour A* et Bellman-Ford.
Dijkstra est un algorithme glouton dont la correction repose sur une seule affirmation: le sommet non fixé le plus proche ne pourra plus être amélioré. Une file de priorité fournit ce sommet en O(log V).
Dijkstra(graphe, source):
pour chaque sommet v: dist[v] = infini
dist[source] = 0
fp = file de priorité contenant (0, source)
tant que fp est non vide:
(d, u) = fp.extraireMin()
si d > dist[u]: continuer // entrée périmée
pour chaque arête (u, v, w):
si dist[u] + w < dist[v]:
dist[v] = dist[u] + w
parent[v] = u
fp.inserer((dist[v], v))Le test des entrées périmées compte. Plutôt que de diminuer la clé dans le tas, ce que la plupart des bibliothèques standard ne permettent pas, l'usage est d'insérer une entrée en double et d'ignorer toute entrée dont la distance enregistrée ne correspond plus. Cela s'appelle la suppression paresseuse, et c'est pourquoi la file peut contenir jusqu'à E entrées plutôt que V.
Exécute Dijkstra depuis A sur un graphe pondéré où le choix glouton paie, en observant grandir l'ensemble des sommets fixés.
Graphe d'exemple: Arêtes non orientées A-B (4), A-C (2), C-B (1), B-D (5) et C-D (8).
Les distances finales sont A 0, C 2, B 3, D 8, et le plus court chemin vers D passe par A, C, B puis D. Remarque que l'arête directe A-B de poids 4 n'est jamais utilisée: passer par C coûte 3. Remarque aussi que les sommets sont fixés dans l'ordre des distances 0, 2, 3, 8, ce qui est exactement la propriété sur laquelle repose l'argument glouton.
Temps: O((V + E) log V) · Espace: O(V)
Avec un tas binaire, chacun des V sommets est extrait une fois en O(log V), et chacune des E arêtes peut déclencher une insertion en O(log V), d'où O((V + E) log V). Avec la suppression paresseuse, le tas contient jusqu'à E entrées, donc l'extraction coûte O(log E), mais comme E vaut au plus V au carré, log E vaut au plus 2 log V et la borne ne change pas. Un tas de Fibonacci améliore la borne théorique en O(E + V log V) car la diminution de clé devient O(1) amorti, mais les constantes sont assez mauvaises pour que les tas binaires l'emportent en pratique. Sur un graphe dense, un simple parcours de tableau pour trouver le minimum donne O(V au carré), ce qui bat le tas dès que E approche V au carré.
Dijkstra est le choix par défaut pour les plus courts chemins pondérés. Ce qui le remplace dépend de celle de ses hypothèses que ton graphe enfreint.
| Alternative | À préférer quand | Coût |
|---|---|---|
| BFS | Toutes les arêtes ont le même poids, donc le nombre de sauts est la distance. Strictement plus rapide. | O(V + E) |
| Bellman-Ford | Un poids d'arête est négatif, ce qui casse l'argument glouton de fixation. | O(VE) |
| Recherche A* | Tu vises une cible précise et disposes d'une heuristique admissible, comme la distance à vol d'oiseau sur une carte. | O((V + E) log V) au pire |
| Floyd-Warshall | Tu veux toutes les distances entre paires et le graphe est petit ou dense. | O(V^3) |
| Dijkstra bidirectionnel | Une source, une cible, un grand graphe, et des arêtes parcourables en sens inverse. | environ moitié moins de sommets explorés |
Lire l'article complet: Shortest Path Algorithms Explained
Algorithmes associés: Algorithme de Bellman-Ford, Algorithme de Floyd-Warshall, Recherche en Largeur (BFS)