Dans cet article, nous discuterons de l'un des algorithmes de chemin le plus court les plus connus, à savoir l'algorithme de chemin le plus court de Dijkstra, développé par l'informaticien néerlandais Edsger W. Dijkstra en 1956. De plus, nous effectuerons une analyse de complexité pour cet algorithme et également voyez en quoi il diffère des autres algorithmes du chemin le plus court.
Table des matières
- L'algorithme de Dijkstra
- Nécessité de l'algorithme de Dijkstra (objectif et cas d'utilisation)
- L'algorithme de Dijkstra peut-il fonctionner à la fois sur des graphes orientés et non orientés ?
- Algorithme pour l'algorithme de Dijkstra
- Comment fonctionne l’algorithme de Dijkstra ?
- Pseudo-code pour l'algorithme de Dijkstra
- Implémentation de l’algorithme de Dijkstra :
- Algorithmes de Dijkstra vs algorithme de Bellman-Ford
- Algorithme de Dijkstra vs algorithme de Floyd-Warshall
- Algorithme de Dijkstra vs algorithme A*
- Problèmes pratiques sur l’algorithme de Dijkstra
- Conclusion:

L'algorithme de Dijkstra :
L'algorithme de Dijkstra est un algorithme populaire pour résoudre de nombreux problèmes de chemin le plus court à source unique ayant un poids d'arête non négatif dans les graphiques, c'est-à-dire qu'il s'agit de trouver la distance la plus courte entre deux sommets sur un graphique. Il a été conçu par un informaticien néerlandais Edsger W. Dijkstra en 1956.
L'algorithme maintient un ensemble de sommets visités et un ensemble de sommets non visités. Il commence au sommet source et sélectionne de manière itérative le sommet non visité avec la plus petite distance provisoire par rapport à la source. Il visite ensuite les voisins de ce sommet et met à jour leurs distances provisoires si un chemin plus court est trouvé. Ce processus se poursuit jusqu'à ce que le sommet de destination soit atteint ou que tous les sommets accessibles aient été visités.
Nécessité de l'algorithme de Dijkstra (objectif et cas d'utilisation)
Le besoin de l’algorithme de Dijkstra se fait sentir dans de nombreuses applications où la recherche du chemin le plus court entre deux points est cruciale.
Par exemple , Il peut être utilisé dans les protocoles de routage des réseaux informatiques et également utilisé par les systèmes cartographiques pour trouver le chemin le plus court entre le point de départ et la destination (comme expliqué dans Comment fonctionne Google Maps ? )
L'algorithme de Dijkstra peut-il fonctionner à la fois sur des graphes orientés et non orientés ?
Oui , l'algorithme de Dijkstra peut fonctionner à la fois sur des graphiques orientés et sur des graphiques non orientés, car cet algorithme est conçu pour fonctionner sur tout type de graphique tant qu'il répond aux exigences d'avoir des poids de bord non négatifs et d'être connecté.
- Dans un graphe orienté, chaque arête a une direction, indiquant la direction de déplacement entre les sommets reliés par l'arête. Dans ce cas, l’algorithme suit la direction des bords lors de la recherche du chemin le plus court.
- Dans un graphe non orienté, les bords n'ont pas de direction et l'algorithme peut parcourir à la fois vers l'avant et vers l'arrière le long des bords lors de la recherche du chemin le plus court.
Algorithme pour l'algorithme de Dijkstra:
- Marquez le nœud source avec une distance actuelle de 0 et le reste avec l'infini.
- Définissez le nœud non visité avec la plus petite distance actuelle comme nœud actuel.
- Pour chaque voisin, N du nœud courant ajoute la distance actuelle du nœud adjacent avec le poids de l'arête reliant 0->1. Si elle est inférieure à la distance actuelle du nœud, définissez-la comme la nouvelle distance actuelle de N.
- Marquez le nœud actuel 1 comme visité.
- Passez à l'étape 2 si certains nœuds ne sont pas visités.
Comment fonctionne l’algorithme de Dijkstra ?
Voyons comment fonctionne l'algorithme de Dijkstra avec un exemple donné ci-dessous :
L'algorithme de Dijkstra générera le chemin le plus court du nœud 0 à tous les autres nœuds du graphique.
Considérez le graphique ci-dessous :
L'algorithme de Dijkstra
L'algorithme générera le chemin le plus court du nœud 0 à tous les autres nœuds du graphique.
Pour ce graphique, nous supposerons que le poids des arêtes représente la distance entre deux nœuds.
chaîne booléenne javaComme nous pouvons voir que nous avons le chemin le plus court depuis,
Nœud 0 à Nœud 1, de
Nœud 0 à Nœud 2, de
Nœud 0 à Nœud 3, de
Nœud 0 à Nœud 4, de
Nœud 0 à nœud 6.Dans un premier temps, nous avons un ensemble de ressources ci-dessous :
- La distance entre le nœud source et lui-même est 0. Dans cet exemple, le nœud source est 0.
- La distance entre le nœud source et tous les autres nœuds est inconnue, nous les marquons donc tous comme infini.
Exemple : 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.
- nous aurons également un tableau d'éléments non visités qui garderont une trace des nœuds non visités ou non marqués.
- L'algorithme se terminera lorsque tous les nœuds marqués comme visités et la distance entre eux seront ajoutés au chemin. Nœuds non visités : - 0 1 2 3 4 5 6.
Étape 1: Commencez à partir du nœud 0 et marquez le nœud comme visité car vous pouvez vérifier l'image ci-dessous. Le nœud visité est marqué en rouge.
L'algorithme de Dijkstra
Étape 2: Vérifiez les nœuds adjacents, nous devons maintenant choisir (soit choisir le nœud 1 avec une distance de 2, soit choisir le nœud 2 avec une distance de 6) et choisir le nœud avec une distance minimale. Dans cette étape Nœud 1 est la distance minimale adjacente au nœud, alors marquez-le comme visité et additionnez la distance.
Distance : Nœud 0 -> Nœud 1 = 2
L'algorithme de Dijkstra
Étape 3: Ensuite, avancez et recherchez le nœud adjacent qui est le nœud 3, alors marquez-le comme visité et additionnez la distance. Maintenant, la distance sera :
Distance : Nœud 0 -> Nœud 1 -> Nœud 3 = 2 + 5 = 7
L'algorithme de Dijkstra
Étape 4: Encore une fois, nous avons deux choix pour les nœuds adjacents (soit nous pouvons choisir le nœud 4 avec une distance de 10, soit nous pouvons choisir le nœud 5 avec une distance de 15), alors choisissez le nœud avec une distance minimale. Dans cette étape Nœud 4 est la distance minimale adjacente au nœud, alors marquez-le comme visité et additionnez la distance.
Distance : Nœud 0 -> Nœud 1 -> Nœud 3 -> Nœud 4 = 2 + 5 + 10 = 17
L'algorithme de Dijkstra
produit scalaire numpyÉtape 5 : Encore une fois, avancez et vérifiez le nœud adjacent qui est Nœud 6 , alors marquez-le comme visité et additionnez la distance. Maintenant, la distance sera :
Distance : Nœud 0 -> Nœud 1 -> Nœud 3 -> Nœud 4 -> Nœud 6 = 2 + 5 + 10 + 2 = 19
L'algorithme de Dijkstra
Ainsi, la distance la plus courte depuis le sommet source est de 19, ce qui est optimal.
Pseudo-code pour l'algorithme de Dijkstra
fonction Dijkstra (Graphique, source):
// Initialise les distances à tous les nœuds à l'infini et au nœud source à 0.distances = carte (tous les nœuds -> infini)
distances = 0
convertir nfa en dfa// Initialise un ensemble vide de nœuds visités et une file d'attente prioritaire pour garder une trace des nœuds à visiter.
visité = ensemble vide
file d'attente = nouvelle PriorityQueue()
file d'attente.enqueue(source, 0)// Boucle jusqu'à ce que tous les nœuds aient été visités.
alors que la file d'attente n'est pas vide :
// Supprime la file d'attente du nœud le plus éloigné de la file d'attente prioritaire.
actuel = file d'attente.dequeue()// Si le nœud a déjà été visité, ignorez-le.
si actuellement visité :
continuer// Marque le nœud comme visité.
visité.ajouter (actuel)// Vérifiez tous les nœuds voisins pour voir si leurs distances doivent être mises à jour.
pour le voisin dans Graph.neighbors (current):
// Calcule la distance provisoire jusqu'au voisin via le nœud actuel.
provisoire_distance = distances[actuel] + Graph.distance(actuel, voisin)// Si la distance provisoire est inférieure à la distance actuelle par rapport au voisin, mettez à jour la distance.
si provisoire_distance
distances[voisin] = tentative_distance// Mettez le voisin en file d'attente avec sa nouvelle distance pour qu'il soit pris en compte pour une visite future.
queue.enqueue(voisin, distances[voisin])// Renvoie les distances calculées de la source à tous les autres nœuds du graphique.
distances de retour
Implémentation de l’algorithme de Dijkstra :
Il existe plusieurs façons d’implémenter l’algorithme de Dijkstra, mais les plus courantes sont :
- File d'attente prioritaire (implémentation basée sur le tas) :
- Implémentation basée sur un tableau :
1. Algorithme de chemin le plus court de Dijkstra utilisant Priority_queue (Heap)
Dans cette implémentation, nous recevons un graphe et un sommet source dans le graphe, trouvant les chemins les plus courts depuis la source vers tous les sommets du graphe donné.
Exemple:
Saisir: Origine = 0
bash si sinonExemple
Sortir: Sommet
Distance du sommet à la source
0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19
Vous trouverez ci-dessous l'algorithme basé sur l'idée ci-dessus :
- Initialisez les valeurs de distance et la file d'attente prioritaire.
- Insérez le nœud source dans la file d'attente prioritaire avec une distance de 0.
- Tant que la file d'attente prioritaire n'est pas vide :
- Extrayez le nœud avec la distance minimale de la file d'attente prioritaire.
- Mettez à jour les distances de ses voisins si un chemin plus court est trouvé.
- Insérez les voisins mis à jour dans la file d'attente prioritaire.
Vous trouverez ci-dessous l'implémentation C++ de l'approche ci-dessus :
C++ // Program to find Dijkstra's shortest path using // priority_queue in STL #include using namespace std; #define INF 0x3f3f3f3f // iPair ==>Paire de types de paires entières iPaire ; // Cette classe représente un graphe orienté en utilisant // la classe de représentation de liste de contiguïté Graph { int V; // Nombre de sommets // Dans un graphe pondéré, nous devons stocker le sommet // et la paire de poids pour chaque liste d'arêtes>* adj; public : Graphique (int V ); // Constructeur // fonction pour ajouter une arête au graphique void addEdge(int u, int v, int w); // affiche le chemin le plus court depuis s void shortPath(int s); } ; // Alloue de la mémoire pour la liste de contiguïté Graph::Graph(int V) { this->V = V; adj = nouvelle liste [V] ; } void Graph::addEdge(int u, int v, int w) { adj[u].push_back(make_pair(v, w)); adj[v].push_back(make_pair(u, w)); } // Imprime les chemins les plus courts de src vers tous les autres sommets void Graph::shortestPath(int src) { // Crée une file d'attente prioritaire pour stocker les sommets qui // sont en cours de prétraitement. C'est une syntaxe étrange en C++. // Reportez-vous au lien ci-dessous pour plus de détails sur cette syntaxe // https://www.techcodeview.com priorité_queue , plus grand > pq; // Crée un vecteur pour les distances et initialise toutes // les distances en tant que vecteur infini (INF) dist(V,INF); // Insère la source elle-même dans la file d'attente prioritaire et initialise // sa distance à 0. pq.push(make_pair(0, src)); dist[src] = 0; /* Boucle jusqu'à ce que la file d'attente prioritaire soit vide (ou que toutes les distances ne soient pas finalisées) */ while (!pq.empty()) { // Le premier sommet de la paire est la distance minimale // le sommet, extrayez-le de la file d'attente prioritaire. // l'étiquette du sommet est stockée dans la seconde de la paire (cela // doit être fait de cette façon pour conserver les sommets // la distance triée (la distance doit être le premier élément // de la paire) int u = pq.top().second; pq.pop(); // 'i' est utilisé pour obtenir tous les sommets adjacents d'une // liste de sommets>::itérateur i ; for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Récupère l'étiquette du sommet et le poids du courant // adjacent à u. int v = (*i).premier; int poids = (*i).seconde; // S'il existe un chemin raccourci vers v via u. if (dist[v]> dist[u] + poids) { // Mise à jour de la distance de v dist[v] = dist[u] + poids; pq.push(make_pair(dist[v], v)); } } } // Imprimer les distances les plus courtes stockées dans dist[] printf('Distance du sommet depuis la source
'); pour (int je = 0; je< V; ++i) printf('%d %d
', i, dist[i]); } // Driver program to test methods of graph class int main() { // create the graph given in above figure int V = 7; Graph g(V); // making above shown graph g.addEdge(0, 1, 2); g.addEdge(0, 2, 6); g.addEdge(1, 3, 5); g.addEdge(2, 3, 8); g.addEdge(3, 4, 10); g.addEdge(3, 5, 15); g.addEdge(4, 6, 2); g.addEdge(5, 6, 6); g.shortestPath(0); return 0; }>
Java import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.PriorityQueue; public class DijkstraAlgoForShortestDistance { static class Node implements Comparable{ à la TV; distance intérieure ; Nœud public (int v, int distance) { this.v = v; this.distance = distance; } @Override public int compareTo(Node n) { if (this.distance<= n.distance) { return -1; } else { return 1; } } } static int[] dijkstra( int V, ArrayList >> adj, int S) { boolean[] visité = new boolean[V]; Carte de hachage carte = nouveau HashMap(); File d'attente de prioritéq = nouvelle PriorityQueue(); map.put(S, nouveau nœud(S, 0)); q.add(nouveau nœud(S, 0)); while (!q.isEmpty()) { Nœud n = q.poll(); int v = n.v; int distance = n.distance; visité[v] = vrai; Liste des tableaux > adjList = adj.get(v); pour (ArrayList adjLink : adjList) { if (visited[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), new Node (v, distance + adjLink.get(1))); } else { Nœud sn = map.get(adjLink.get(0)); si (distance + adjLink.get(1)< sn.distance) { sn.v = v; sn.distance = distance + adjLink.get(1); } } q.add(new Node(adjLink.get(0), distance + adjLink.get(1))); } } } int[] result = new int[V]; for (int i = 0; i < V; i++) { result[i] = map.get(i).distance; } return result; } public static void main(String[] args) { ArrayList >> adj = new ArrayList(); Carte de hachage >> carte = new HashMap(); entier V = 6 ; entier E = 5 ; int[] u = { 0, 0, 1, 2, 4 }; int[] v = {3, 5, 4, 5, 5 }; int[] w = {9, 4, 4, 10, 3 }; pour (int je = 0; je< E; i++) { ArrayList bord = new ArrayList(); edge.add(v[i]); edge.add(w[i]); Liste des tableaux > adjListe ; if (!map.containsKey(u[i])) { adjList = new ArrayList(); } else { adjList = map.get(u[i]); } adjList.add(edge); map.put(u[i], adjList); Liste des tableaux edge2 = new ArrayList(); edge2.add(u[i]); edge2.add(w[i]); Liste des tableaux > listeadj2 ; if (!map.containsKey(v[i])) { adjList2 = new ArrayList(); } else { adjList2 = map.get(v[i]); } adjList2.add(edge2); map.put(v[i], adjList2); } pour (int je = 0; je< V; i++) { if (map.containsKey(i)) { adj.add(map.get(i)); } else { adj.add(null); } } int S = 1; // Input sample //[0 [[3, 9], [5, 4]], // 1 [[4, 4]], // 2 [[5, 10]], // 3 [[0, 9]], // 4 [[1, 4], [5, 3]], // 5 [[0, 4], [2, 10], [4, 3]] //] int[] result = DijkstraAlgoForShortestDistance.dijkstra( V, adj, S); System.out.println(Arrays.toString(result)); } }> Python # Python implementation of Dijkstra Algorithm import heapq class Node: def __init__(self, v, distance): self.v = v self.distance = distance def __lt__(self, other): return self.distance < other.distance def dijkstra(V, adj, S): visited = [False] * V map = {} q = [] map[S] = Node(S, 0) heapq.heappush(q, Node(S, 0)) while q: n = heapq.heappop(q) v = n.v distance = n.distance visited[v] = True adjList = adj[v] for adjLink in adjList: if not visited[adjLink[0]]: if adjLink[0] not in map: map[adjLink[0]] = Node(v, distance + adjLink[1]) else: sn = map[adjLink[0]] if distance + adjLink[1] < sn.distance: sn.v = v sn.distance = distance + adjLink[1] heapq.heappush(q, Node(adjLink[0], distance + adjLink[1])) result = [0] * V for i in range(V): result[i] = map[i].distance return result def main(): adj = [[] for _ in range(6)] V = 6 E = 5 u = [0, 0, 1, 2, 4] v = [3, 5, 4, 5, 5] w = [9, 4, 4, 10, 3] for i in range(E): edge = [v[i], w[i]] adj[u[i]].append(edge) edge2 = [u[i], w[i]] adj[v[i]].append(edge2) S = 1 result = dijkstra(V, adj, S) print(result) if __name__ == '__main__': main() # This code is contributed by ragul21> C# // C# Code: using System; using System.Collections.Generic; public class Graph { // No. of vertices private int V; // adjacency list private List>[] adj; // Constructeur public Graph(int v) { V = v; adj = nouvelle liste>[ v ]; pour (int je = 0; je< v; ++i) adj[i] = new List>(); } // fonction pour ajouter une arête au graphique public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w)); adj[v].Add(Tuple.Create(u, w)); } // affiche le chemin le plus court depuis s public void shortPath(int s) { // Crée une file d'attente prioritaire pour stocker les sommets qui // sont en cours de prétraitement. var pq = nouvelle PriorityQueue>(); // Crée un vecteur pour les distances et initialise toutes // les distances comme infinies (INF) var dist = new int[V]; pour (int je = 0; je< V; i++) dist[i] = int.MaxValue; // Insert source itself in priority queue and // initialize its distance as 0. pq.Enqueue(Tuple.Create(0, s)); dist[s] = 0; /* Looping till priority queue becomes empty (or all distances are not finalized) */ while (pq.Count != 0) { // The first vertex in pair is the minimum // distance vertex, extract it from priority // queue. vertex label is stored in second of // pair (it has to be done this way to keep the // vertices sorted distance (distance must be // first item in pair) var u = pq.Dequeue().Item2; // 'i' is used to get all adjacent vertices of a // vertex foreach(var i in adj[u]) { // Get vertex label and weight of current // adjacent of u. int v = i.Item1; int weight = i.Item2; // If there is shorted path to v through u. if (dist[v]>dist[u] + poids) { // Mise à jour de la distance de v dist[v] = dist[u] + poids; pq.Enqueue(Tuple.Create(dist[v], v)); } } } // Imprimer les distances les plus courtes stockées dans dist[] Console.WriteLine('Vertex Distance from Source'); pour (int je = 0; je< V; ++i) Console.WriteLine('{0} {1}', i, dist[i]); } } public class PriorityQueue{ Liste privée en lecture seule_données; comparaison privée en lecture seule_compare; public PriorityQueue() : this(Comparer.Default) { } public PriorityQueue (IComparercomparer) : this(comparer.Compare) { } public PriorityQueue(Comparisoncomparaison) { _data = nouvelle liste(); _compare = comparaison ; } public void Enqueue (élément T) { _data.Add (élément); var childIndex = _data.Count - 1; while (childIndex> 0) { var parentIndex = (childIndex - 1) / 2; if (_compare(_data[childIndex], _data[parentIndex])>= 0) break; T tmp = _data[childIndex]; _data[childIndex] = _data[parentIndex]; _data[parentIndex] = tmp; enfantIndex = parentIndex; } } public T Dequeue() { // suppose que pq n'est pas vide ; jusqu'à appeler le code var lastElement = _data.Count - 1; var frontItem = _data[0]; _data[0] = _data[lastElement]; _data.RemoveAt(lastElement); --dernierÉlément ; varparentIndex = 0; while (true) { var childIndex = parentIndex * 2 + 1; if (childIndex> lastElement) break ; // Fin de l'arborescence var rightChild = childIndex + 1; si (droitEnfant<= lastElement && _compare(_data[rightChild], _data[childIndex]) < 0) childIndex = rightChild; if (_compare(_data[parentIndex], _data[childIndex]) <= 0) break; // Correct position T tmp = _data[parentIndex]; _data[parentIndex] = _data[childIndex]; _data[childIndex] = tmp; parentIndex = childIndex; } return frontItem; } public T Peek() { T frontItem = _data[0]; return frontItem; } public int Count { get { return _data.Count; } } } class Program { // Driver program to test methods of graph class static void Main(string[] args) { // create the graph given in above figure int V = 7; Graph g = new Graph(V); // making above shown graph g.addEdge(0, 1, 2); g.addEdge(0, 2, 6); g.addEdge(1, 3, 5); g.addEdge(2, 3, 8); g.addEdge(3, 4, 10); g.addEdge(3, 5, 15); g.addEdge(4, 6, 2); g.addEdge(5, 6, 6); g.shortestPath(0); } }> Javascript class PriorityQueue { constructor() { this.queue = []; } enqueue(element, priority) { this.queue.push({ element, priority }); this.queue.sort((a, b) =>a.priorité - b.priorité); } dequeue() { if (this.isEmpty()) { return null ; } renvoie this.queue.shift().element; } isEmpty() { return this.queue.length === 0; } } classe Graph { constructeur (V) { this.V = V; this.adj = nouveau tableau (V); pour (soit i = 0; i< V; i++) { this.adj[i] = []; } } addEdge(u, v, w) { this.adj[u].push({ v, w }); this.adj[v].push({ v: u, w }); } shortestPath(src) { const pq = new PriorityQueue(); const dist = new Array(this.V).fill(Infinity); const visited = new Array(this.V).fill(false); pq.enqueue(src, 0); dist[src] = 0; while (!pq.isEmpty()) { const u = pq.dequeue(); if (visited[u]) continue; visited[u] = true; for (const { v, w } of this.adj[u]) { if (!visited[v] && dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.enqueue(v, dist[v]); } } } console.log('Vertex Distance from Source'); for (let i = 0; i < this.V; i++) { console.log(`${i} ${dist[i] === Infinity ? 'Infinity' : dist[i]}`); } } } function main() { const V = 7; const g = new Graph(V); g.addEdge(0, 1, 2); g.addEdge(0, 2, 6); g.addEdge(1, 3, 5); g.addEdge(2, 3, 8); g.addEdge(3, 4, 10); g.addEdge(3, 5, 15); g.addEdge(4, 6, 2); g.addEdge(5, 6, 6); g.shortestPath(0); } main();> Réponse finale:

Sortir
Analyse de complexité de l'algorithme de Dijkstra :
- Complexité temporelle : O((V + E)logV) , où V est le nombre de sommets et E est le nombre d’arêtes.
- Espace auxiliaire : O(V), où V est le nombre de sommets et E est le nombre d'arêtes du graphe.
2.Implémentation basée sur des tableaux de l'algorithme de Dijkstra (approche naïve) :
L'algorithme de Dijkstra peut également être implémenté à l'aide de tableaux sans utiliser de file d'attente prioritaire. Cette implémentation est simple mais peut être moins efficace, notamment sur les grands graphes.
L'algorithme procède de la manière suivante :
- Initialisez un tableau pour stocker les distances entre la source et chaque nœud.
- Marquez tous les nœuds comme non visités.
- Définissez la distance jusqu'au nœud source sur 0 et l'infini pour tous les autres nœuds.
- Répétez jusqu'à ce que tous les nœuds soient visités :
- Trouvez le nœud non visité avec la plus petite distance connue.
- Pour le nœud actuel, mettez à jour les distances de ses voisins non visités.
- Marquez le nœud actuel comme visité.
Analyse de complexité :
- Complexité temporelle : O(V^2) dans le pire des cas, où V est le nombre de sommets. Cela peut être amélioré en O(V^2) avec quelques optimisations.
- Espace auxiliaire : O(V), où V est le nombre de sommets et E est le nombre d'arêtes du graphe.
Algorithmes de Dijkstra vs algorithme de Bellman-Ford
L'algorithme de Dijkstra et Algorithme de Bellman-Ford sont tous deux utilisés pour trouver le chemin le plus court dans un graphique pondéré, mais ils présentent quelques différences clés. Voici les principales différences entre l’algorithme de Dijkstra et l’algorithme de Bellman-Ford :
| Fonctionnalité: | De Dijkstra | Bellman Ford |
|---|---|---|
| Optimisation | optimisé pour trouver le chemin le plus court entre un seul nœud source et tous les autres nœuds dans un graphique avec des poids de bord non négatifs | L'algorithme Bellman-Ford est optimisé pour trouver le chemin le plus court entre un seul nœud source et tous les autres nœuds dans un graphique avec des poids de bord négatifs. |
| Relaxation | L'algorithme de Dijkstra utilise une approche gourmande dans laquelle il choisit le nœud avec la plus petite distance et met à jour ses voisins. | l'algorithme de Bellman-Ford assouplit toutes les arêtes à chaque itération, mettant à jour la distance de chaque nœud en considérant tous les chemins possibles vers ce nœud |
| Complexité temporelle | L'algorithme de Dijkstra a une complexité temporelle de O(V^2) pour un graphe dense et O(E log V) pour un graphe clairsemé, où V est le nombre de sommets et E est le nombre d'arêtes du graphe. | L'algorithme de Bellman-Ford a une complexité temporelle de O(VE), où V est le nombre de sommets et E est le nombre d'arêtes du graphe. |
| Poids négatifs | L’algorithme de Dijkstra ne fonctionne pas avec les graphiques ayant des poids de bord négatifs, car il suppose que tous les poids de bord sont non négatifs. | L'algorithme de Bellman-Ford peut gérer les poids de bord négatifs et détecter les cycles de poids négatifs dans le graphique. |
Algorithme de Dijkstra vs algorithme de Floyd-Warshall
L'algorithme de Dijkstra et Algorithme de Floyd-Warshall sont tous deux utilisés pour trouver le chemin le plus court dans un graphique pondéré, mais ils présentent quelques différences clés. Voici les principales différences entre l’algorithme de Dijkstra et l’algorithme de Floyd-Warshall :
| Fonctionnalité: | De Dijkstra | Algorithme Floyd-Warshall |
|---|---|---|
| Optimisation | Optimisé pour trouver le chemin le plus court entre un seul nœud source et tous les autres nœuds dans un graphique avec des poids de bord non négatifs | L'algorithme Floyd-Warshall est optimisé pour trouver le chemin le plus court entre toutes les paires de nœuds d'un graphique. |
| Technique | L'algorithme de Dijkstra est un algorithme de chemin le plus court à source unique qui utilise une approche gloutonne et calcule le chemin le plus court depuis le nœud source vers tous les autres nœuds du graphique. | L'algorithme Floyd-Warshall, quant à lui, est un algorithme de chemin le plus court pour toutes les paires qui utilise la programmation dynamique pour calculer le chemin le plus court entre toutes les paires de nœuds du graphique. |
| Complexité temporelle | L'algorithme de Dijkstra a une complexité temporelle de O(V^2) pour un graphe dense et O(E log V) pour un graphe clairsemé, où V est le nombre de sommets et E est le nombre d'arêtes du graphe. | L'algorithme Floyd-Warshall, quant à lui, est un algorithme de chemin le plus court pour toutes les paires qui utilise la programmation dynamique pour calculer le chemin le plus court entre toutes les paires de nœuds du graphique. |
| Poids négatifs | L’algorithme de Dijkstra ne fonctionne pas avec les graphiques ayant des poids de bord négatifs, car il suppose que tous les poids de bord sont non négatifs. | L'algorithme Floyd-Warshall, quant à lui, est un algorithme de chemin le plus court pour toutes les paires qui utilise la programmation dynamique pour calculer le chemin le plus court entre toutes les paires de nœuds du graphique. |
Algorithme de Dijkstra vs algorithme A*
L'algorithme de Dijkstra et Un* algorithme sont tous deux utilisés pour trouver le chemin le plus court dans un graphique pondéré, mais ils présentent quelques différences clés. Voici les principales différences entre l’algorithme de Dijkstra et l’algorithme A* :
| Fonctionnalité: | Un* algorithme | |
|---|---|---|
| Technique de recherche | Optimisé pour trouver le chemin le plus court entre un seul nœud source et tous les autres nœuds dans un graphique avec des poids de bord non négatifs | L'algorithme A* est un algorithme de recherche informé qui utilise une fonction heuristique pour guider la recherche vers le nœud objectif. |
| Fonction heuristique | L’algorithme de Dijkstra n’utilise aucune fonction heuristique et considère tous les nœuds du graphe. | L'algorithme A* utilise une fonction heuristique qui estime la distance entre le nœud actuel et le nœud objectif. Cette fonction heuristique est admissible, ce qui signifie qu'elle ne surestime jamais la distance réelle jusqu'au nœud objectif. |
| Complexité temporelle | L'algorithme de Dijkstra a une complexité temporelle de O(V^2) pour un graphe dense et O(E log V) pour un graphe clairsemé, où V est le nombre de sommets et E est le nombre d'arêtes du graphe. | La complexité temporelle de l’algorithme A* dépend de la qualité de la fonction heuristique. |
| Application | L'algorithme de Dijkstra est utilisé dans de nombreuses applications telles que les algorithmes de routage, les systèmes de navigation GPS et l'analyse de réseau. | . L'algorithme A* est couramment utilisé dans les problèmes de recherche de chemin et de traversée de graphiques, tels que les jeux vidéo, la robotique et les algorithmes de planification. |
Problèmes pratiques sur l’algorithme de Dijkstra :
- L'algorithme du chemin le plus court de Dijkstra | Algo gourmand-7
- Algorithme de Dijkstra pour la représentation de liste de contiguïté | Algo gourmand-8
- Algorithme de Dijkstra – Implémentation de files d’attente et de tableaux prioritaires
- L'algorithme de chemin le plus court de Dijkstra utilisant un ensemble en STL
- L'algorithme de chemin le plus court de Dijkstra utilisant STL en C++
- L'algorithme du plus court chemin de Dijkstra utilisant la file d'attente prioritaire de STL
- L'algorithme du plus court chemin de Dijkstra utilisant la matrice en C++
- Algorithme de Dijkstra pour le plus court chemin à source unique dans un DAG
- Algorithme de Dijkstra utilisant le tas de Fibonacci
- L'algorithme de chemin le plus court de Dijkstra pour un graphe orienté avec des poids négatifs
- Impression des chemins dans l'algorithme du chemin le plus court de Dijkstra
- L'algorithme de chemin le plus court de Dijkstra avec file d'attente prioritaire en Java




