Dijkstra-Algorithmus-Variation in Javascript

OP (Firma: Laboratorium_S1) #7444079
Lesenswert?
• ▲
▼

Hallo.

In meinem Letzten Beitrag (Beitrag "Javascript Verkehrsleitsystem") wurde mir geraten, für das Finden des kürzesten Weges zwischen zwei Punkten den A*-Algorithmus zu verwenden.

Nach einigen Recherchen lernte ich jedoch den Dijkstra-Algorithmus kennen, der mir nicht nur verständlicher, sondern auch einfacher erscheint, da nicht berechnet werden muss, wie wahrscheinlich es ist, dass ein bestimmter Pfad eher zum Ziel führt als andere.

Ich fand nach einiger Suche Code für JavaScript, der Programmiersprache, in der ich den Algorithmus implementieren möchte, auf folgender Seite: https://www.tutorialspoint.com/Dijkstra-s-algorithm-in-Javascript

Jedoch gibt dieser die kürzeste Entfernung zu allen weiteren Knoten von einem Startknoten aus an. Ich benötige jedoch zum einen die Entfernung zu einem bestimmten Knoten, zum anderen möchte ich wissen, welchen Pfad das Programm errechnet hat.

Wie müsste ich den Code umschreiben? Wird in der "while (!pq.isEmpty())"-Schleife geprüft, ob der Ziel-Knoten schon erreicht ist?

Zu Beginn des Programms würde ich ein Array initialisieren ("let pfad = [];"), welches ebenfalls ausgegeben wird und den "zu gehenden" Pfad angibt.

In welcher Schleife werden dann die Knoten des Pfades diesem Array hinzugefügt?

Verzeiht die etwas plumpe Grußformel und Verabschiedung. Was kreative Begrüßungen und Verabschiedungen angeht, bin ich (zum Glück?) kein Profi.

Viele Grüße und Dank für jede hilfreiche Antwort Ernst

#7446711
Lesenswert?
• ▲
▼
  1. Du prüfst einfach ab ob aus "pq" dein Zielknoten herausgenommen wird. In dem Moment kannst du den Algorithmus vorzeitig terminieren:

direkt nach der Zeile let minNode = pq.dequeue();

machst du:

if minNode.node == "Zielknoten" { break; }

  1. Um den Pfad zu rekonstruieren musst du nur "prev" nutzen. prev speichert den Vorgängerknoten des kürzesten Pfades. Das heißt du fängst beim Zielknoten an prev auszuwerten und hangelst dich so rückwärts durch den kürzesten Pfad bis du irgendwann beim Startknoten angekommen bist.

Noch ein Hinweis. Dijkstra funktioniert nur mit nichtnegativen (>=0) Kantengewichten korrekt (liefert den kürzesten Pfad).

#7446726
Lesenswert?
• ▲
▼

In Pseudocode könnte das so aussehen:

1
function reconstruct_path(prev: Array, Startknoten, Zielknoten) {
2
  let curNode = Zielknoten;
3
  let Pfad : Array = [Zielknoten];
4
  
5
  while curNode != Startknoten {
6
    //ist ein Vorgänger für diesen Knoten hinterlegt?
7
    //wenn nicht dann gibt es keinen Pfad vom Start- zum Zielknoten
8
    if curNode != null {
9
      curNode = prev[curNode];
10
      Pfad.push(curNode);
11
    } else {
12
      throw new Exception("Es gibt keinen Pfad vom Startknoten zum Zielknoten");
13
    }
14
  }
15
  
16
  //bei Bedarf den Pfad umdrehen
17
  return Pfad.reverseArray();
18
}
#7446812
Lesenswert?
• ▲
▼

Theoretisch reicht es den else Zweig

1
} else {
2
      throw new Exception("Es gibt keinen Pfad vom Startknoten zum Zielknoten");
3
    }

genau einmal für den Zielknoten am Anfang (vor der Schleife) auszuführen. Denn wenn dieser Knoten einen Vorgänger hat muss der Algorithmus vom Startknoten aus irgendwann dort hingekommen sein. Es gibt also einen Pfad. So kann man den Algorithmus etwas optimieren...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 3 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.