Praktische Einführung und Programmierung
Stefan Bosse
Universität Koblenz - FB Informatik
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen ::
Warum der ICE im Dörfchen Oberau hält - aber nicht in Koblenz
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Grundlagen der Graphen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Vertiefende Literatur
[1] H. Ernst, J. Schmidt, and G. Beneken, Grundkurs Informatik. Springer, 2023.
Auch die bereits behandelten Bäume sind ein Spezialfall von Graphen. Tatsächlich handelt es sich bei Graphen um eine der wichtigsten Datenstrukturen in der Programmierung, die in vielen Anwendungsgebieten zum Einsatz kommen.
Ein Graph besteht grob aus mit Kanten verbundenen Knoten.
Unterschiede gibt es in der Art der Kanten sowie in der Realisierung der Kanten und Knoten in einer Datenstruktur, die sich auf die Effizienz der unterschiedlichen Graphenfunktionen auswirkt.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Grundlagen der Graphen
Graphen können realen Umgebungen abbilden und abstrahieren
Das Königsberger Brückenproblem. Oben eine Skizze der Innenstadt von Königsberg im 18. Jahrhundert. Unten eine Repräsentation als Graph, wobei die Stadtteile als Knoten und die Brücken als Kanten dargestellt sind
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Taxonomie der Graphen
Graphen werden als eine durch Kanten verbundene Menge von Knoten definiert. Wir werden insbesondere die folgenden drei Klassen von Graphen näher betrachten:
Bei ungerichteten Graphen wird angegeben, welcher Knoten mit welchem verbunden ist, ohne dass eine Richtung vorgegeben wird. Ist allgemein von Graphen ohne nähere Einschränkung die Rede, sind in der Regel ungerichtete Graphen gemeint. Typische Anwendungen von ungerichteten Graphen sind die Modellierung von Straßenverbindungen (ohne Einbahnstraßen!), der Nachbarschaft von Gegenständen oder eines Telefonnetzes.
Gerichtete Graphen unterscheiden sich von den ungerichteten dadurch, dass Kanten eine Richtung haben. Auch können zwei Knoten nun durch zwei Kanten (d.h. in jeder Richtung eine) verbunden sein.
Typische Beispiele sind Modelle von Förderanlagen, der Kontrollfluss in Programmen oder auch Petri-Netze (Abluafdiagramme mit Tokens).
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Taxonomie der Graphen
Beispiele sind die Vorfahrenbeziehung in Stammbäumen und die Vererbung in Programmiersprachen. Ein DAG ist natürlich als Datenstruktur ein normaler gerichteter Graph; relevant ist hier allerdings der möglichst effiziente Test auf Zyklenfreiheit.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Ungerichtete Graphen
Die Definition von (ungerichteten) Graphen erfolgt in Form eines Zweiertupels G = (V, E). Ein Graph besteht aus
Jedes e ∊ E ist dabei eine zweielementige Teilmenge der Knotenmenge V.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Ungerichtete Graphen
Als Beispiel für diese Formalisierung von Graphen betrachten wir den Graph Gu:
Gu=(Vu,Eu)Vu={1,2,3,4,5,6}Eu={{1,2},{1,3},{1,4},{2,6},{4,6},{3,6},{5,6},{3,4},{3,5}}
Biespiel Ungerichteter Graph mit obiger Knoten- und Kantenmenge
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gerichtete Graphen
Die Definition von gerichteten Graphen erfolgt analog zu den allgemeinen Graphen durch ein Zweitupel G = (V, E) mit
Allerdings ist jedes e ∊ E nun ein Tupel (a, b) mit a, b ∊ V. Diese Definition lässt Schleifen (a, a) zu.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gerichtete Graphen
Als Beispiel für diese Definition gerichteter Graphen betrachten wir den Graph Gg aus Abbildung 16–2:
Gg=(Vg,Eg)Vg={1,2,3,4,5,6}Eg={(1,2),(1,3),(3,1),(4,1),(3,4),(3,6),(5,3),(5,5),(6,5),(6,2),(6,4)}
Biespiel Gerichteter Graph mit obiger Knoten- und Kantenmenge
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gerichtete Graphen
Zustandsautomaten (z.B. Mikroprozessoren oder Kontrollpfade von Logiksystemen) bestehen aus einer endlichen Menge von Zuständen und Übergängen zwischen Zuständen.
add := expression + expression
, und expression
spaltet weiter auf (Baumstrukturen!!), z.B. expression := Number | Variable | expression
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gerichtete Graphen
function parse(text) { state = { instring : 0, incomment : 0, last : '', buffer : '' } while (next=nexttoken) { if (state.incomment) { if (next!=NL) continue; else state.incomment=0; } else if (state.instring==1) { if (next!='"') { state.buffer+=next; continue } } switch (next) { case '"': state.instring++; if (state.instring==2) { processString(state.buffer); state.instring=0 } break; case '/': if (state.last=='/') state.incomment++; break; } state.last=next }}
Der programmatische Ablauf eines endlichen Zustandsautomaten kann durch eine Zustandsübergangstabelle und als Graph repräsentiert (abstrahiert) werden. Hier sind die Zustände aber im Programmkode "verborgen"
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gewichtete Graphen
Gewichtete Graphen besitzen zusätzlich zu den bisherigen Graphenbestandteilen noch Kantengewichte. Kantengewichte sind den Kanten zugeordnete Gewichtswerte, etwa natürliche Zahlen oder int- oder real-Werte. Ein gewichteter Graph kann nun für natürliche Zahlen als Kantengewichte durch G = (V, E, γ) mit
γ:E→N
definiert werden.
Gewichtete Graphen werfen einige neue Fragestellungen auf, so etwa die Suche nach kürzesten Wegen, dem maximalem Fluss durch einen Graphen oder die Konstruktion minimaler aufspannender Bäume.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gewichtete Graphen
Beispiel eines gewichteten, gerichteten Graphen. Natürlich gibt es auch gewichtete, ungerichtete Graphen, etwa um Entfernungen in Verkehrsnetzen zu modellieren.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Gewichtete Graphen
Beispiel: Kommunikationsnetzwerk wie das Internet. Die Kanten werden mit Geschwindigkeits- und Durchsatzmetriken annotiert und ermöglichen die Fundung einer optimal schnellen Verbidnung.
Beispiel für ein Graph eines Rechnernetzwerkes mit unterschiedlichen Übertragungsgeschwindigkeiten (Bandbreite). Der Pfad A-B-D ist langsamer als der Pfad A-C-D, obwohl die gleiche Anzahl von Knoten entlang der Pfade liegen.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Eigenschaften von Graphen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Eine Datenstruktur für Graphen kann unterschiedlich aufgebaut werden. Die Realisierungen unterscheiden sich dabei im Platzbedarf gespeicherter Graphen sowie in der Komplexität der erwähnten Basisoperationen.
Eine sehr einfache (und historisch daher als erste verwendete) Speicherung von Graphen erfolgt als eine Liste von Zahlen, etwa in einem Array, einer sequenziellen Datei oder als verkettete Liste.
Diese Liste von Zahlen dient als Kodierung des Graphen, wobei die Knoten von 1 bis n = |V| durchnummeriert werden.
Die Realisierung durch Kantenlisten baut eine Zahlenfolge wie folgt auf (Kodierung!):
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Beispiel:
Gg=(Vg,Eg)Vg={1,2,3,4,5,6}Eg={(1,2),(1,3),(3,1),(4,1),(3,4),(3,6),(5,3),(5,5),(6,5),(6,2),(6,4)}
wird in Listen (Arrays) kodiert als:
Kantenliste :=[6, 11, 1, 2, 1, 3, 3, 1, 4, 1, 3, 4, 3, 6, 5, 3, 5, 5, 6, 5, 6, 2, 6, 4]Knotenliste :=[6, 11, 2, 2, 3, 0, 3, 1, 4, 6, 1, 1, 2, 3, 5, 3, 2, 4, 5]
Die Teilfolge 2, 2, 3 beginnend an der dritten Position in dieser Zahlenfolge bedeutet beispielsweise »Knoten 1 hat Ausgangsgrad 2 und herausgehende Kanten zu den Knoten 2 und 3«.
Man sieht bereits an diesem Beispiel, dass für Graphen mit vielen Kanten Knotenlisten weniger Speicherbedarf als Kantenlisten benötigen. Genauer benötigen Kantenlisten 2 + 2 · |E| Zahlen und Knotenlisten 2 + |V| + |E| Zahlen.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Insbesondere bei sehr vielen Kanten ist eine Speicherung der Verbindungen als n × n-Matrix sinnvoll. Der Wert n entspricht dabei der Knotenanzahl |V|. Eine derartige Matrix wird als Adjazenzmatrix bezeichnet.
Ein typisches Beispiel aus der Digitallogik und Rechnerarchitektur: Der Crossbar Switch!
Die Adjazenzmatrix ist ähnlich einer Zustandsübergangstabelle einer FSM. Sie kann für gerichtete Graphen direkt erstellt werden.
Die Idee der Adjazenzmatrix lässt sich direkt auf ungerichtete Graphen übertragen, wobei dann eigentlich nur die eine Hälfte der Matrix gespeichert werden muss, da sich die andere Hälfte durch Spiegelung ergibt.
Beim Vergleich des Speicherbedarfs muss man nun beachten, dass die Matrixelemente boolesche Werte sind, die im Gegensatz zu Zahlwerten nur ein Bit benötigen.
Es lassen sich zyklische wie azyklische Graphen darstellen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Die folgende Adjazenzmatrix stellt den gerichteten Graphen Gg und ungerichteten Gu dar:
GG=⎛⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜⎝011000000000100101100000001010010110⎞⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟⎠GU=⎛⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜ ⎜⎝011100100001100111101001001001011110⎞⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟ ⎟⎠
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Auch gewichtete Graphen können auf die gleiche Art mit Matrizen beschrieben (und progarmmiert) werden.
Grundkurs Informatik
Speicherung eines Graphen als Adjazenzmatrix A und Bewertungsmatrix B die die Gewichte vermerkt.
Für bewertete Graphen kann das Konzept beibehalten werden, wenn anstelle der Nullen und Einsen die Bewertung eingetragen wird. Man spricht dann auch von einer Bewertungsmatrix B.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Mit Matrizen können wir direkt rechnen:
Man kann nun fragen, wie man über direkte Verbindungen hinaus längere Wege zwischen zwei Knoten finden kann. Eine Methode ist die Bildung von Potenzen Am der Adjazenzmatrix. Die Komponenten der Matrix Am geben dann die Anzahl der Wege der Länge m vom i-ten zum k-ten Knoten an. Die Komponenten der Matrix A2 berechnet man nach der Regel „Zeile mal Spalte“ als Skalarprodukte der Zeilen- und Spaltenvektoren der Matrix A mit n × n Elementen:
(aik)2=n∑i=1aijajk
Die obige Formel liefert also die Anzahl der Wege der Länge 2 vom Knoten i zum Knoten k.
Beispiel: (a32)2=0, (a14)2=2 bedeutet es gibt also keinen Weg der Länge 2 vom dritten zum zweiten Knoten, also von C nach B, aber zweiWege der Länge 2 von A nach D, nämlich A → B → D und A → C → D. Man kann dies direkt am Skalarprodukt ablesen: es ergibt sich genau dann ein Beitrag, wenn die entsprechende Kante existiert. Die Zählung der Indizes beginnt dabei mit 1.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Will man wissen, ob unabhängig von der Länge des Weges überhaupt ein Weg von einem Knoten zu einem anderen existiert, so addiert man alle n Potenzen der Adjazenzmatrix und erhält die Erreichbarkeitsmatrix oder Wegematrix:
E=n∑i=1Ai
Die Einträge eik von E geben also an, auf wie vielen verschiedenen Wegen ein Knoten von einem anderen Knoten aus erreichbar ist, ohne dass dazwischen liegende Knoten mehrfach besucht werden.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Realisierung von Graphen
Grundkurs Informatik
Bestimmung der Erreichbarkeitsmatrix an einem Beispiel. Die Potenzen der Matrix A ergebn sich aus dem Matrixprodukt!
Enthält eine ganze Spalte der Erreichbarkeitsmatrix nur die Einträge 0, so kann dieser Knoten von keinem anderen Knoten aus erreicht werden. Sind alle Einträge einer Zeile 0, so kann von dem entsprechenden Knoten aus kein andere Knoten erreicht werden.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Kürzeste und längste Wege
Weiter mit den Adjazenzmatrizen ...
Berechnung der kürzesten und längsten Wege
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Kürzeste und längste Wege
Nummeriere die Knoten des Graphen von 1 bis n durch und trage die Längen der Wege von Knoten i zu Knoten j in die Erreichbarkeitsmatrix e(i,j) ein. Existiert kein solcher direkter Weg, trage ein Symol für „unendlich“ ein (Infinity).Wiederhole für k := 1 bis n Wiederhole für i := 1 bis n Wiederhole für j := 1 bis n Wenn e(i,k) + e(k,j) < e(i,j) dann Setze e(i,j) := e(i,k) + e(k,j) Ersetze die zu e(i,j) gehörende Knotenliste durch die Knotenliste, die durch Verbinden der zu e(i,k) und zu e(k,j) gehörenden Knotenlisten entsteht.ENDE
Floyd-Warshall-Algorithmus zum Auffinden kürzester Wege in einem Graphen
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Kürzeste und längste Wege
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Kürzeste und längste Wege
Das Problem des längsten Pfades ist NP-schwer oder NP-vollständig, abhängig von zusätzlichen Randbedingungen. Eine einfache Modifikation des Floyd-Warshall- oder Dijkstra-Algorithmus wird nicht funktionieren.
https://www.geeksforgeeks.org/find-longest-path-directed-acyclic-graph/
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Kürzeste und längste Wege
dass für jede gerichtete Kante (u,v) vom Knoten u zum Knoten v dann u in der Reihenfolge vor v steht.
Topologisches Sortieren = Scheduling Problem
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Graphen als dynamische Datenstrukturen
Die bisherigen Graphendarstellungen waren statische Realisierungen, da eigentlich keine dynamischen Erweiterungen im Sinne verketteter Listen vorgesehen waren (obwohl etwa Knotenlisten natürlich auch als verkettete Liste realisiert werden können).
Es gibt nun eine Reihe von Möglichkeiten, Graphen als dynamische Datenstrukturen zu realisieren.
Wir werden uns eine andere Realisierung anschauen, die auch als Adjazenzliste bezeichnet wird. Ein Graph wird dabei durch |V| +1 verkettete Listen realisiert. Die Basisstruktur bildet die Liste aller Knoten. Für jeden Knoten wird eine Liste der Nachfolger entlang gerichteter Kanten abgespeichert, so dass man für n = |V| und m = |E| insgesamt image Listenelemente erhält.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Graphen als dynamische Datenstrukturen
Graph als dynamische Datenstruktur
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Verkettete Speicherung eines Graphen
Eine sehr platzeffiziente Möglichkeit zum Speichern von Graphen ist der Forward Star. Dabei wird zunächst jedem der n Knoten ein Index zugewiesen.
Nun werden in einem als Knotenliste bezeichneten Array K Verweise auf Positionen in einem zweiten Array, die Nachfolgerliste N, eingetragen.
Die in der Knotenliste eingetragenen Verweise Ki geben die Position an, an der in der Nachfolgerliste die zugehörigen Nachfolger beginnen.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Verkettete Speicherung eines Graphen
Repräsentation eines Graphen als Forward Star
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Verkettete Speicherung eines Graphen
Der Graph wird direkt als verzeigerte Datenstruktur abgebildet. Jeder Knoten hat eine Nachfolgerliste. Algortihmen auf diese Datenstruktur anzuwenden ist wegen Zyklen gefährlich und aufwendig Zyklen zu erkennen.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Vergleich und Komplexität
Alle vorgestellten Realisierungsvarianten sind äquivalent; jede Darstellung kann also in jede andere ohne Informationsverlust transformiert werden. Im Wesentlichen erfordert dies das Auslesen der einen Darstellung und anschließend das Erzeugen der jeweils anderen Darstellung.
addp
Vergleich der Komplexität. Hierbei gilt n = |V| und m = |E|.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Vergleich und Komplexität
Die Komplexität für die Berechnung der Erreichbarkeitsmatrix eines Graphen mit n Knoten durch Summierung der ersten n Potenzen der Adjazenzmatrix ist von der Ordnung O(n4), also polynomial mit einem recht hohen Exponenten. Dies ergibt sich, da n − 1 Matrixmultiplikationen auszuführen sind, wobei die Komplexität der Multiplikation zweier n × n Matrizen von der Ordnung O(n3) ist.
Der Floyd-Warshall-Algorithmus hat die Komplexität O(n3), was sich aus den drei ineinander geschachtelten Schleigen mit n Durchläufen sofort ertgit.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Vergleich und Komplexität
Das Löschen eines Knotens löscht auch zugehörige Kanten, so dass hier der Aufwand in allen Varianten unvermutet hoch ist. Zu den einzelnen Varianten sind einige Bemerkungen angebracht:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Bei der Tiefensuche (Depth First Search) in einem Graphen besucht man von einem Startknoten k ausgehend dessen nächsten noch nicht besuchten Nachfolger, d.h. den als nächsten in der zu k gehörenden Nachfolgerliste befindlichen Knoten und setzt dort die Suche rekursiv fort. Gerät man dabei in eine Sackgasse, so muss der Weg bis zum ersten Knoten zurückverfolgt werden, von dem aus eine alternative Wahl möglich ist (Backtracking).
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Bei der Breitensuche (Breadth First Search) besucht man von einem Knoten ausgehend zuerst alle direkten Nachfolger, d. h. die in der zugehörigen Kantenliste enthaltenen Knoten, bevor deren noch nicht besuchte Nachfolger besucht werden. Auch bei der Breitensuche müssen Knoten als schon bearbeitet markiert werden können, wozu wie schon bei der Tiefensuche der Eintrag „Status“ verwendet wird. Anstelle eines Stapels wird bei der Breitensuche ein Puffer (Warteschlange, FIFO) für die temporäre Speicherung benötigt.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Problematisch bei der uniformen Kosten Suche ist, dass zur Bestimmung kürzester Wege der zu expandierende Knoten nur auf Basis der schon entstandenen Kosten ab dem Startknoten ausgewählt wird, in der Annahme, dass es besser ist zunächst die Wege mit aktuell geringen Kosten weiter zu betrachten.
Solche Wege können aber kurz sein und in die falsche Richtung gehen, d. h. weg vom Ziel.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Der A∗ -Algorithmus kombiniert die besten Aspekte zweier anderer Algorithmen:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
A∗ findet immer eine Lösung, sofern diese existiert. Das Verfahren ist optimal-effizient.
Es lässt sich zeigen, dass kein anderer Algorithmus existiert, der bei der Suche weniger Knoten expandiert, wenn die Bedingungen für die heuristische Funktion eingehalten werden.
Deswegen ist A∗ das Standardverfahren für alle Anwendungen, bei denen kürzeste Wege gesucht werden müssen, so z.B. bei der Routenplanung in Navigationsgeräten oder der Wegplanung in Computerspielen.
Die Zeitkomplexität von A∗ ist exponentiell in der Länge des kürzesten Pfads zum Ziel.
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
https://www.datacamp.com/tutorial/a-star-algorithm
Die Effizienz des A∗ -Algorithmus beruht auf seiner intelligenten Bewertung von Pfaden unter Verwendung von drei Schlüsselkomponenten: g(n), h(n) und f(n). Diese Komponenten arbeiten zusammen, um den Suchprozess auf die vielversprechendsten Pfade zu lenken.
A∗ Kostenfunktionen: Pfadkosten g, heuristische Funktion h
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
function A_Star(start, goal) { // Initialize open and closed lists openList = [start] // Nodes to be evaluated closedList = [] // Nodes already evaluated // Initialize node properties start.g = 0 // Cost from start to start is 0 start.h = heuristic(start, goal) // Estimate to goal start.f = start.g + start.h // Total estimated cost start.parent = null // For path reconstruction while openList is not empty: // Get node with lowest f value - implement using a priority queue // for faster retrieval of the best node current = node in openList with lowest f value // Check if we've reached the goal if current = goal: return reconstruct_path(current) // Move current node from open to closed list remove current from openList add current to closedList // Check all neighboring nodes for each neighbor of current: if neighbor in closedList: continue // Skip already evaluated nodes // Calculate tentative g score tentative_g = current.g + distance(current, neighbor) if neighbor not in openList: add neighbor to openList else if tentative_g >= neighbor.g: continue // This path is not better // This path is the best so far neighbor.parent = current neighbor.g = tentative_g neighbor.h = heuristic(neighbor, goal) neighbor.f = neighbor.g + neighbor.h return failure // No path exists}
A∗-Algorithmus
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Was ist wichtig?
Der Algorithmus beginnt mit der Erstellung von zwei wesentlichen Listen:
Jeder Knoten speichert vier kritische Informationen:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Der Kern von A∗ ist seine Hauptschleife, die fortgesetzt wird, bis entweder:
Während jeder Iteration wird der Algorithmus:
Für jeden Nachbarn der Algorithmus:
Stefan Bosse - Algorithmen und Datenstrukturen - Modul G Graphen und Graphenalgorithmen :: Durchsuchen von Graphen
Sobald das Ziel erreicht ist, arbeitet der Algorithmus rückwärts durch die übergeordneten Referenzen, um den optimalen Pfad vom Start zum Ziel zu konstruieren.
Diese systematische Vorgehensweise stellt sicher, dass A* immer den optimalen Weg findet, wenn: