V tomto článku budeme diskutovat o jednom z nejznámějších algoritmů nejkratší cesty, tj. Dijkstrově algoritmu nejkratší cesty, který vyvinul holandský počítačový vědec Edsger W. Dijkstra v roce 1956. Kromě toho provedeme analýzu složitosti tohoto algoritmu a také Podívejte se, jak se liší od jiných algoritmů s nejkratší cestou.
Obsah
- Dijkstrův algoritmus
- Need for Dijkstra's Algorithm (účel a případy použití)
- Může Dijkstrův algoritmus fungovat na řízených i neorientovaných grafech?
- Algoritmus pro Dijkstrův algoritmus
- Jak funguje Dijkstrův algoritmus?
- Pseudokód pro Dijkstrův algoritmus
- Implementace Dijkstrova algoritmu:
- Dijkstrovy algoritmy vs Bellman-Fordův algoritmus
- Dijkstrův algoritmus vs Floyd-Warshallův algoritmus
- Dijkstrův algoritmus vs A* Algoritmus
- Cvičné problémy na Dijkstrově algoritmu
- Závěr:

Dijkstrův algoritmus:
Dijkstrův algoritmus je populární algoritmus pro řešení mnoha jednozdrojových problémů s nejkratší cestou, které mají nezápornou váhu hrany v grafech, tj. jde o nalezení nejkratší vzdálenosti mezi dvěma vrcholy v grafu. Vymyslel ho holandský počítačový vědec Edsger W. Dijkstra v roce 1956.
Algoritmus udržuje sadu navštívených vrcholů a sadu nenavštívených vrcholů. Začíná ve zdrojovém vrcholu a iterativně vybírá nenavštívený vrchol s nejmenší orientační vzdáleností od zdroje. Poté navštíví sousedy tohoto vrcholu a aktualizuje jejich předběžné vzdálenosti, pokud je nalezena kratší cesta. Tento proces pokračuje, dokud není dosaženo cílového vrcholu nebo dokud nejsou navštíveny všechny dosažitelné vrcholy.
Need for Dijkstra's Algorithm (účel a případy použití)
Potřeba Dijkstrova algoritmu vyvstává v mnoha aplikacích, kde je klíčové najít nejkratší cestu mezi dvěma body.
Například , Může být použit ve směrovacích protokolech pro počítačové sítě a také používán v mapových systémech k nalezení nejkratší cesty mezi výchozím bodem a Cílem (jak je vysvětleno v Jak fungují Mapy Google? )
Může Dijkstrův algoritmus fungovat na řízených i neorientovaných grafech?
Ano , Dijkstrův algoritmus může pracovat jak s orientovanými grafy, tak s neorientovanými grafy, protože tento algoritmus je navržen tak, aby fungoval na jakémkoli typu grafu, pokud splňuje požadavky na nezáporné váhy hran a propojení.
- V orientovaném grafu každá hrana má směr, udávající směr pohybu mezi vrcholy spojenými hranou. V tomto případě algoritmus při hledání nejkratší cesty sleduje směr hran.
- V neorientovaném grafu hrany nemají žádný směr a algoritmus se může při hledání nejkratší cesty pohybovat podél hran vpřed i vzad.
Algoritmus pro Dijkstrův algoritmus:
- Označte zdrojový uzel aktuální vzdáleností 0 a zbytek nekonečnem.
- Jako aktuální uzel nastavte nenavštívený uzel s nejmenší aktuální vzdáleností.
- Pro každého souseda N aktuálního uzlu sečte aktuální vzdálenost sousedního uzlu s váhou spojující hrany 0->1. Pokud je menší než aktuální vzdálenost uzlu, nastavte ji jako novou aktuální vzdálenost N.
- Označte aktuální uzel 1 jako navštívený.
- Přejděte ke kroku 2, pokud jsou některé uzly nenavštíveny.
Jak funguje Dijkstrův algoritmus?
Podívejme se, jak funguje Dijkstrův algoritmus, s příkladem uvedeným níže:
Dijkstrův algoritmus vygeneruje nejkratší cestu z uzlu 0 do všech ostatních uzlů v grafu.
Zvažte níže uvedený graf:
Dijkstrův algoritmus
Algoritmus vygeneruje nejkratší cestu z uzlu 0 do všech ostatních uzlů v grafu.
Pro tento graf budeme předpokládat, že váha hran představuje vzdálenost mezi dvěma uzly.
vstupní řetězec javaJak vidíme, máme nejkratší cestu z,
Uzel 0 až uzel 1, od
Uzel 0 až uzel 2, od
Uzel 0 až uzel 3, od
Uzel 0 až uzel 4, od
Uzel 0 až uzel 6.Zpočátku máme níže uvedenou sadu zdrojů:
- Vzdálenost od zdrojového uzlu k sobě samému je 0. V tomto příkladu je zdrojový uzel 0.
- Vzdálenost od zdrojového uzlu ke všem ostatním uzlům není známa, takže všechny označíme jako nekonečno.
Příklad: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.
- budeme mít také řadu nenavštívených prvků, které budou sledovat nenavštívené nebo neoznačené uzly.
- Algoritmus bude dokončen, když všechny uzly označené jako navštívené a vzdálenost mezi nimi se přidá k cestě. Nenavštívené uzly:- 0 1 2 3 4 5 6.
Krok 1: Začněte od uzlu 0 a označte uzel jako navštívený, jak můžete zkontrolovat na obrázku níže, uzel je označen červeně.
Dijkstrův algoritmus
Krok 2: Zkontrolujte sousední uzly, Nyní musíme vybrat (Buď zvolte Uzel1 se vzdáleností 2 nebo buď zvolte Uzel 2 se vzdáleností 6 ) a vyberte Uzel s minimální vzdáleností. V tomto kroku Uzel 1 je Minimální vzdálenost přilehlého uzlu, takže jej označte jako navštívený a sečtěte vzdálenost.
Vzdálenost: Uzel 0 -> Uzel 1 = 2
Dijkstrův algoritmus
Krok 3: Poté se posuňte vpřed a zkontrolujte sousední uzel, což je uzel 3, označte jej jako navštívený a sečtěte vzdálenost. Nyní bude vzdálenost:
Vzdálenost: Uzel 0 -> Uzel 1 -> Uzel 3 = 2 + 5 = 7
formátovat datum na řetězecDijkstrův algoritmus
Krok 4: Opět máme dvě možnosti pro sousední uzly (buď můžeme zvolit uzel 4 se vzdáleností 10 nebo buď můžeme zvolit uzel 5 se vzdáleností 15), takže vyberte uzel s minimální vzdáleností. V tomto kroku Uzel 4 je Minimální vzdálenost přilehlého uzlu, takže jej označte jako navštívený a sečtěte vzdálenost.
Vzdálenost: Uzel 0 -> Uzel 1 -> Uzel 3 -> Uzel 4 = 2 + 5 + 10 = 17
Dijkstrův algoritmus
Krok 5: Znovu, Move Forward a zkontrolujte sousední uzel, který je Uzel 6 , tak to označte jako navštívené a sečtěte vzdálenost, Nyní bude vzdálenost:
Vzdálenost: Uzel 0 -> Uzel 1 -> Uzel 3 -> Uzel 4 -> Uzel 6 = 2 + 5 + 10 + 2 = 19
Dijkstrův algoritmus
volání funkce javascript z htmlNejkratší vzdálenost od zdrojového vrcholu je tedy 19, což je optimální
Pseudokód pro Dijkstrův algoritmus
funkce Dijkstra(Graf, zdroj):
// Inicializuje vzdálenosti ke všem uzlům jako nekonečno a ke zdrojovému uzlu jako 0.vzdálenosti = mapa (všechny uzly -> nekonečno)
vzdálenosti = 0
// Inicializuje prázdnou sadu navštívených uzlů a prioritní frontu pro sledování uzlů k návštěvě.
navštíveno = prázdná množina
fronta = new PriorityQueue()
queue.enqueue(zdroj, 0)// Smyčka, dokud nebudou navštíveny všechny uzly.
zatímco fronta není prázdná:
// Vyřadí uzel s nejmenší vzdáleností od prioritní fronty.
aktuální = queue.dequeue()// Pokud byl uzel již navštíven, přeskočte jej.
pokud je aktuální v navštívených:
pokračovat// Označení uzlu jako navštíveného.
navštíveno.přidat (aktuální)// Zkontrolujte všechny sousední uzly a zjistěte, zda je třeba aktualizovat jejich vzdálenosti.
pro souseda v Graph.neighbors(aktuální):
// Vypočítejte předběžnou vzdálenost k sousedovi přes aktuální uzel.
tentative_distance = vzdálenosti[aktuální] + Graph.distance(aktuální, soused)// Pokud je předběžná vzdálenost menší než aktuální vzdálenost k sousedovi, aktualizujte vzdálenost.
pokud je předběžná_vzdálenost
vzdálenosti[soused] = předběžná_vzdálenost// Zařaďte souseda do fronty s jeho novou vzdáleností, aby byl v budoucnu zvažován pro návštěvu.
queue.enqueue(soused, vzdálenosti[soused])// Vrátí vypočítané vzdálenosti od zdroje ke všem ostatním uzlům v grafu.
zpáteční vzdálenosti
Implementace Dijkstrova algoritmu:
Existuje několik způsobů, jak implementovat Dijkstrův algoritmus, ale ty nejběžnější jsou:
- Prioritní fronta (implementace založená na haldě):
- Implementace založená na poli:
1. Dijkstrův algoritmus nejkratší cesty pomocí priority_queue (Heap)
V této Implementaci dostaneme graf a zdrojový vrchol v grafu, který najde nejkratší cesty od zdroje ke všem vrcholům v daném grafu.
Příklad:
Vstup: Zdroj = 0
Příklad
Výstup: Vrchol
Vzdálenost vrcholu od zdroje
0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19
Níže je uveden algoritmus založený na výše uvedené myšlence:
- Inicializujte hodnoty vzdálenosti a prioritní frontu.
- Vložte zdrojový uzel do prioritní fronty se vzdáleností 0.
- Zatímco fronta priorit není prázdná:
- Extrahujte uzel s minimální vzdáleností od prioritní fronty.
- Aktualizujte vzdálenosti jeho sousedů, pokud je nalezena kratší cesta.
- Vložte aktualizované sousedy do prioritní fronty.
Níže je uvedena implementace výše uvedeného přístupu v C++:
C++ // Program to find Dijkstra's shortest path using // priority_queue in STL #include using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef pair iPair; // Tato třída představuje orientovaný graf pomocí // reprezentace seznamu sousedství class Graph { int V; // Počet vrcholů // Ve váženém grafu potřebujeme uložit vrchol // a váhový pár pro každý seznam hran>* adj; veřejnost: Graf(int V); // Konstruktor // funkce pro přidání hrany do grafu void addEdge(int u, int v, int w); // vypíše nejkratší cestu z s void shortestPath(int s); }; // Alokuje paměť pro seznam sousedství Graph::Graph(int V) { this->V = V; adj = nový seznam [PROTI]; } 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)); } // Vytiskne nejkratší cesty od src ke všem ostatním vrcholům void Graph::shortestPath(int src) { // Vytvoří prioritní frontu pro uložení vrcholů, které // jsou předzpracovány. To je divná syntaxe v C++. // Podrobnosti o této syntaxi naleznete na níže uvedeném odkazu // https://www.techcodeview.com priority_queue , větší > pq; // Vytvořte vektor pro vzdálenosti a inicializujte všechny // vzdálenosti jako nekonečný (INF) vektor dist(V, INF); // Vloží samotný zdroj do prioritní fronty a inicializuje // jeho vzdálenost jako 0. pq.push(make_pair(0, src)); dist[src] = 0; /* Opakování, dokud se prioritní fronta nevyprázdní (nebo nejsou dokončeny všechny vzdálenosti) */ while (!pq.empty()) { // První vrchol v páru je minimální vzdálenost // vrchol, extrahujte jej z prioritní fronty. // štítek vrcholu je uložen v sekundě z páru (to // musí být provedeno tímto způsobem, aby se zachovaly vrcholy // seřazená vzdálenost (vzdálenost musí být první položka // v páru) int u = pq.top().second; pq.pop(); // 'i' se používá k získání všech sousedních vrcholů // seznamu vrcholů>::iterátor i; for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Získání štítku vrcholu a váhy aktuálního // sousedícího s u. int v = (*i).první; int váha = (*i).sekunda; // Pokud existuje zkrácená cesta k v přes u. if (dist[v]> dist[u] + hmotnost) { // Aktualizace vzdálenosti v dist[v] = dist[u] + hmotnost; pq.push(make_pair(dist[v], v)); } } } // Tisk nejkratších vzdáleností uložených v dist[] printf('Vzdálenost vrcholu od zdroje
'); for (int i = 0; i< 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; }>
Jáva import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.PriorityQueue; public class DijkstraAlgoForShortestDistance { static class Node implements Comparable{ int v; int vzdálenost; public Uzel(int v, int vzdálenost) { this.v = v; this.distance = vzdálenost; } @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[] navštíveno = new boolean[V]; HashMap mapa = new HashMap(); PriorityQueueq = new PriorityQueue(); map.put(S, nový uzel(S, 0)); q.add(new Node(S, 0)); while (!q.isEmpty()) { Uzel n = q.poll(); int v = n.v; int vzdálenost = n.vzdálenost; navštíveno[v] = true; ArrayList > adjList = adj.get(v); pro (ArrayList adjLink : adjList) { if (visited[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), nový uzel (v, vzdálenost + adjLink.get(1))); } else { Uzel sn = map.get(adjLink.get(0)); if (vzdálenost + 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(); HashMap >> mapa = new HashMap(); int V = 6; int E = 5; int[] u = { 0, 0, 1, 2, 4 }; int[] v = { 3, 5, 4, 5, 5 }; int[] w = { 9, 4, 4, 10, 3}; for (int i = 0; i< E; i++) { ArrayList edge = new ArrayList(); hrana.add(v[i]); hrana.add(w[i]); ArrayList > adjList; if (!map.containsKey(u[i])) { adjList = new ArrayList(); } else { adjList = map.get(u[i]); } adjList.add(edge); map.put(u[i], adjList); ArrayList hrana2 = new ArrayList(); hrana2.add(u[i]); hrana2.add(w[i]); ArrayList > adjList2; if (!map.containsKey(v[i])) { adjList2 = new ArrayList(); } else { adjList2 = map.get(v[i]); } adjList2.add(edge2); map.put(v[i], adjList2); } for (int i = 0; i< 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)); } }> Krajta # 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; // Konstruktor public Graph(int v) { V = v; adj = nový seznam>[ v]; for (int i = 0; i< v; ++i) adj[i] = new List>(); } // funkce pro přidání hrany do grafu public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w)); adj[v].Add(Tuple.Create(u, w)); } // vypíše nejkratší cestu ze s public void shortestPath(int s) { // Vytvoří prioritní frontu pro uložení vrcholů, které // jsou předzpracovány. var pq = new PriorityQueue>(); // Vytvořte vektor pro vzdálenosti a inicializujte všechny // vzdálenosti jako nekonečné (INF) var dist = new int[V]; for (int i = 0; i< 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] + váha) { // Aktualizace vzdálenosti v dist[v] = dist[u] + váha; pq.Enqueue(Tuple.Create(dist[v], v)); } } } // Tisk nejkratších vzdáleností uložených v dist[] Console.WriteLine('Vzdálenost vrcholu od zdroje'); for (int i = 0; i< V; ++i) Console.WriteLine('{0} {1}', i, dist[i]); } } public class PriorityQueue{ private readonly List_data; soukromé srovnání pouze pro čtení_v porovnání; public PriorityQueue(): this(Porovnat.Výchozí) { } public PriorityQueue(IComparerporovnat): this(compare.Compare) { } public PriorityQueue(Comparisonporovnání) { _data = nový seznam(); _compare = srovnání; } public void Enqueue(T item) { _data.Add(item); 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; childIndex = parentIndex; } } public T Dequeue() { // předpokládá, že pq není prázdné; až do volajícího kódu var lastElement = _data.Count - 1; var frontItem = _data[0]; _data[0] = _data[posledníPrvek]; _data.RemoveAt(lastElement); --posledníprvek; var parentIndex = 0; while (true) { var childIndex = parentIndex * 2 + 1; if (childIndex> lastElement) break; // Konec stromu var rightChild = childIndex + 1; pokud (pravé Dítě<= 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.priority - b.priority); } dequeue() { if (this.isEmpty()) { return null; } return this.queue.shift().element; } isEmpty() { return this.queue.length === 0; } } class Graph { konstruktor(V) { this.V = V; this.adj = new Array(V); for (ať 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();> Konečná odpověď:

Výstup
Analýza složitosti Dijkstrova algoritmu :
- Časová složitost: O((V + E) log V) , kde V je počet vrcholů a E je počet hran.
- Pomocný prostor: O(V), kde V je počet vrcholů a E je počet hran v grafu.
2.Implementace Dijkstrova algoritmu založená na poli (naivní přístup):
Dijkstrův algoritmus lze také implementovat pomocí polí bez použití prioritní fronty. Tato implementace je přímočará, ale může být méně efektivní, zejména na velkých grafech.
Algoritmus probíhá následovně:
stack java
- Inicializujte pole pro uložení vzdáleností od zdroje ke každému uzlu.
- Označte všechny uzly jako nenavštívené.
- Nastavte vzdálenost ke zdrojovému uzlu na 0 a nekonečno pro všechny ostatní uzly.
- Opakujte, dokud nenavštívíte všechny uzly:
- Najděte nenavštívený uzel s nejmenší známou vzdáleností.
- Pro aktuální uzel aktualizujte vzdálenosti jeho nenavštívených sousedů.
- Označte aktuální uzel jako navštívený.
Analýza složitosti:
- Časová náročnost: O(V^2) v nejhorším případě, kde V je počet vrcholů. To lze zlepšit na O(V^2) pomocí určitých optimalizací.
- Pomocný prostor: O(V), kde V je počet vrcholů a E je počet hran v grafu.
Dijkstrovy algoritmy vs Bellman-Fordův algoritmus
Dijkstrův algoritmus a Bellman-Fordův algoritmus oba se používají k nalezení nejkratší cesty ve váženém grafu, ale mají některé klíčové rozdíly. Zde jsou hlavní rozdíly mezi Dijkstrovým algoritmem a Bellman-Fordovým algoritmem:
| Vlastnosti: | Dijkstra's | Bellman Ford |
|---|---|---|
| Optimalizace | optimalizováno pro nalezení nejkratší cesty mezi jedním zdrojovým uzlem a všemi ostatními uzly v grafu s nezápornými váhami hran | Algoritmus Bellman-Ford je optimalizován pro nalezení nejkratší cesty mezi jedním zdrojovým uzlem a všemi ostatními uzly v grafu se zápornými váhami hran. |
| Relaxace | Dijkstrův algoritmus používá chamtivý přístup, kdy si vybere uzel s nejmenší vzdáleností a aktualizuje své sousedy | Algoritmus Bellman-Ford uvolňuje všechny hrany v každé iteraci a aktualizuje vzdálenost každého uzlu zvážením všech možných cest k tomuto uzlu |
| Časová složitost | Dijkstrův algoritmus má časovou složitost O(V^2) pro hustý graf a O(E log V) pro řídký graf, kde V je počet vrcholů a E je počet hran v grafu. | Bellman-Fordův algoritmus má časovou složitost O(VE), kde V je počet vrcholů a E je počet hran v grafu. |
| Záporné váhy | Dijkstrův algoritmus nepracuje s grafy, které mají záporné váhy hran, protože předpokládá, že všechny váhy hran jsou nezáporné. | Algoritmus Bellman-Ford dokáže zpracovat záporné váhy hran a dokáže detekovat cykly záporných vah v grafu. |
Dijkstrův algoritmus vs Floyd-Warshallův algoritmus
Dijkstrův algoritmus a Floyd-Warshall algoritmus oba se používají k nalezení nejkratší cesty ve váženém grafu, ale mají některé klíčové rozdíly. Zde jsou hlavní rozdíly mezi Dijkstrovým algoritmem a Floyd-Warshallovým algoritmem:
| Vlastnosti: | Dijkstra's | Floyd-Warshallův algoritmus |
|---|---|---|
| Optimalizace | Optimalizováno pro nalezení nejkratší cesty mezi jedním zdrojovým uzlem a všemi ostatními uzly v grafu s nezápornými váhami hran | Floyd-Warshallův algoritmus je optimalizován pro nalezení nejkratší cesty mezi všemi páry uzlů v grafu. |
| Technika | Dijkstrův algoritmus je jednozdrojový algoritmus nejkratší cesty, který používá chamtivý přístup a vypočítává nejkratší cestu ze zdrojového uzlu ke všem ostatním uzlům v grafu. | Na druhé straně Floyd-Warshallův algoritmus je algoritmus nejkratší cesty všech párů, který používá dynamické programování k výpočtu nejkratší cesty mezi všemi páry uzlů v grafu. |
| Časová složitost | Dijkstrův algoritmus má časovou složitost O(V^2) pro hustý graf a O(E log V) pro řídký graf, kde V je počet vrcholů a E je počet hran v grafu. | Na druhé straně Floyd-Warshallův algoritmus je algoritmus nejkratší cesty všech párů, který používá dynamické programování k výpočtu nejkratší cesty mezi všemi páry uzlů v grafu. |
| Záporné váhy | Dijkstrův algoritmus nepracuje s grafy, které mají záporné váhy hran, protože předpokládá, že všechny váhy hran jsou nezáporné. | Na druhé straně Floyd-Warshallův algoritmus je algoritmus nejkratší cesty všech párů, který používá dynamické programování k výpočtu nejkratší cesty mezi všemi páry uzlů v grafu. |
Dijkstrův algoritmus vs A* Algoritmus
Dijkstrův algoritmus a A* algoritmus oba se používají k nalezení nejkratší cesty ve váženém grafu, ale mají některé klíčové rozdíly. Zde jsou hlavní rozdíly mezi Dijkstrovým algoritmem a A* algoritmem:
| Vlastnosti: | A* Algoritmus | |
|---|---|---|
| Technika vyhledávání | Optimalizováno pro nalezení nejkratší cesty mezi jedním zdrojovým uzlem a všemi ostatními uzly v grafu s nezápornými váhami hran | Algoritmus A* je informovaný vyhledávací algoritmus, který používá heuristickou funkci k vedení hledání směrem k cílovému uzlu. |
| Heuristická funkce | Dijkstrův algoritmus nepoužívá žádnou heuristickou funkci a bere v úvahu všechny uzly v grafu. | Algoritmus A* používá heuristickou funkci, která odhaduje vzdálenost od aktuálního uzlu k cílovému uzlu. Tato heuristická funkce je přípustná, což znamená, že nikdy nepřeceňuje skutečnou vzdálenost k cílovému uzlu |
| Časová složitost | Dijkstrův algoritmus má časovou složitost O(V^2) pro hustý graf a O(E log V) pro řídký graf, kde V je počet vrcholů a E je počet hran v grafu. | Časová složitost A* algoritmu závisí na kvalitě heuristické funkce. |
| aplikace | Dijkstrův algoritmus se používá v mnoha aplikacích, jako jsou směrovací algoritmy, navigační systémy GPS a síťová analýza. | . Algoritmus A* se běžně používá v problémech s hledáním cest a procházením grafů, jako jsou videohry, robotika a plánovací algoritmy. |
Cvičné problémy na Dijkstrově algoritmu:
- Dijkstrův algoritmus nejkratší cesty | Chamtivý Algo-7
- Dijkstrův algoritmus pro reprezentaci seznamu sousedství | Greedy Algo-8
- Dijkstrův algoritmus – prioritní fronta a implementace pole
- Dijkstrův algoritmus nejkratší cesty pomocí sady v STL
- Dijkstrův algoritmus nejkratší cesty využívající STL v C++
- Dijkstrův algoritmus nejkratší cesty pomocí priority_queue STL
- Dijkstrův algoritmus nejkratší cesty využívající matici v C++
- Dijkstrův algoritmus pro nejkratší cestu jednoho zdroje v DAG
- Dijkstrův algoritmus využívající Fibonacciho haldu
- Dijkstrův algoritmus nejkratší cesty pro orientovaný graf se zápornými vahami
- Tisk cest v Dijkstrově algoritmu nejkratší cesty
- Algoritmus nejkratší cesty Dijkstra s prioritní frontou v Javě




