logo

Ce este algoritmul lui Dijkstra? | Introducere în algoritmul lui Dijkstra cea mai scurtă cale

În acest articol, vom discuta despre unul dintre cei mai cunoscuți algoritmi cu cea mai scurtă cale, adică algoritmul Dijkstra’s Shortest Path, care a fost dezvoltat de informaticianul olandez Edsger W. Dijkstra în 1956. Mai mult, vom face o analiză a complexității acestui algoritm și, de asemenea, vezi cum diferă de alți algoritmi cu calea cea mai scurtă.

Cuprins

algoritmul dijkstra-(1)



Algoritmul lui Dijkstra:

algoritmul lui Dijkstra este un algoritm popular pentru rezolvarea multor probleme cu calea cea mai scurtă dintr-o singură sursă, având greutatea marginii nenegative în grafice, adică este să găsească cea mai scurtă distanță dintre două vârfuri pe un grafic. A fost conceput de un informatician olandez Edsger W. Dijkstra în 1956.

Algoritmul menține un set de vârfuri vizitate și un set de vârfuri nevizitate. Începe de la vârful sursă și selectează în mod iterativ vârful nevizitat cu cea mai mică distanță tentativă de la sursă. Apoi vizitează vecinii acestui vârf și își actualizează distanțele provizorii dacă se găsește o cale mai scurtă. Acest proces continuă până când este atins vârful de destinație sau până când toate vârfurile accesibile au fost vizitate.

Nevoia algoritmului lui Dijkstra (scop și cazuri de utilizare)

Necesitatea algoritmului lui Dijkstra apare în multe aplicații în care găsirea celei mai scurte căi între două puncte este crucială.

De exemplu , Poate fi folosit în protocoalele de rutare pentru rețelele de calculatoare și, de asemenea, utilizat de sistemele de hărți pentru a găsi calea cea mai scurtă între punctul de plecare și Destinație (după cum este explicat în Cum funcționează Google Maps? )

Algoritmul lui Dijkstra poate funcționa atât pe grafice direcționate, cât și pe cele nedirecționate?

da , algoritmul lui Dijkstra poate funcționa atât pe grafice direcționate, cât și pe grafice nedirecționate, deoarece acest algoritm este proiectat să funcționeze pe orice tip de grafic, atâta timp cât îndeplinește cerințele de a avea ponderi nenegative de margine și de a fi conectat.

  • Într-un grafic direcționat, fiecare muchie are o direcție, indicând direcția de mers între vârfurile conectate prin muchie. În acest caz, algoritmul urmează direcția marginilor atunci când caută calea cea mai scurtă.
  • Într-un grafic nedirecționat, marginile nu au direcție, iar algoritmul poate traversa atât înainte, cât și înapoi de-a lungul marginilor atunci când caută calea cea mai scurtă.

Algoritm pentru algoritmul lui Dijkstra:

  1. Marcați nodul sursă cu o distanță curentă de 0 și restul cu infinit.
  2. Setați nodul nevizitat cu cea mai mică distanță curentă ca nod curent.
  3. Pentru fiecare vecin, N al nodului curent adaugă distanța curentă a nodului adiacent cu greutatea muchiei care leagă 0->1. Dacă este mai mică decât distanța curentă a Nodului, setați-o ca nouă distanță curentă a lui N.
  4. Marcați nodul curent 1 ca vizitat.
  5. Treceți la pasul 2 dacă există noduri nevizitate.

Cum funcționează algoritmul lui Dijkstra?

Să vedem cum funcționează algoritmul lui Dijkstra cu un exemplu de mai jos:

Algoritmul lui Dijkstra va genera cea mai scurtă cale de la Nodul 0 la toate celelalte Noduri din grafic.

Luați în considerare graficul de mai jos:

Dijkstra

Algoritmul lui Dijkstra

Algoritmul va genera calea cea mai scurtă de la nodul 0 la toate celelalte noduri din grafic.

Pentru acest grafic, vom presupune că greutatea muchiilor reprezintă distanța dintre două noduri.

matrice care returnează în java

După cum putem vedea că avem cea mai scurtă cale de la,
Nodul 0 la Nodul 1, de la
Nodul 0 la Nodul 2, de la
Nodul 0 la Nodul 3, de la
Nodul 0 la Nodul 4, de la
Nodul 0 până la nodul 6.

Inițial avem un set de resurse prezentate mai jos:

  • Distanța de la nodul sursă la sine este 0. În acest exemplu, nodul sursă este 0.
  • Distanța de la nodul sursă la toate celelalte noduri este necunoscută, așa că le marchem pe toate ca infinit.

Exemplu: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.

  • vom avea, de asemenea, o serie de elemente nevizitate care vor ține evidența Nodurilor nevizitate sau nemarcate.
  • Algoritmul se va finaliza atunci când toate nodurile marcate ca vizitate și distanța dintre ele se adaugă la cale. Noduri nevizitate: - 0 1 2 3 4 5 6.

Pasul 1: Începeți de la Nodul 0 și marcați Nodul ca vizitat, așa cum puteți verifica mai jos imaginea vizitată. Nodul este marcat cu roșu.

Dijkstra

Algoritmul lui Dijkstra

Pasul 2: Verificați nodurile adiacente, acum trebuie să alegeți (fie alegeți Nodul1 cu distanța 2, fie alegeți Nodul 2 cu distanța 6) și alegeți Nodul cu distanța minimă. În acest pas Nodul 1 este Distanța minimă adiacentă a nodului, deci marcați-l ca vizitat și adăugați distanța.

Distanță: Nodul 0 -> Nodul 1 = 2

Dijkstra

Algoritmul lui Dijkstra

Pasul 3: Apoi deplasați-vă înainte și verificați nodul adiacent care este Nodul 3, deci marcați-l ca vizitat și adăugați distanța. Acum distanța va fi:

Oracle sql nu este egal

Distanță: Nodul 0 -> Nodul 1 -> Nodul 3 = 2 + 5 = 7

Dijkstra

Algoritmul lui Dijkstra

Pasul 4: Din nou avem două opțiuni pentru Nodurile adiacente (Fie putem alege Nodul 4 cu distanța 10, fie putem alege Nodul 5 cu distanța 15), așa că alegem Nodul cu distanța minimă. În acest pas Nodul 4 este Distanța minimă adiacentă a nodului, deci marcați-l ca vizitat și adăugați distanța.

Distanță: Nodul 0 -> Nodul 1 -> Nodul 3 -> Nodul 4 = 2 + 5 + 10 = 17

Dijkstra

Algoritmul lui Dijkstra

Pasul 5: Din nou, deplasați-vă înainte și verificați dacă nodul adiacent este Nodul 6 , așa că l-ați marcat ca vizitat și adăugați distanța. Acum distanța va fi:

Distanță: Nodul 0 -> Nodul 1 -> Nodul 3 -> Nodul 4 -> Nodul 6 = 2 + 5 + 10 + 2 = 19

Dijkstra

Algoritmul lui Dijkstra

Deci, cea mai scurtă distanță de la vârful sursă este 19, ceea ce este optim

Pseudocod pentru algoritmul lui Dijkstra

funcția Dijkstra(Grafic, sursă):
// Inițializați distanțele către toate nodurile ca infinit și către nodul sursă ca 0.

distanțe = hartă (toate nodurile -> infinit)

distante = 0

// Inițializați un set gol de noduri vizitate și o coadă de prioritate pentru a ține evidența nodurilor de vizitat.
vizitat = set gol
coadă = priorityQueue nou ()
queue.enqueue(sursa, 0)

// Buclă până când toate nodurile au fost vizitate.
în timp ce coada nu este goală:
// Scoateți din coadă nodul cu cea mai mică distanță de coada de prioritate.
curent = queue.dequeue()

// Dacă nodul a fost deja vizitat, omiteți-l.
dacă este curent în vizitat:
continua

// Marcați nodul ca vizitat.
vizitat.add(current)

// Verificați toate nodurile învecinate pentru a vedea dacă distanțele lor trebuie actualizate.
pentru vecinul din Graph.neighbors(current):
// Calculați distanța provizorie până la vecin prin nodul curent.
tentative_distance = distanțe[curent] + Graph.distance(curent, vecin)

// Dacă distanța provizorie este mai mică decât distanța curentă până la vecin, actualizați distanța.
dacă distanța_provizuală
distants[neighbor] = distanta_probabila

// Pune vecinul cu noua sa distanță pentru a fi luat în considerare pentru vizitare în viitor.
queue.enqueue(vecin, distante[neighbor])

// Returnează distanțele calculate de la sursă la toate celelalte noduri din grafic.
distante de intoarcere

Implementarea algoritmului lui Dijkstra:

Există mai multe moduri de implementare a algoritmului Dijkstra, dar cele mai comune sunt:

  1. Coadă prioritară (implementare bazată pe heap):
  2. Implementare bazată pe matrice:

1. Algoritmul lui Dijkstra cu cea mai scurtă cale folosind priority_queue (Heap)

În această implementare, ni se oferă un grafic și un vârf sursă în grafic, găsind cele mai scurte căi de la sursă la toate vârfurile din graficul dat.

alinierea unei imagini în css

Exemplu:

Intrare: Sursa = 0

Exemplu

Ieșire: Vertex

Distanța vârfurilor de la sursă

0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19

Mai jos este algoritmul bazat pe ideea de mai sus:

  • Inițializați valorile distanței și coada de prioritate.
  • Introduceți nodul sursă în coada de prioritate cu distanța 0.
  • În timp ce coada de prioritate nu este goală:
    • Extrageți nodul cu distanța minimă de la coada de prioritate.
    • Actualizați distanțele vecinilor săi dacă se găsește o cale mai scurtă.
    • Introduceți vecini actualizați în coada de prioritate.

Mai jos este implementarea C++ a abordării de mai sus:

C++
// Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef pereche iPair; // Această clasă reprezintă un graf direcționat folosind // clasa de reprezentare a listei de adiacență Graph { int V; // Nr. de vârfuri // Într-un grafic ponderat, trebuie să stocăm vârful // și perechea de ponderi pentru fiecare listă de margini>> adj; public: Graph(int V); // Constructor // funcție pentru a adăuga o margine la grafic void addEdge(int u, int v, int w);  // afișează cea mai scurtă cale de la s void shortestPath(int s); }; // Aloca memorie pentru lista de adiacente Graph::Graph(int V) { this->V = V;  adj = listă nouă [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)); } // Imprimă cele mai scurte căi de la src la toate celelalte vârfuri void Graph::shortestPath(int src) { // Creați o coadă de prioritate pentru a stoca nodurile care // sunt preprocesate. Aceasta este sintaxă ciudată în C++.  // Consultați linkul de mai jos pentru detalii despre această sintaxă // https://www.techcodeview.com priority_queue , mai mare > pq;  // Creați un vector pentru distanțe și inițializați // toate distanțele ca vector infinit (INF). dist(V, INF);  // Inserează sursa însăși în coada de prioritate și inițializează // distanța acesteia ca 0. pq.push(make_pair(0, src));  dist[src] = 0;  /* Se face buclă până când coada de prioritate devine goală (sau toate distanțele nu sunt finalizate) */ while (!pq.empty()) { // Primul vârf din pereche este distanța minimă // vârf, extrageți-l din coada de prioritate.  // eticheta nodurilor este stocată în secunda din pereche (trebuie făcută astfel pentru a păstra vârfurile // distanța sortată (distanța trebuie să fie primul element // în pereche) int u = pq.top().second; pq.pop(); // 'i' este folosit pentru a obține toate nodurile adiacente ale unei // liste de vârfuri>::iteratorul i;  pentru (i = adj[u].begin(); i != adj[u].end(); ++i) { // Obține eticheta vârfului și greutatea curentului // adiacent lui u.  int v = (*i).în primul rând;  int greutate = (*i).secunda;  // Dacă există cale scurtă către v prin u.  if (dist[v]> dist[u] + greutate) { // Actualizarea distanței de v dist[v] = dist[u] + greutate;  pq.push(make_pair(dist[v], v));  } } } // Afișează cele mai scurte distanțe stocate în dist[] printf('Distanța la vârf de la sursă
');  pentru (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; }>
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{  în televizor;  int distanta;  public Node(int v, int distanta) { this.v = v;  aceasta.distanta = distanta;  } @Override public int comparăTo(Nodul n) { dacă (this.distance<= n.distance) {  return -1;  }  else {  return 1;  }  }  }  static int[] dijkstra(  int V,  ArrayList >> adj, int S) { boolean[] vizitat = new boolean[V];  HashMap map = new HashMap();  PriorityQueueq = PriorityQueue nou ();  map.put(S, nou Nod(S, 0));  q.add(nod nou (S, 0));  while (!q.isEmpty()) { Nodul n = q.poll();  int v = n.v;  int distanta = n.distanta;  vizitat[v] = adevărat;  ArrayList > adjList = adj.get(v);  pentru (ArrayList adjLink : adjList) { if (vizited[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), nod nou (v, distanta + adjLink.get(1)));  } else { Nodul sn = map.get(adjLink.get(0));  if (distanță + 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 >> harta = 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 };  pentru (int i = 0; i< E; i++) {  ArrayList margine = new ArrayList();  edge.add(v[i]);  edge.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 margine2 = new ArrayList();  edge2.add(u[i]);  edge2.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);  } pentru (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));  } }>
Piton
# 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;  // Constructor public Graph(int v) { V = v;  adj = Listă nouă>[ v ];  pentru (int i = 0; i< v; ++i)  adj[i] = new List>();  } // funcție pentru a adăuga o margine la graficul public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w));  adj[v].Add(Tuple.Create(u, w));  } // afișează cea mai scurtă cale de la s public void shortestPath(int s) { // Creați o coadă de prioritate pentru a stoca nodurile care // sunt preprocesate.  var pq = priorityQueue nou>();  // Creați un vector pentru distanțe și inițializați // toate distanțele ca infinit (INF) var dist = new int[V];  pentru (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] + greutate) { // Actualizarea distanței de v dist[v] = dist[u] + greutate;  pq.Enqueue(Tuple.Create(dist[v], v));  } } } // Imprimă cele mai scurte distanțe stocate în dist[] Console.WriteLine('Distanța Vertex de la Sursă');  pentru (int i = 0; i< V; ++i)  Console.WriteLine('{0}		{1}', i, dist[i]);  } } public class PriorityQueue{ private readonly List_date;  Private readonly Comparație_comparat;  public PriorityQueue(): aceasta(Comparare.Implicit) { } public PriorityQueue(IComparercompară): this(compare.Compare) { } public PriorityQueue(Comparațiecomparație) { _date = listă nouă();  _compara = comparatie;  } public void Queue(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 = _date[childIndex];  _data[childIndex] = _data[parentIndex];  _data[parentIndex] = tmp;  childIndex = parentIndex;  } } public T Dequeue() { // presupune că pq nu este gol; până la codul de apel var lastElement = _data.Count - 1;  var frontItem = _data[0];  _data[0] = _data[lastElement];  _data.RemoveAt(lastElement);  --lastElement;  var parentIndex = 0;  while (adevărat) { var childIndex = parentIndex * 2 + 1;  if (childIndex> lastElement) break; // Sfârșitul arborelui var rightChild = childIndex + 1;  dacă (copilul dreapta<= 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.prioritate - b.prioritate);  } scoate la coada() { if (this.isEmpty()) { return null;  } returnează this.queue.shift().element;  } isEmpty() { return this.queue.length === 0;  } } class Graph { constructor(V) { this.V = V;  this.adj = new Array(V);  pentru (fie 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ăspuns final:

Ieșire

Analiza complexității algoritmului Dijkstra :

  • Complexitatea timpului: O((V + E) log V) , unde V este numărul de vârfuri și E este numărul de muchii.
  • Spațiu auxiliar: O(V), unde V este numărul de vârfuri și E este numărul de muchii din grafic.

2.Implementarea bazată pe matrice a algoritmului Dijkstra (abordare naivă):

Algoritmul lui Dijkstra poate fi implementat și folosind matrice fără a utiliza o coadă de prioritate. Această implementare este simplă, dar poate fi mai puțin eficientă, în special pe grafice mari.

sortare de selecție

Algoritmul procedează după cum urmează:

  • Inițializați o matrice pentru a stoca distanțele de la sursă la fiecare nod.
  • Marcați toate nodurile ca nevizitate.
  • Setați distanța până la nodul sursă la 0 și infinit pentru toate celelalte noduri.
  • Repetați până când sunt vizitate toate nodurile:
    • Găsiți nodul nevizitat cu cea mai mică distanță cunoscută.
    • Pentru nodul curent, actualizați distanțele vecinilor săi nevizitați.
    • Marcați nodul curent ca vizitat.

Analiza complexității:

  • Complexitatea timpului: O(V^2) în cel mai rău caz, unde V este numărul de vârfuri. Acest lucru poate fi îmbunătățit la O(V^2) cu unele optimizări.
  • Spațiu auxiliar: O(V), unde V este numărul de vârfuri și E este numărul de muchii din grafic.

Algoritmii lui Dijkstra vs algoritmul Bellman-Ford

algoritmul lui Dijkstra și Algoritmul Bellman-Ford ambele sunt folosite pentru a găsi calea cea mai scurtă într-un grafic ponderat, dar au câteva diferențe cheie. Iată principalele diferențe dintre algoritmul lui Dijkstra și algoritmul Bellman-Ford:

Caracteristică:ale lui DijkstraBellman Ford
Optimizareoptimizat pentru a găsi calea cea mai scurtă între un singur nod sursă și toate celelalte noduri dintr-un grafic cu greutăți de margine nenegativeAlgoritmul Bellman-Ford este optimizat pentru a găsi calea cea mai scurtă între un singur nod sursă și toate celelalte noduri dintr-un grafic cu greutăți de margine negativă.
RelaxareAlgoritmul lui Dijkstra folosește o abordare lacomă în care alege nodul cu cea mai mică distanță și își actualizează veciniialgoritmul Bellman-Ford relaxează toate marginile în fiecare iterație, actualizând distanța fiecărui nod luând în considerare toate căile posibile către acel nod
Complexitatea timpuluiAlgoritmul lui Dijkstra are o complexitate de timp de O(V^2) pentru un grafic dens și O(E log V) pentru un grafic rar, unde V este numărul de vârfuri și E este numărul de muchii din grafic.Algoritmul Bellman-Ford are o complexitate de timp de O(VE), unde V este numărul de vârfuri și E este numărul de muchii din grafic.
Greutăți negativeAlgoritmul lui Dijkstra nu funcționează cu grafice care au greutăți de margine negative, deoarece presupune că toate greutățile de margine sunt nenegative.Algoritmul Bellman-Ford poate gestiona greutățile marginilor negative și poate detecta ciclurile cu greutate negativă în grafic.

Algoritmul lui Dijkstra vs algoritmul Floyd-Warshall

algoritmul lui Dijkstra și Algoritmul Floyd-Warshall ambele sunt folosite pentru a găsi calea cea mai scurtă într-un grafic ponderat, dar au câteva diferențe cheie. Iată principalele diferențe dintre algoritmul lui Dijkstra și algoritmul Floyd-Warshall:

Caracteristică:Dijkstra'sAlgoritmul Floyd-Warshall
OptimizareOptimizat pentru a găsi calea cea mai scurtă între un singur nod sursă și toate celelalte noduri dintr-un grafic cu greutăți de margine nenegativeAlgoritmul Floyd-Warshall este optimizat pentru a găsi calea cea mai scurtă între toate perechile de noduri dintr-un grafic.
TehnicăAlgoritmul lui Dijkstra este un algoritm de calea cea mai scurtă cu o singură sursă, care utilizează o abordare lacomă și calculează calea cea mai scurtă de la nodul sursă la toate celelalte noduri din grafic.Algoritmul Floyd-Warshall, pe de altă parte, este un algoritm de calea cea mai scurtă din toate perechile care utilizează programarea dinamică pentru a calcula calea cea mai scurtă dintre toate perechile de noduri din grafic.
Complexitatea timpuluiAlgoritmul lui Dijkstra are o complexitate de timp de O(V^2) pentru un grafic dens și O(E log V) pentru un grafic rar, unde V este numărul de vârfuri și E este numărul de muchii din grafic.Algoritmul Floyd-Warshall, pe de altă parte, este un algoritm de calea cea mai scurtă din toate perechile care utilizează programarea dinamică pentru a calcula calea cea mai scurtă dintre toate perechile de noduri din grafic.
Greutăți negativeAlgoritmul lui Dijkstra nu funcționează cu grafice care au greutăți de margine negative, deoarece presupune că toate greutățile de margine sunt nenegative.Algoritmul Floyd-Warshall, pe de altă parte, este un algoritm de calea cea mai scurtă din toate perechile care utilizează programarea dinamică pentru a calcula calea cea mai scurtă dintre toate perechile de noduri din grafic.

Algoritmul lui Dijkstra vs algoritmul A*

algoritmul lui Dijkstra și Algoritm A* ambele sunt folosite pentru a găsi calea cea mai scurtă într-un grafic ponderat, dar au câteva diferențe cheie. Iată principalele diferențe dintre algoritmul lui Dijkstra și algoritmul A*:

Caracteristică: A* Algoritm
Tehnica de căutareOptimizat pentru a găsi calea cea mai scurtă între un singur nod sursă și toate celelalte noduri dintr-un grafic cu greutăți de margine nenegativeAlgoritmul A* este un algoritm de căutare informat care utilizează o funcție euristică pentru a ghida căutarea către nodul obiectiv.
Funcția euristicăAlgoritmul lui Dijkstra, nu folosește nicio funcție euristică și ia în considerare toate nodurile din grafic.Algoritmul A* folosește o funcție euristică care estimează distanța de la nodul curent la nodul obiectiv. Această funcție euristică este admisibilă, ceea ce înseamnă că nu supraestimează niciodată distanța reală până la nodul obiectiv
Complexitatea timpuluiAlgoritmul lui Dijkstra are o complexitate de timp de O(V^2) pentru un grafic dens și O(E log V) pentru un grafic rar, unde V este numărul de vârfuri și E este numărul de muchii din grafic.Complexitatea temporală a algoritmului A* depinde de calitatea funcției euristice.
AplicațieAlgoritmul lui Dijkstra este folosit în multe aplicații, cum ar fi algoritmi de rutare, sisteme de navigație GPS și analiza rețelei. Algoritmul A* este utilizat în mod obișnuit în problemele de căutare a căii și de traversare a graficelor, cum ar fi jocurile video, robotica și algoritmii de planificare.

Probleme de practică cu algoritmul lui Dijkstra:

  1. Algoritmul cu calea cea mai scurtă a lui Dijkstra | Lacomul Algo-7
  2. Algoritmul lui Dijkstra pentru reprezentarea listei de adiacență | Lacomul Algo-8
  3. Algoritmul lui Dijkstra – Implementarea cozii prioritare și a matricei
  4. Algoritmul cu calea cea mai scurtă a lui Dijkstra folosind set în STL
  5. Algoritmul cu cea mai scurtă cale al lui Dijkstra folosind STL în C++
  6. Algoritmul lui Dijkstra cu cea mai scurtă cale folosind priority_queue din STL
  7. Algoritmul cu cea mai scurtă cale al lui Dijkstra folosind matrice în C++
  8. Algoritmul lui Dijkstra pentru cea mai scurtă cale dintr-o singură sursă într-un DAG
  9. Algoritmul lui Dijkstra folosind Fibonacci Heap
  10. Algoritmul cu calea cea mai scurtă a lui Dijkstra pentru graficul direcționat cu ponderi negative
  11. Tipărirea căilor în algoritmul Dijkstra cu cea mai scurtă cale
  12. Algoritmul cu cea mai scurtă cale de la Dijkstra cu coadă de prioritate în Java