logo

Kas yra Dijkstros algoritmas? | Dijkstra trumpiausio kelio algoritmo įvadas

Šiame straipsnyje aptarsime vieną iš dažniausiai žinomų trumpiausio kelio algoritmų, ty Dijkstra's Shortest Path Algorithm, kurį 1956 m. sukūrė olandų kompiuterių mokslininkas Edsgeris W. Dijkstra. Be to, atliksime šio algoritmo sudėtingumo analizę. pažiūrėkite, kuo jis skiriasi nuo kitų trumpiausio kelio algoritmų.

Turinys

dijkstra-algoritm-(1)



Dijkstros algoritmas:

Dijkstros algoritmas yra populiarus algoritmas, sprendžiantis daugelį vieno šaltinio trumpiausio kelio uždavinių, turinčių neneigiamą kraštų svorį grafuose, ty rasti trumpiausią atstumą tarp dviejų grafo viršūnių. Jį sugalvojo olandų kompiuterių mokslininkas Edsgeris W. Dijkstra 1956 metais.

Algoritmas palaiko aplankytų viršūnių rinkinį ir neaplankytų viršūnių rinkinį. Jis prasideda nuo šaltinio viršūnės ir iteratyviai pasirenka nelankytą viršūnę su mažiausiu preliminariu atstumu nuo šaltinio. Tada jis aplanko šios viršūnės kaimynus ir atnaujina jų preliminarius atstumus, jei randamas trumpesnis kelias. Šis procesas tęsiasi tol, kol pasiekiama paskirties viršūnė arba aplankomos visos pasiekiamos viršūnės.

Dijkstros algoritmo poreikis (tikslas ir naudojimo atvejai)

Dijkstra algoritmo poreikis kyla daugelyje programų, kuriose labai svarbu rasti trumpiausią kelią tarp dviejų taškų.

Pavyzdžiui , Jis gali būti naudojamas kompiuterių tinklų maršruto parinkimo protokoluose, taip pat naudojamas žemėlapių sistemose, norint rasti trumpiausią kelią tarp pradžios taško ir paskirties vietos (kaip paaiškinta Kaip veikia „Google“ žemėlapiai? )

Ar Dijkstros algoritmas gali veikti ir nukreiptuose, ir nerežisuotuose grafikuose?

Taip , Dijkstra algoritmas gali veikti tiek nukreiptuose, tiek neorientuotuose grafikuose, nes šis algoritmas sukurtas dirbti su bet kokio tipo grafiku, jei jis atitinka neneigiamų briaunų svorių ir prijungimo reikalavimus.

  • Nukreiptame grafike kiekviena briauna turi kryptį, nurodant judėjimo kryptį tarp briauna sujungtų viršūnių. Šiuo atveju, ieškodamas trumpiausio kelio, algoritmas vadovaujasi kraštų kryptimi.
  • Nenukreiptame grafike briaunos neturi krypties, o ieškant trumpiausio kelio algoritmas gali važiuoti tiek pirmyn, tiek atgal išilgai kraštų.

Dijkstros algoritmo algoritmas:

  1. Pažymėkite šaltinio mazgą srovės atstumu 0, o likusius - begalybe.
  2. Nustatykite neaplankytą mazgą su mažiausiu dabartiniu atstumu kaip dabartinį mazgą.
  3. Kiekvienam kaimynui dabartinio mazgo N prideda esamą gretimo mazgo atstumą su krašto, jungiančio 0->1, svoriu. Jei jis mažesnis už dabartinį mazgo atstumą, nustatykite jį kaip naują dabartinį N atstumą.
  4. Pažymėkite dabartinį 1 mazgą kaip aplankytą.
  5. Jei yra neaplankytų mazgų, pereikite prie 2 veiksmo.

Kaip veikia Dijkstros algoritmas?

Pažiūrėkime, kaip veikia Dijkstra algoritmas su toliau pateiktu pavyzdžiu:

Dijkstra algoritmas sukurs trumpiausią kelią nuo 0 mazgo iki visų kitų grafiko mazgų.

Apsvarstykite žemiau pateiktą grafiką:

Dijkstra

Dijkstros algoritmas

Algoritmas generuos trumpiausią kelią nuo 0 mazgo iki visų kitų grafiko mazgų.

Šiame grafike darysime prielaidą, kad kraštų svoris reiškia atstumą tarp dviejų mazgų.

java skaitiklis

Kaip matome, turime trumpiausią kelią nuo
0 mazgas 1 mazgas, nuo
0 mazgas 2 mazgas, nuo
Mazgas 0 iki 3 mazgas, nuo
Mazgas 0 iki 4 mazgas, nuo
Nuo 0 iki 6 mazgo.

Iš pradžių turime toliau pateiktą išteklių rinkinį:

  • Atstumas nuo šaltinio mazgo iki jo paties yra 0. Šiame pavyzdyje šaltinio mazgas yra 0.
  • Atstumas nuo šaltinio mazgo iki visų kitų mazgų nežinomas, todėl juos visus pažymime kaip begalybę.

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

  • taip pat turėsime daugybę nelankytų elementų, kurie stebės nelankytus arba nepažymėtus mazgus.
  • Algoritmas bus baigtas, kai visi mazgai pažymėti kaip aplankyti ir atstumas tarp jų bus pridėtas prie kelio. Nelankyti mazgai:- 0 1 2 3 4 5 6.

1 žingsnis: Pradėkite nuo 0 mazgo ir pažymėkite Mazgą kaip aplankytą, nes galite užsiregistruoti žemiau esančiame aplankytame paveikslėlyje Mazgas pažymėtas raudonai.

Dijkstra

Dijkstros algoritmas

2 žingsnis: Patikrinkite, ar nėra gretimų mazgų. Dabar turime pasirinkti (arba pasirinkti 1 mazgą, kurio atstumas yra 2, arba 2 mazgą su atstumu 6 ) ir pasirinkti Mazgą su mažiausiu atstumu. Šiame žingsnyje 1 mazgas yra Minimalus atstumas šalia mazgo, todėl pažymėjo jį kaip aplankytą ir pridėkite atstumą.

Atstumas: 0 mazgas -> 1 mazgas = 2

Dijkstra

Dijkstros algoritmas

3 veiksmas: Tada pereikite į priekį ir patikrinkite, ar nėra gretimo mazgo, kuris yra 3 mazgas, todėl pažymėjote jį kaip aplankytą ir pridėkite atstumą. Dabar atstumas bus toks:

Atstumas: 0 mazgas -> 1 mazgas -> 3 mazgas = 2 + 5 = 7

ins raktas
Dijkstra

Dijkstros algoritmas

4 veiksmas: Vėlgi, turime du gretimų mazgų pasirinkimus (galime pasirinkti 4 mazgą, kurio atstumas yra 10, arba 5 mazgą, kurio atstumas yra 15), todėl pasirinkite Mazgą su minimaliu atstumu. Šiame žingsnyje 4 mazgas yra Minimalus atstumas šalia mazgo, todėl pažymėjo jį kaip aplankytą ir pridėkite atstumą.

Atstumas: 0 mazgas -> 1 mazgas -> 3 mazgas -> 4 mazgas = 2 + 5 + 10 = 17

Dijkstra

Dijkstros algoritmas

5 veiksmas: Vėlgi, pereikite į priekį ir patikrinkite, ar nėra gretimo mazgo, kuris yra 6 mazgas , todėl pažymėjote kaip aplankytą ir pridėkite atstumą, Dabar atstumas bus:

Atstumas: 0 mazgas -> 1 mazgas -> 3 mazgas -> 4 mazgas -> 6 mazgas = 2 + 5 + 10 + 2 = 19

Dijkstra

Dijkstros algoritmas

už loop bash

Taigi, trumpiausias atstumas nuo šaltinio viršūnės yra 19, kuris yra optimalus

Dijkstros algoritmo pseudo kodas

funkcija Dijkstra (grafikas, šaltinis):
// Atstumus iki visų mazgų inicijuokite kaip begalybę, o iki šaltinio mazgo – kaip 0.

atstumai = žemėlapis (visi mazgai -> begalybė)

atstumai = 0

// Inicijuokite tuščią aplankytų mazgų rinkinį ir prioritetinę eilę, kad galėtumėte sekti aplankomus mazgus.
aplankyta = tuščias rinkinys
eilė = nauja PriorityQueue()
queue.enqueue(šaltinis, 0)

// Ciklas, kol bus aplankyti visi mazgai.
kol eilė nėra tuščia:
// Ištraukite į eilę mazgo, kurio atstumas yra mažiausias nuo prioritetinės eilės.
srovė = eilė.dequeue()

// Jei mazgas jau buvo aplankytas, praleiskite jį.
jei dabar lankėtės:
Tęsti

// Pažymėkite mazgą kaip aplankytą.
visited.add(current)

// Patikrinkite visus gretimus mazgus, kad pamatytumėte, ar jų atstumus reikia atnaujinti.
kaimynui Graph.neighbors(dabartinis):
// Apskaičiuokite preliminarų atstumą iki kaimyno per dabartinį mazgą.
preliminarus_atstumas = atstumai[dabartinis] + grafikas.atstumas(dabartinis, kaimynas)

// Jei preliminarus atstumas yra mažesnis nei dabartinis atstumas iki kaimyno, atnaujinkite atstumą.
jei preliminarus_atstumas
atstumai[kaimynas] = preliminarus_atstumas

// Įkelkite kaimyną į eilę su nauju atstumu, kad jį būtų galima aplankyti ateityje.
eilė.eilė(kaimynas, atstumai[kaimynas])

// Grąžinti apskaičiuotus atstumus nuo šaltinio iki visų kitų grafiko mazgų.
grįžimo atstumai

Dijkstros algoritmo įgyvendinimas:

Yra keli Dijkstra algoritmo įgyvendinimo būdai, tačiau dažniausiai naudojami šie:

  1. Prioritetinė eilė (diegimas pagal krūvą):
  2. Masyvu pagrįstas diegimas:

1. Dijkstra trumpiausio kelio algoritmas naudojant priority_queue (heap)

Šiame įgyvendinime mums pateikiamas grafikas ir grafo šaltinio viršūnė, surandant trumpiausius kelius nuo šaltinio iki visų duoto grafo viršūnių.

Pavyzdys:

Įvestis: Šaltinis = 0

Pavyzdys

Išvestis: Viršūnė

Viršūnių atstumas nuo šaltinio

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

Žemiau pateikiamas algoritmas, pagrįstas aukščiau pateikta idėja:

  • Inicijuoti atstumo reikšmes ir prioriteto eilę.
  • Įdėkite šaltinio mazgą į prioritetinę eilę su 0 atstumu.
  • Nors prioritetinė eilė nėra tuščia:
    • Išskleiskite mazgą, esantį mažiausiu atstumu nuo prioritetinės eilės.
    • Atnaujinkite kaimynų atstumus, jei randamas trumpesnis kelias.
    • Į prioritetinę eilę įterpkite atnaujintus kaimynus.

Žemiau pateikiamas aukščiau pateikto metodo C++ įgyvendinimas:

C++
// Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef pora iPair; // Ši klasė vaizduoja nukreiptą grafiką naudojant // gretimų sąrašo reprezentacijos klasė Graph { int V; // Viršūnių skaičius // Svertiniame grafe turime išsaugoti kiekvieno briaunų sąrašo viršūnę // ir svorio porą>> adj; vieša: Grafas(int V); // Konstruktorius // funkcija pridėti briauną į grafiką void addEdge(int u, int v, int w);  // spausdina trumpiausią kelią iš s void shortestPath(int s); }; // Skiria atmintį gretimų sąrašui Graph::Graph(int V) { this->V = V;  adj = naujas sąrašas [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)); } // Spausdina trumpiausius kelius nuo src iki visų kitų viršūnių void Graph::shortestPath(int src) { // Sukurkite prioritetinę eilę viršūnėms, kurios // yra iš anksto apdorojamos, saugoti. Tai keista C++ sintaksė.  // Norėdami sužinoti daugiau apie šią sintaksę, žr. toliau pateiktą nuorodą // https://www.techcodeview.com priority_queue , didesnis > pq;  // Sukurkite atstumų vektorių ir inicijuokite visus // atstumus kaip begalinį (INF) vektorių dist(V, INF);  // Įterpti patį šaltinį į prioritetinę eilę ir inicijuoti // jo atstumą kaip 0. pq.push(make_pair(0, src));  dist[src] = 0;  /* Perėjimas, kol prioritetinė eilė tampa tuščia (arba visi atstumai nėra užbaigti) */ while (!pq.empty()) { // Pirmoji poros viršūnė yra mažiausias atstumas // viršūnė, ištraukite ją iš prioritetinės eilės.  // viršūnių etiketė saugoma antroje poroje (tai // turi būti padaryta taip, kad viršūnės išliktų // surūšiuotas atstumas (atstumas turi būti pirmasis elementas // poroje) int u = pq.top().second; pq.pop(); // 'i' naudojamas visoms gretimoms // viršūnių sąrašo viršūnėms gauti>::iteratorius i;  for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Gauti viršūnės etiketę ir srovės svorį // greta u.  int v = (*i).pirma;  int svoris = (*i).sekundė;  // Jei yra sutrumpintas kelias į v per u.  if (dist[v]> dist[u] + svoris) { // Atnaujinamas v atstumas dist[v] = dist[u] + svoris;  pq.push(make_pair(dist[v], v));  } } } // Spausdinti trumpiausius atstumus, saugomus dist[] printf('Vertex Distance from Source
');  už (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{ int v;  int atstumas;  viešasis mazgas(int v, int atstumas) { this.v = v;  tai.atstumas = atstumas;  } @Nepaisyti viešosios int palygintiTo(Node n) { if (this.distance<= n.distance) {  return -1;  }  else {  return 1;  }  }  }  static int[] dijkstra(  int V,  ArrayList >> adj, int S) { loginis [] aplankytas = naujas loginis [V];  HashMap žemėlapis = naujas HashMap();  PriorityQueueq = new PriorityQueue();  map.put(S, new Node(S, 0));  q.add(new Node(S, 0));  while (!q.isEmpty()) { Mazgas n = q.poll();  int v = n.v;  int atstumas = n.atstumas;  aplankytas[v] = tiesa;  ArrayList > adjList = adj.get(v);  už (ArrayList adjLink : adjList) { if (aplankyta[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), naujas mazgas (v, atstumas + adjLink.get(1)));  } else { Mazgas sn = map.get(adjLink.get(0));  if (atstumas + 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 >> žemėlapis = naujas 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 };  už (int i = 0; i< E; i++) {  ArrayList kraštas = naujas ArrayList();  kraštas.add(v[i]);  kraštas.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 kraštas2 = naujas ArrayList();  kraštas2.add(u[i]);  kraštas2.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));  } }>
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;  // Konstruktorius public Graph(int v) { V = v;  adj = naujas sąrašas>[ v ];  už (int i = 0; i< v; ++i)  adj[i] = new List>();  } // funkcija pridėti briauną į grafiką public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w));  adj[v].Add(Tuple.Create(u, w));  } // spausdina trumpiausią kelią iš s public void shortestPath(int s) { // Sukurkite prioritetinę eilę, kurioje saugomos viršūnės, kurios // yra iš anksto apdorojamos.  var pq = nauja PriorityQueue>();  // Sukurti atstumų vektorių ir inicijuoti visus // atstumus kaip begalinius (INF) var dist = new int[V];  už (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] + svoris) { // Atnaujinamas v atstumas dist[v] = dist[u] + svoris;  pq.Enqueue(Tuple.Create(dist[v], v));  } } } // Spausdinti trumpiausius atstumus, saugomus dist[] Console.WriteLine('Vertex Distance from Source');  už (int i = 0; i< V; ++i)  Console.WriteLine('{0}		{1}', i, dist[i]);  } } public class PriorityQueue{ privatus, tik skaitomas sąrašas_duomenys;  privatus, tik skaitomas palyginimas_palyginti;  public PriorityQueue(): this(Palyginti.Numatytasis) { } public PriorityQueue(IComparerpalyginti): this(palyginti.Palyginti) { } public PriorityQueue(palyginimaspalyginimas) { _duomenys = naujas sąrašas();  _palyginti = palyginimas;  } public void Eilė(T elementas) { _duomenys.Pridėti(elementas);  var childIndex = _duomenys.Skaičius – 1;  while (childIndex> 0) { var parentIndex = (childIndex - 1) / 2;  if (_palyginti(_duomenys[vaikoIndeksas], _duomenys[parentIndex])>= 0) pertrauka;  T tmp = _duomenys[vaiko indeksas];  _duomenys[vaikoIndeksas] = _duomenys[parentIndex];  _duomenys[parentIndex] = tmp;  vaikasIndex = parentIndex;  } } public T Dequeue() { // daro prielaidą, kad pq ​​nėra tuščias; iki iškvietimo kodo var lastElement = _duomenys.Skaičius - 1;  var frontItem = _duomenys[0];  _duomenys[0] = _duomenys[paskutinis elementas];  _data.RemoveAt(lastElement);  --lastElement;  var parentIndex = 0;  while (true) { var childIndex = parentIndex * 2 + 1;  if (childIndex> lastElement) pertrauka; // Medžio pabaiga var rightChild = vaikasIndex + 1;  jei (teisingasVaikas<= 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 Grafikas { konstruktorius(V) { this.V = V;  this.adj = naujas Masyvas(V);  for (tegul 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();>

Galutinis atsakymas:

Išvestis

Dijkstra algoritmo sudėtingumo analizė :

  • Laiko sudėtingumas: O((V + E) log V) , kur V yra viršūnių skaičius, o E yra briaunų skaičius.
  • Pagalbinė erdvė: O(V), kur V – viršūnių skaičius, o E – kraštinių skaičius grafe.

2.Masyvu pagrįstas Dijkstros algoritmo įgyvendinimas (naivus požiūris):

Dijkstra algoritmas taip pat gali būti įgyvendintas naudojant masyvus, nenaudojant prioritetinės eilės. Šis įgyvendinimas yra nesudėtingas, bet gali būti ne toks efektyvus, ypač dideliuose grafikuose.

Algoritmas vyksta taip:

skaitytuvas java
  • Inicijuokite masyvą, kad išsaugotumėte atstumus nuo šaltinio iki kiekvieno mazgo.
  • Pažymėkite visus mazgus kaip nelankytus.
  • Nustatykite atstumą iki šaltinio mazgo kaip 0 ir begalybę visiems kitiems mazgams.
  • Kartokite, kol aplankysite visus mazgus:
    • Raskite nelankytą mazgą su mažiausiu žinomu atstumu.
    • Atnaujinkite dabartinio mazgo nelankytų kaimynų atstumus.
    • Pažymėkite dabartinį mazgą kaip aplankytą.

Sudėtingumo analizė:

  • Laiko sudėtingumas: O(V^2) blogiausiu atveju, kur V yra viršūnių skaičius. Tai gali būti patobulinta iki O(V^2) su tam tikrais optimizavimais.
  • Pagalbinė erdvė: O(V), kur V – viršūnių skaičius, o E – kraštinių skaičius grafe.

Dijkstra algoritmai vs Bellman-Ford algoritmas

Dijkstros algoritmas ir Bellman-Ford algoritmas Abu yra naudojami norint rasti trumpiausią kelią svertiniame grafike, tačiau jie turi keletą pagrindinių skirtumų. Štai pagrindiniai Dijkstra algoritmo ir Bellman-Ford algoritmo skirtumai:

Ypatybė:Dijkstra'sBelmanas Fordas
Optimizavimasoptimizuotas rasti trumpiausią kelią tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neneigiamais kraštų svoriaisBellman-Ford algoritmas yra optimizuotas ieškant trumpiausio kelio tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neigiamais kraštų svoriais.
AtsipalaidavimasDijkstra algoritmas naudoja godų metodą, kai pasirenka mazgą su mažiausiu atstumu ir atnaujina savo kaimynusBellman-Ford algoritmas atpalaiduoja visas kiekvienos iteracijos briaunas, atnaujindamas kiekvieno mazgo atstumą, atsižvelgdamas į visus galimus kelius į tą mazgą
Laiko sudėtingumasDijkstra algoritmo laiko sudėtingumas yra O(V^2) tankiam grafui ir O(E log V) retam grafikui, kur V yra viršūnių skaičius, o E yra grafo briaunų skaičius.Bellman-Ford algoritmo laiko sudėtingumas yra O(VE), kur V yra viršūnių skaičius, o E yra grafo briaunų skaičius.
Neigiami svoriaiDijkstra algoritmas neveikia su grafikais, kurių kraštų svoriai yra neigiami, nes daroma prielaida, kad visi briaunų svoriai yra neneigiami.Bellman-Ford algoritmas gali apdoroti neigiamus kraštų svorius ir aptikti neigiamo svorio ciklus grafike.

Dijkstros algoritmas prieš Floydo-Warshall algoritmą

Dijkstros algoritmas ir Floydo-Warshall algoritmas Abu yra naudojami norint rasti trumpiausią kelią svertiniame grafike, tačiau jie turi keletą pagrindinių skirtumų. Štai pagrindiniai Dijkstra algoritmo ir Floydo-Warshall algoritmo skirtumai:

Ypatybė:Dijkstra'sFloydo-Warshall algoritmas
OptimizavimasOptimizuotas norint rasti trumpiausią kelią tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neneigiamais kraštų svoriaisFloydo-Warshall algoritmas yra optimizuotas norint rasti trumpiausią kelią tarp visų grafiko mazgų porų.
TechnikaDijkstra algoritmas yra vieno šaltinio trumpiausio kelio algoritmas, kuris naudoja godų metodą ir apskaičiuoja trumpiausią kelią nuo šaltinio mazgo iki visų kitų grafiko mazgų.Kita vertus, Floydo-Warshall algoritmas yra visų porų trumpiausio kelio algoritmas, kuris naudoja dinaminį programavimą, kad apskaičiuotų trumpiausią kelią tarp visų grafiko mazgų porų.
Laiko sudėtingumasDijkstra algoritmo laiko sudėtingumas yra O(V^2) tankiam grafui ir O(E log V) retam grafikui, kur V yra viršūnių skaičius, o E yra grafo briaunų skaičius.Kita vertus, Floydo-Warshall algoritmas yra visų porų trumpiausio kelio algoritmas, kuris naudoja dinaminį programavimą, kad apskaičiuotų trumpiausią kelią tarp visų grafiko mazgų porų.
Neigiami svoriaiDijkstra algoritmas neveikia su grafikais, kurių kraštų svoriai yra neigiami, nes daroma prielaida, kad visi briaunų svoriai yra neneigiami.Kita vertus, Floydo-Warshall algoritmas yra visų porų trumpiausio kelio algoritmas, kuris naudoja dinaminį programavimą, kad apskaičiuotų trumpiausią kelią tarp visų grafiko mazgų porų.

Dijkstros algoritmas prieš A* algoritmą

Dijkstros algoritmas ir A* algoritmas Abu yra naudojami norint rasti trumpiausią kelią svertiniame grafike, tačiau jie turi keletą pagrindinių skirtumų. Štai pagrindiniai Dijkstra algoritmo ir A* algoritmo skirtumai:

Ypatybė: A* Algoritmas
Paieškos technikaOptimizuotas norint rasti trumpiausią kelią tarp vieno šaltinio mazgo ir visų kitų mazgų grafike su neneigiamais kraštų svoriaisA* algoritmas yra informuotas paieškos algoritmas, kuris naudoja euristinę funkciją, kad nukreiptų paiešką link tikslo mazgo.
Euristinė funkcijaDijkstra algoritmas, nenaudoja jokios euristinės funkcijos ir atsižvelgia į visus grafiko mazgus.A* algoritmas naudoja euristinę funkciją, kuri įvertina atstumą nuo dabartinio mazgo iki tikslo mazgo. Ši euristinė funkcija yra leistina, tai reiškia, kad ji niekada nepervertina tikrojo atstumo iki tikslo mazgo
Laiko sudėtingumasDijkstra algoritmo laiko sudėtingumas yra O(V^2) tankiam grafui ir O(E log V) retam grafikui, kur V yra viršūnių skaičius, o E yra kraštinių skaičius grafe.A* algoritmo laiko sudėtingumas priklauso nuo euristinės funkcijos kokybės.
TaikymasDijkstra algoritmas naudojamas daugelyje programų, tokių kaip maršruto algoritmai, GPS navigacijos sistemos ir tinklo analizė. A* algoritmas dažniausiai naudojamas kelio nustatymo ir grafiko perėjimo problemoms, tokioms kaip vaizdo žaidimai, robotika ir planavimo algoritmai.

Dijkstra algoritmo praktikos problemos:

  1. Dijkstra trumpiausio kelio algoritmas | Godus Algo-7
  2. Dijkstra algoritmas gretimų vietų sąrašui pateikti | Godus Algo-8
  3. Dijkstra algoritmas – prioritetinė eilė ir masyvo įgyvendinimas
  4. Dijkstra trumpiausio kelio algoritmas, naudojant rinkinį STL
  5. Dijkstra trumpiausio kelio algoritmas naudojant STL C++
  6. Dijkstra trumpiausio kelio algoritmas, naudojant STL priority_queue
  7. Dijkstra trumpiausio kelio algoritmas naudojant matricą C++
  8. Dijkstra algoritmas, skirtas vieno šaltinio trumpiausiam keliui DAG
  9. Dijkstros algoritmas naudojant Fibonacci Heap
  10. Dijkstra trumpiausio kelio algoritmas nukreiptam grafikui su neigiamais svoriais
  11. Kelių spausdinimas Dijkstra trumpiausio kelio algoritmu
  12. Dijkstra trumpiausio kelio algoritmas su prioritetine eile Java