logo

Kas ir Dijkstras algoritms? | Ievads Dijkstra īsākā ceļa algoritmā

Šajā rakstā mēs apspriedīsim vienu no visbiežāk zināmajiem īsākā ceļa algoritmiem, t.i., Dijkstra īsākā ceļa algoritmu, ko 1956. gadā izstrādāja nīderlandiešu datorzinātnieks Edsgers V. Dijkstra. Turklāt mēs veiksim šī algoritma sarežģītības analīzi, kā arī redzēt, kā tas atšķiras no citiem īsākā ceļa algoritmiem.

Satura rādītājs

dijkstra-algoritm-(1)



Dijkstras algoritms:

Dijkstras algoritms ir populārs algoritms daudzu viena avota īsākā ceļa problēmu risināšanai ar nenegatīvu malu svaru grafos, t.i., tas ir, lai atrastu īsāko attālumu starp divām grafa virsotnēm. To izstrādāja holandiešu datorzinātnieks Edsgers V. Dijkstra 1956. gadā.

Algoritms uztur apmeklēto virsotņu kopu un neapmeklēto virsotņu kopu. Tas sākas no avota virsotnes un iteratīvi atlasa neapmeklēto virsotni ar vismazāko provizorisko attālumu no avota. Pēc tam tas apmeklē šīs virsotnes kaimiņus un atjaunina to provizoriskos attālumus, ja tiek atrasts īsāks ceļš. Šis process turpinās, līdz tiek sasniegta galamērķa virsotne vai ir apmeklētas visas sasniedzamās virsotnes.

Nepieciešamība pēc Dijkstra algoritma (mērķis un lietošanas gadījumi)

Nepieciešamība pēc Dijkstra algoritma rodas daudzās lietojumprogrammās, kur ir ļoti svarīgi atrast īsāko ceļu starp diviem punktiem.

Piemēram , To var izmantot datortīklu maršrutēšanas protokolos, kā arī izmantot karšu sistēmās, lai atrastu īsāko ceļu starp sākuma punktu un galamērķi (kā paskaidrots Kā darbojas Google Maps? )

Vai Dijkstras algoritms var darboties gan ar virzītiem, gan nevirzītiem grafikiem?

, Dijkstra algoritms var darboties gan ar virzītiem grafikiem, gan nevirzītiem grafikiem, jo ​​šis algoritms ir paredzēts darbam ar jebkura veida grafikiem, ja vien tas atbilst nenegatīvu malu svara un savienojuma prasībām.

  • Virzītā grafikā katrai malai ir virziens, kas norāda kustības virzienu starp virsotnēm, kuras savieno mala. Šajā gadījumā algoritms, meklējot īsāko ceļu, seko malu virzienam.
  • Nevirzītā grafikā malām nav virziena, un algoritms var šķērsot gan uz priekšu, gan atpakaļ gar malām, meklējot īsāko ceļu.

Algoritms Dijkstras algoritmam:

  1. Atzīmējiet avota mezglu ar strāvas attālumu 0 un pārējo ar bezgalību.
  2. Iestatiet neapmeklēto mezglu ar mazāko pašreizējo attālumu kā pašreizējo mezglu.
  3. Katram kaimiņam pašreizējā mezgla N pievieno blakus esošā mezgla pašreizējo attālumu ar malas svaru, kas savieno 0->1. Ja tas ir mazāks par pašreizējo Node attālumu, iestatiet to kā jauno pašreizējo attālumu N.
  4. Atzīmējiet pašreizējo mezglu 1 kā apmeklētu.
  5. Ja ir neapmeklēti mezgli, pārejiet uz 2. darbību.

Kā darbojas Dijkstras algoritms?

Apskatīsim, kā darbojas Dijkstra algoritms, izmantojot tālāk sniegto piemēru:

Dijkstra algoritms ģenerēs īsāko ceļu no 0. mezgla uz visiem pārējiem diagrammas mezgliem.

Apsveriet tālāk redzamo grafiku:

Dijkstra

Dijkstras algoritms

Algoritms ģenerēs īsāko ceļu no mezgla 0 uz visiem pārējiem diagrammas mezgliem.

Šajā diagrammā mēs pieņemsim, ka malu svars atspoguļo attālumu starp diviem mezgliem.

mainīt pievienot kolonnu orākuls

Kā redzam, mums ir īsākais ceļš no
Node 0 līdz Node 1, no
Node 0 līdz Node 2, no
Node 0 līdz Node 3, no
Node 0 līdz Node 4, no
No 0 līdz 6. mezglam.

Sākotnēji mums ir tālāk norādīts resursu kopums:

  • Attālums no avota mezgla līdz pašam ir 0. Šajā piemērā avota mezgls ir 0.
  • Attālums no avota mezgla līdz visiem pārējiem mezgliem nav zināms, tāpēc mēs tos visus atzīmējam kā bezgalību.

Piemērs: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.

  • mums būs arī virkne neapmeklētu elementu, kas sekos līdzi neapmeklētajiem vai neatzīmētajiem mezgliem.
  • Algoritms tiks pabeigts, kad visi mezgli ir atzīmēti kā apmeklēti un attālums starp tiem tiks pievienots ceļam. Neapmeklētie mezgli:- 0 1 2 3 4 5 6.

1. darbība: Sāciet no 0. mezgla un atzīmējiet mezglu kā apmeklētu, jo varat reģistrēties zemāk apmeklētajā attēlā. Mezgls ir atzīmēts sarkanā krāsā.

Dijkstra

Dijkstras algoritms

2. darbība: Pārbaudiet blakus esošos mezglus. Tagad mums ir jāizvēlas (vai nu jāizvēlas mezgls 1 ar attālumu 2, vai arī jāizvēlas mezgls 2 ar attālumu 6) un jāizvēlas mezgls ar minimālo attālumu. Šajā solī 1. mezgls ir Minimālais attālums blakus mezglam, tāpēc atzīmējiet to kā apmeklētu un saskaitiet attālumu.

Attālums: 0. mezgls —> 1. mezgls = 2

Dijkstra

Dijkstras algoritms

3. darbība: Pēc tam pārejiet uz priekšu un pārbaudiet blakus esošo mezglu, kas ir 3. mezgls, atzīmējiet to kā apmeklētu un saskaitiet attālumu. Tagad attālums būs:

Attālums: mezgls 0 -> mezgls 1 -> mezgls 3 = 2 + 5 = 7

Dijkstra

Dijkstras algoritms

4. darbība: Atkal mums ir divas izvēles iespējas blakus esošajiem mezgliem (vai nu mēs varam izvēlēties mezglu 4 ar attālumu 10, vai nu mēs varam izvēlēties mezglu 5 ar attālumu 15), tāpēc izvēlieties mezglu ar minimālo attālumu. Šajā solī 4. mezgls ir Minimālais attālums blakus mezglam, tāpēc atzīmējiet to kā apmeklētu un saskaitiet attālumu.

cik daudz ir neiespējamās misijas filmu

Attālums: mezgls 0 -> mezgls 1 -> mezgls 3 -> mezgls 4 = 2 + 5 + 10 = 17

Dijkstra

Dijkstras algoritms

5. darbība: Atkal pārejiet uz priekšu un pārbaudiet, vai nav blakus mezgla 6. mezgls , tāpēc atzīmēja to kā apmeklētu un saskaiti attālumu. Tagad attālums būs:

Attālums: mezgls 0 -> mezgls 1 -> mezgls 3 -> mezgls 4 -> mezgls 6 = 2 + 5 + 10 + 2 = 19

Dijkstra

Dijkstras algoritms

Tātad īsākais attālums no avota virsotnes ir 19, kas ir optimāls

Dijkstras algoritma pseido kods

funkcija Dijkstra (grafiks, avots):
// Attālumus līdz visiem mezgliem inicializējiet kā bezgalību un līdz avota mezglam kā 0.

kas ir automātiski pieslēgts java

attālumi = karte (visi mezgli -> bezgalība)

attālumi = 0

// Inicializējiet tukšu apmeklēto mezglu kopu un prioritāro rindu, lai izsekotu apmeklējamajiem mezgliem.
apmeklēts = tukšs komplekts
rinda = jauns PriorityQueue()
queue.enqueue(avots, 0)

// Cilpa, līdz visi mezgli ir apmeklēti.
kamēr rinda nav tukša:
// Atvienojiet mezglu ar mazāko attālumu no prioritārās rindas.
pašreizējais = rinda.dequeue()

// Ja mezgls jau ir apmeklēts, izlaidiet to.
ja pašreiz ir apmeklēts:
Turpināt

// Atzīmēt mezglu kā apmeklētu.
visited.add(pašreizējais)

// Pārbaudiet visus blakus esošos mezglus, lai redzētu, vai to attālumi ir jāatjaunina.
kaimiņam programmā Graph.neighbors (pašreizējais):
// Aprēķināt provizorisko attālumu līdz kaimiņam caur pašreizējo mezglu.
pagaidu_attālums = attālumi[pašreizējais] + grafiks.attālums(pašreizējais, kaimiņš)

// Ja provizoriskais attālums ir mazāks par pašreizējo attālumu līdz kaimiņam, atjauniniet attālumu.
ja provizoriskais_attālums
distances[kaimiņš] = provizoriskais_attālums

// Ievietojiet kaimiņu rindā ar savu jauno attālumu, lai nākotnē to varētu apmeklēt.
rinda.rinda(kaimiņš, attālumi[kaimiņš])

// Atgriezt aprēķinātos attālumus no avota līdz visiem citiem diagrammas mezgliem.
atgriešanās attālumi

Dijkstra algoritma ieviešana:

Ir vairāki veidi, kā ieviest Dijkstra algoritmu, taču visizplatītākie ir:

  1. Prioritātes rinda (uz kaudzes balstīta ieviešana):
  2. Uz masīvu balstīta ieviešana:

1. Dijkstra īsākā ceļa algoritms, izmantojot priority_queue (kaudze)

Šajā realizācijā mums ir dots grafs un grafa avota virsotne, atrodot īsākos ceļus no avota uz visām dotā grafa virsotnēm.

Piemērs:

Ievade: Avots = 0

Piemērs

Izvade: Virsotne

Virsotnes attālums no avota

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

Zemāk ir algoritms, kas balstīts uz iepriekš minēto ideju:

  • Inicializējiet attāluma vērtības un prioritātes rindu.
  • Ievietojiet avota mezglu prioritārajā rindā ar attālumu 0.
  • Kamēr prioritārā rinda nav tukša:
    • Izvelciet mezglu ar minimālo attālumu no prioritārās rindas.
    • Ja tiek atrasts īsāks ceļš, atjauniniet tā kaimiņu attālumus.
    • Ievietojiet atjauninātos kaimiņus prioritārajā rindā.

Tālāk ir sniegta iepriekš minētās pieejas C++ ieviešana:

C++
// Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>Integer Pair typedef pāris iPair; // Šī klase attēlo virzītu grafiku, izmantojot // blakus esošo sarakstu reprezentācijas klase Graph { int V; // Virsotņu skaits // Svērtajā grafikā mums ir jāsaglabā virsotnes // un svara pāris katram malu sarakstam>> adj; public: Graph(int V); // Konstruktors // funkcija malas pievienošanai grafikam void addEdge(int u, int v, int w);  // izdrukā īsāko ceļu no s void shortestPath(int s); }; // Piešķir atmiņu blakus sarakstam Graph::Graph(int V) { this->V = V;  adj = jauns saraksts [V]; } void Graph::pievienotEdge(int u, int v, int w) { adj[u].push_back(make_pair(v, w));  adj[v].push_back(make_pair(u, w)); } // Drukā īsākos ceļus no src uz visām pārējām virsotnēm void Graph::shortestPath(int src) { // Izveidojiet prioritāru rindu, lai saglabātu virsotnes, kuras // tiek iepriekš apstrādātas. Šī ir dīvaina sintakse valodā C++.  // Sīkāku informāciju par šo sintaksi skatiet tālāk norādītajā saitē // https://www.techcodeview.com priority_queue , lielāks > pq;  // Izveidojiet vektoru attālumiem un inicializējiet visus // attālumus kā bezgalīgu (INF) vektoru dist(V, INF);  // Ievietot pašu avotu prioritārā rindā un inicializēt // tā attālumu kā 0. pq.push(make_pair(0, src));  dist[src] = 0;  /* Cilpas, līdz prioritātes rinda kļūst tukša (vai visi attālumi nav pabeigti) */ while (!pq.empty()) { // Pirmā virsotne pārī ir minimālais attālums // virsotne, izņemiet to no prioritārās rindas.  // virsotnes etiķete tiek saglabāta pāra otrajā daļā (tas // ir jādara šādi, lai saglabātu virsotnes // sakārtotu attālumu (attālumam jābūt pirmajam vienumam // pārī) int u = pq.top().second; pq.pop(); // 'i' tiek izmantots, lai iegūtu visas // virsotņu saraksta blakus esošās virsotnes>::iterators i;  for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Iegūt virsotnes etiķeti un strāvas svaru // blakus u.  int v = (*i).pirmais;  int svars = (*i).sekunde;  // Ja ir saīsināts ceļš uz v caur u.  if (dist[v]> dist[u] + svars) { // Atjaunināšanas attālums v dist[v] = dist[u] + svars;  pq.push(make_pair(dist[v], v));  } } } // Drukāt īsākos attālumus, kas saglabāti dist[] printf('Vertex Distance from Source
');  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; }>
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 distance;  publiskais mezgls(int v, int attālums) { this.v = v;  this.distance = attālums;  } @Override public int salīdzinātTo(Node n) { if (this.distance<= n.distance) {  return -1;  }  else {  return 1;  }  }  }  static int[] dijkstra(  int V,  ArrayList >> adj, int S) { Būla [] apmeklētais = jauns Būla [V];  HashMap karte = new HashMap();  PriorityQueueq = new PriorityQueue();  map.put(S, new Node(S, 0));  q.add(new Node(S, 0));  while (!q.isEmpty()) { Node n = q.poll();  int v = n.v;  int distance = n.attālums;  apmeklēts[v] = patiess;  ArrayList > adjList = adj.get(v);  priekš (ArrayList adjLink : adjList) { if (apmeklēts[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), new Node (v, attālums + adjLink.get(1)));  } else { Mezgls sn = map.get(adjLink.get(0));  if (attālums + 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 >> karte = 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 mala = jauns 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 mala2 = jauns ArrayList();  mala2.add(u[i]);  mala2.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;  // Konstruktors public Graph(int v) { V = v;  adj = jauns saraksts>[ v ];  for (int i = 0; i< v; ++i)  adj[i] = new List>();  } // funkcija malas pievienošanai grafikam public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w));  adj[v].Add(Tuple.Create(u, w));  } // drukā īsāko ceļu no s public void shortestPath(int s) { // Izveidojiet prioritāru rindu, lai saglabātu virsotnes, kuras // tiek iepriekš apstrādātas.  var pq = new PriorityQueue>();  // Izveidot vektoru attālumiem un inicializēt visus // attālumus kā bezgalīgus (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] + svars) { // V atjaunināšanas attālums dist[v] = dist[u] + svars;  pq.Enqueue(Tuple.Create(dist[v], v));  } } } // Drukāt īsākos attālumus, kas saglabāti dist[] Console.WriteLine('Vertex Distance from Source');  for (int i = 0; i< V; ++i)  Console.WriteLine('{0}		{1}', i, dist[i]);  } } public class PriorityQueue{ privāts tikai lasāms saraksts_data;  privāts, tikai lasāms salīdzinājums_salīdzināts;  publiskā PriorityQueue(): this(Salīdzināt.Noklusējums) { } public PriorityQueue(ICalīdzinātājssalīdzināt): this(salīdzināt.Salīdzināt) { } public PriorityQueue(Salīdzinājumssalīdzinājums) { _data = jauns saraksts();  _salīdzināt = salīdzinājums;  } public void Enqueue(T item) { _data.Add(item);  var bērnsIndekss = _dati.Skaits — 1;  while (childIndex> 0) { var parentIndex = (childIndex — 1) / 2;  if (_salīdzināt(_dati[bērnindekss], _dati[parentIndex])>= 0) pārtraukums;  T tmp = _dati[bērnindekss];  _dati[bērnindekss] = _dati[vecāku indekss];  _dati[parentIndex] = tmp;  childIndex = vecākuIndekss;  } } public T Dequeue() { // pieņem, ka pq nav tukšs; līdz izsaukšanas kodam var lastElement = _data.Count - 1;  var frontItem = _data[0];  _dati[0] = _dati[pēdējaisElements];  _data.RemoveAt(lastElement);  --lastElement;  var parentIndex = 0;  while (true) { var childIndex = vecākuIndekss * 2 + 1;  if (childIndex> lastElement) pārtraukums; // Koka beigas var rightChild = childIndex + 1;  ja (labaisBērns<= 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;  } atgriež this.queue.shift().element;  } isEmpty() { return this.queue.length === 0;  } } class Graph { konstruktors(V) { this.V = V;  this.adj = jauns Masīvs(V);  for (lai 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();>

Galīgā atbilde:

Izvade

Dijkstra algoritma sarežģītības analīze :

  • Laika sarežģītība: O((V +E) log V) , kur V ir virsotņu skaits un E ir šķautņu skaits.
  • Palīgtelpa: O(V), kur V ir virsotņu skaits un E ir grafa malu skaits.

2.Dijkstra algoritma masīva ieviešana (naivā pieeja):

Dijkstra algoritmu var ieviest arī, izmantojot masīvus, neizmantojot prioritāro rindu. Šī ieviešana ir vienkārša, taču tā var būt mazāk efektīva, it īpaši lielos grafikos.

Algoritms darbojas šādi:

  • Inicializējiet masīvu, lai saglabātu attālumus no avota līdz katram mezglam.
  • Atzīmējiet visus mezglus kā neapmeklētus.
  • Iestatiet attālumu līdz avota mezglam kā 0 un bezgalību visiem pārējiem mezgliem.
  • Atkārtojiet, līdz visi mezgli ir apmeklēti:
    • Atrodiet neapmeklēto mezglu ar mazāko zināmo attālumu.
    • Pašreizējam mezglam atjauniniet tā neapmeklēto kaimiņu attālumus.
    • Atzīmējiet pašreizējo mezglu kā apmeklētu.

Sarežģītības analīze:

  • Laika sarežģītība: O(V^2) sliktākajā gadījumā, kur V ir virsotņu skaits. To var uzlabot līdz O(V^2), veicot dažas optimizācijas.
  • Palīgtelpa: O(V), kur V ir virsotņu skaits un E ir grafa malu skaits.

Dijkstras algoritmi pret Bellmana-Forda algoritmu

Dijkstras algoritms un Bellman-Ford algoritms abi tiek izmantoti, lai atrastu īsāko ceļu svērtā grafikā, taču tiem ir dažas būtiskas atšķirības. Šeit ir galvenās atšķirības starp Dijkstra algoritmu un Bellman-Ford algoritmu:

drukāšanas paziņojums java
Iezīme:DijkstrasBelmens Fords
Optimizācijaoptimizēts, lai atrastu īsāko ceļu starp vienu avota mezglu un visiem citiem mezgliem grafikā ar nenegatīviem malu svariemBellman-Ford algoritms ir optimizēts, lai atrastu īsāko ceļu starp vienu avota mezglu un visiem citiem mezgliem grafikā ar negatīvu malu svaru.
RelaksācijaDijkstra algoritms izmanto mantkārīgu pieeju, kad tas izvēlas mezglu ar mazāko attālumu un atjaunina savus kaimiņusBellman-Ford algoritms atslābina visas malas katrā iterācijā, atjauninot katra mezgla attālumu, ņemot vērā visus iespējamos ceļus uz šo mezglu
Laika sarežģītībaDijkstras algoritma laika sarežģītība ir O(V^2) blīvam grafikam un O(E log V) retam grafam, kur V ir virsotņu skaits un E ir grafa malu skaits.Belmana-Forda algoritma laika sarežģītība ir O(VE), kur V ir virsotņu skaits un E ir grafa malu skaits.
Negatīvie svariDijkstra algoritms nedarbojas ar grafikiem, kuriem ir negatīvs malu svars, jo tiek pieņemts, ka visi malu svari nav negatīvi.Bellman-Ford algoritms var apstrādāt negatīvo malu svaru un var noteikt negatīvā svara ciklus grafikā.

Dijkstras algoritms pret Floida-Varšala algoritmu

Dijkstras algoritms un Floida-Voršala algoritms abi tiek izmantoti, lai atrastu īsāko ceļu svērtā grafikā, taču tiem ir dažas būtiskas atšķirības. Šeit ir galvenās atšķirības starp Dijkstra algoritmu un Floyd-Warshall algoritmu:

Iezīme:DijkstrasFloida-Varšala algoritms
OptimizācijaOptimizēts, lai atrastu īsāko ceļu starp vienu avota mezglu un visiem citiem mezgliem diagrammā ar nenegatīviem malu svariemFloyd-Warshall algoritms ir optimizēts, lai atrastu īsāko ceļu starp visiem grafikā esošo mezglu pāriem.
TehnikaDijkstra algoritms ir viena avota īsākā ceļa algoritms, kas izmanto mantkārīgu pieeju un aprēķina īsāko ceļu no avota mezgla uz visiem citiem diagrammas mezgliem.No otras puses, Floida-Voršala algoritms ir visu pāru īsākā ceļa algoritms, kas izmanto dinamisku programmēšanu, lai aprēķinātu īsāko ceļu starp visiem grafa mezglu pāriem.
Laika sarežģītībaDijkstras algoritma laika sarežģītība ir O(V^2) blīvam grafikam un O(E log V) retam grafam, kur V ir virsotņu skaits un E ir grafa malu skaits.No otras puses, Floida-Voršala algoritms ir visu pāru īsākā ceļa algoritms, kas izmanto dinamisku programmēšanu, lai aprēķinātu īsāko ceļu starp visiem grafa mezglu pāriem.
Negatīvie svariDijkstra algoritms nedarbojas ar grafikiem, kuriem ir negatīvs malu svars, jo tiek pieņemts, ka visi malu svari nav negatīvi.No otras puses, Floida-Voršala algoritms ir visu pāru īsākā ceļa algoritms, kas izmanto dinamisku programmēšanu, lai aprēķinātu īsāko ceļu starp visiem grafa mezglu pāriem.

Dijkstras algoritms pret A* algoritmu

Dijkstras algoritms un A* algoritms abi tiek izmantoti, lai atrastu īsāko ceļu svērtā grafikā, taču tiem ir dažas būtiskas atšķirības. Šeit ir galvenās atšķirības starp Dijkstra algoritmu un A* algoritmu:

Iezīme: A* algoritms
Meklēšanas tehnikaOptimizēts, lai atrastu īsāko ceļu starp vienu avota mezglu un visiem citiem mezgliem grafikā ar nenegatīvu malu svaruA* algoritms ir informēts meklēšanas algoritms, kas izmanto heiristisku funkciju, lai virzītu meklēšanu uz mērķa mezglu.
Heiristiskā funkcijaDijkstra algoritms neizmanto nevienu heiristisku funkciju un ņem vērā visus diagrammas mezglus.A* algoritms izmanto heiristisku funkciju, kas novērtē attālumu no pašreizējā mezgla līdz mērķa mezglam. Šī heiristiskā funkcija ir pieļaujama, kas nozīmē, ka tā nekad nepārvērtē faktisko attālumu līdz mērķa mezglam
Laika sarežģītībaDijkstras algoritma laika sarežģītība ir O(V^2) blīvam grafikam un O(E log V) retam grafam, kur V ir virsotņu skaits un E ir grafa malu skaits.A* algoritma laika sarežģītība ir atkarīga no heiristiskās funkcijas kvalitātes.
PieteikumsDijkstra algoritms tiek izmantots daudzās lietojumprogrammās, piemēram, maršrutēšanas algoritmos, GPS navigācijas sistēmās un tīkla analīzē.. A* algoritms parasti tiek izmantots ceļa noteikšanas un grafiku šķērsošanas problēmās, piemēram, videospēlēs, robotikā un plānošanas algoritmos.

Prakses problēmas Dijkstra algoritmā:

  1. Dijkstra īsākā ceļa algoritms | Mantkārīgais Algo-7
  2. Dijkstra algoritms blakus esošo sarakstu attēlošanai | Mantkārīgais Algo-8
  3. Dijkstra algoritms - prioritārā rinda un masīva ieviešana
  4. Dijkstra īsākā ceļa algoritms, izmantojot komplektu STL
  5. Dijkstra īsākā ceļa algoritms, izmantojot STL C++
  6. Dijkstra īsākā ceļa algoritms, izmantojot STL priority_queue
  7. Dijkstra īsākā ceļa algoritms, izmantojot matricu C++
  8. Dijkstras algoritms viena avota īsākajam ceļam DAG
  9. Dijkstras algoritms, izmantojot Fibonači kaudzi
  10. Dijkstra īsākā ceļa algoritms virzītam grafikam ar negatīvu svaru
  11. Ceļu drukāšana Dijkstras īsākā ceļa algoritmā
  12. Dijkstra īsākā ceļa algoritms ar prioritāro rindu Java