logo

Co je Dijkstrův algoritmus? | Úvod do Dijkstrova algoritmu nejkratší cesty

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

dijkstra-algorithm-(1)



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:

  1. Označte zdrojový uzel aktuální vzdáleností 0 a zbytek nekonečnem.
  2. Jako aktuální uzel nastavte nenavštívený uzel s nejmenší aktuální vzdáleností.
  3. 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.
  4. Označte aktuální uzel 1 jako navštívený.
  5. 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:

Dijkstra

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 java

Jak 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ě.

Dijkstra

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

Dijkstra

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ězec
Dijkstra

Dijkstrů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

Dijkstra

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

Dijkstra

Dijkstrův algoritmus

volání funkce javascript z html

Nejkratší 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:

  1. Prioritní fronta (implementace založená na haldě):
  2. 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'sBellman Ford
Optimalizaceoptimalizová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 hranAlgoritmus 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.
RelaxaceDijkstrův algoritmus používá chamtivý přístup, kdy si vybere uzel s nejmenší vzdáleností a aktualizuje své sousedyAlgoritmus 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žitostDijkstrů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áhyDijkstrů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'sFloyd-Warshallův algoritmus
OptimalizaceOptimalizová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 hranFloyd-Warshallův algoritmus je optimalizován pro nalezení nejkratší cesty mezi všemi páry uzlů v grafu.
TechnikaDijkstrů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žitostDijkstrů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áhyDijkstrů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 hranAlgoritmus A* je informovaný vyhledávací algoritmus, který používá heuristickou funkci k vedení hledání směrem k cílovému uzlu.
Heuristická funkceDijkstrů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žitostDijkstrů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.
aplikaceDijkstrů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:

  1. Dijkstrův algoritmus nejkratší cesty | Chamtivý Algo-7
  2. Dijkstrův algoritmus pro reprezentaci seznamu sousedství | Greedy Algo-8
  3. Dijkstrův algoritmus – prioritní fronta a implementace pole
  4. Dijkstrův algoritmus nejkratší cesty pomocí sady v STL
  5. Dijkstrův algoritmus nejkratší cesty využívající STL v C++
  6. Dijkstrův algoritmus nejkratší cesty pomocí priority_queue STL
  7. Dijkstrův algoritmus nejkratší cesty využívající matici v C++
  8. Dijkstrův algoritmus pro nejkratší cestu jednoho zdroje v DAG
  9. Dijkstrův algoritmus využívající Fibonacciho haldu
  10. Dijkstrův algoritmus nejkratší cesty pro orientovaný graf se zápornými vahami
  11. Tisk cest v Dijkstrově algoritmu nejkratší cesty
  12. Algoritmus nejkratší cesty Dijkstra s prioritní frontou v Javě