{"id":16720,"date":"2020-11-25T09:00:16","date_gmt":"2020-11-25T08:00:16","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=16720"},"modified":"2025-06-12T09:17:58","modified_gmt":"2025-06-12T07:17:58","slug":"dijkstra-algorithmus-java","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/algorithmen\/dijkstra-algorithmus-java\/","title":{"rendered":"Dijkstra-Algorithmus (mit Java-Beispiel)"},"content":{"rendered":"\n<p>Wie findet ein Navigationssystem den k\u00fcrzesten Weg vom Start zum Ziel in m\u00f6glichst geringer Zeit? Dieser Frage (und \u00e4hnlichen) geht diese Artikelserie \u00fcber \"Shortest Path\"-Algorithmen nach. <\/p>\n\n\n\n<p>Dieser Teil behandelt den Dijkstra-Algorithmus (englisch: \"Dijkstra's algorithm\") \u2013 benannt nach dessen Erfinder, <a rel=\"noopener\" href=\"https:\/\/de.wikipedia.org\/wiki\/Edsger_W._Dijkstra\" target=\"_blank\">Edsger W. Dijkstra<\/a>. Dijkstras Algorithmus findet in einem Graphen zu einem gegebenen Startknoten die k\u00fcrzeste Entfernung zu allen anderen Punkten (oder zu einem vorgegebenen Endpunkt).<\/p>\n\n\n\n<p>Die Themen des Artikels im Einzelnen:<\/p>\n\n\n\n<ul id=\"block-c6904272-187c-4570-875a-1547e9b66439\" class=\"wp-block-list\">\n<li>Schritt-f\u00fcr-Schritt-Beispiel zur Erkl\u00e4rung der Funktionsweise des Algorithmus<\/li>\n\n\n\n<li>Quellcode des Dijkstra-Algorithmus (mit <code>PriorityQueue<\/code>)<\/li>\n\n\n\n<li>Bestimmung der Zeitkomplexit\u00e4t des Algorithmus<\/li>\n\n\n\n<li>Messung der Laufzeit \u2013 mit <code>PriorityQueue<\/code>, <code>TreeSet<\/code> und <code>FibonacciHeap<\/code><\/li>\n<\/ul>\n\n\n\n<p>Fangen wir an mit dem Beispiel!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstras-algorithmus-beispiel\">Dijkstras Algorithmus \u2013 Beispiel<\/h2>\n\n\n\n<p>Den Dijkstra-Algorithmus erkl\u00e4rt man am besten an einem Beispiel. Die folgende Grafik zeigt eine fiktive Stra\u00dfenkarte. Orte werden durch Kreise mit Buchstaben dargestellt; die Linien sind Stra\u00dfen und Wege, die diese Orte verbinden.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1174\" height=\"850\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x.png\" alt=\"Dijkstras Algorithmus: Stra\u00dfenkarte als Beispiel\" class=\"wp-image-17370\" style=\"width:587px;height:425px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x.png 1174w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-224x162.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-336x243.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-504x365.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-672x487.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-400x290.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-600x434.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-800x579.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map-2x-944x683.png 944w\" sizes=\"(max-width: 1174px) 100vw, 1174px\" \/><figcaption class=\"wp-element-caption\">Stra\u00dfenkarte<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die dicken Linien stellen eine Schnellstra\u00dfe dar; die etwas d\u00fcnneren Linien sind die Landstra\u00dfen, und die gestrichelten Linien sind schwer passierbare Feldwege.<\/p>\n\n\n\n<p>Die Stra\u00dfenkarte bilden wir nun auf einen Graphen ab. D\u00f6rfer werden dabei zu Knoten, Stra\u00dfen und Wege werden zu Kanten.<\/p>\n\n\n<div class=\"convertkit-form wp-block-convertkit-form\" style=\"\"><script async data-uid=\"5c918c0177\" src=\"https:\/\/happycoders.kit.com\/5c918c0177\/index.js\" data-jetpack-boost=\"ignore\" data-no-defer=\"1\" data-no-optimize=\"1\" nowprocket><\/script><\/div>\n\n\n\n<p>Die Gewichte der Kanten geben an, wie viele Minuten es dauert von einem Ort zum anderen zu kommen. Dabei spielt sowohl die L\u00e4nge als auch die Beschaffenheit der Wege eine Rolle, d. h. eine lange Hauptstra\u00dfe ist m\u00f6glicherweise schneller passierbar als ein deutlich k\u00fcrzerer Feldweg.<\/p>\n\n\n\n<p>Es ergibt sich folgender Graph:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1000\" height=\"728\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x.png\" alt=\"Dijkstras Algorithmus: Stra\u00dfenkarte als gewichteter Graph\" class=\"wp-image-17365\" style=\"width:500px;height:364px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x.png 1000w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-224x163.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-336x245.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-504x367.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-672x489.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-400x291.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-600x437.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-800x582.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_street_map_graph-2x-944x687.png 944w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><figcaption class=\"wp-element-caption\">Stra\u00dfenkarte als gewichteter Graph<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Aus dem Graph kann man nun z. B. ablesen, dass der Weg von D nach H auf der k\u00fcrzesten Strecke \u2013 also auf dem Feldweg \u00fcber Knoten F \u2013 11 Minuten dauert (gelb hinterlegte Strecke). \u00dcber die deutlich l\u00e4ngere Route \u00fcber die Land- und Schnellstra\u00dfen \u00fcber Knoten C und G (blaue Strecke) dauert es nur 9 Minuten:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1000\" height=\"778\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2.png\" alt=\"Dijkstras Algorithmus: schnellster Weg und k\u00fcrzester Weg\" class=\"wp-image-17363\" style=\"width:500px;height:389px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2.png 1000w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-224x174.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-336x261.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-504x392.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-672x523.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-400x311.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-600x467.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-800x622.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_shortest_path-2x-v2-944x734.png 944w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><figcaption class=\"wp-element-caption\">Stra\u00dfenkarte: schnellster Weg und k\u00fcrzester Weg<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Das menschliche Gehirn ist sehr gut darin, solche Muster zu erkennen. Einem Computer m\u00fcssen wir dies erst mit geeigneten Mitteln beibringen. Hier kommt der Dijkstra-Algorithmus ins Spiel.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"vorbereitung-tabelle-der-knoten\">Vorbereitung \u2013 Tabelle der Knoten<\/h3>\n\n\n\n<p>Zuerst m\u00fcssen wir einige Vorbereitungen treffen: Wir erstellen eine Tabelle der Knoten mit zwei zus\u00e4tzlichen Attributen: Vorg\u00e4nger-Knoten und Gesamtdistanz zum Startknoten. Die Vorg\u00e4nger-Knoten bleiben zun\u00e4chst leer; die Gesamtdistanz zum Startknoten wird im Startknoten selbst auf 0 gesetzt, in allen anderen Knoten auf \u221e (unendlich).<\/p>\n\n\n\n<p>Die Tabelle wird nach Gesamtdistanz zum Startknoten aufsteigend sortiert, d. h. der Startknoten selbst (Knoten D) steht ganz vorne in der Tabelle; die \u00fcbrigen Knoten sind unsortiert. Im Beispiel belassen wir sie in alphabetischer Reihenfolge:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Gesamtdistanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">D<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">0<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">A<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">B<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">C<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">E<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">F<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">G<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">H<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">I<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Im folgenden ist es wichtig die Begriffe <em>Distanz<\/em> und <em>Gesamtdistanz<\/em> zu unterscheiden:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Distanz<\/em> bezeichnet die Distanz von einem Knoten zu seinen Nachbarknoten; <\/li>\n\n\n\n<li><em>Gesamtdistanz<\/em> bezeichnet die Summe aller Teildistanzen vom Startknoten \u00fcber eventuelle Zwischenknoten zu einem bestimmten Knoten.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstras-algorithmus-schritt-fuer-schritt-abarbeitung-der-knoten\">Dijkstras Algorithmus Schritt f\u00fcr Schritt \u2013 Abarbeitung der Knoten<\/h3>\n\n\n\n<p>In den folgenden Darstellungen der Graphen werden Vorg\u00e4nger der Knoten und Gesamtdistanz mit angezeigt. Diese Daten sind in der Regel nicht im Graph selbst enthalten, sondern ausschlie\u00dflich in der oben beschriebenen Tabelle. Ich zeige sie hier mit an, um das Verst\u00e4ndnis zu erleichtern.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 1: Betrachten aller Nachbarn des Startpunkts<\/h4>\n\n\n\n<p>Nun entnehmen wir das erste Element \u2013 Knoten D \u2013 aus der Liste und betrachten dessen Nachbarn, also C, E und F.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"384\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-v2.png\" alt=\"Dijkstra-Algorithmus Schritt 2: Von D aus erreichbare Knoten\" class=\"wp-image-17359\" style=\"width:300px;height:192px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-v2.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-v2-224x143.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-v2-336x215.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-v2-504x323.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-v2-400x256.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Von D aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Da die Gesamtdistanz in all diesen Nachbarn noch <em>unendlich<\/em> ist (d. h. wir haben noch keinen Weg dorthin entdeckt), setzen wir die Gesamtdistanz der Nachbarn auf die Distanz von D zum jeweiligen Nachbarn und tragen jeweils D als Vorg\u00e4nger ein. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"384\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 2: Gesamtdistanz und Vorg\u00e4nger der Knoten C, E, F wurden aktualisiert\" class=\"wp-image-17384\" style=\"width:300px;height:192px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-after.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-after-224x143.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-after-336x215.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-after-504x323.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_2_node_d-2x-after-400x256.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger der Knoten C, E, F wurden aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die Liste sortieren wir wieder nach Gesamtdistanz (die ge\u00e4nderten Eintr\u00e4ge sind fett hervorgehoben):<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Gesamtdistanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>E<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>D<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>1<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>C<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>D<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>3<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>F<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>D<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>4<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">A<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">B<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">G<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">H<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">I<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Die Liste ist so zu lesen: Knoten E, C und F sind entdeckt und k\u00f6nnen \u00fcber D in 1, 3 bzw. 4 Minuten erreicht werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 2: Betrachten aller Nachbarn von Knoten E<\/h4>\n\n\n\n<p>Nun wiederholen wir, was wir eben f\u00fcr den Startknoten D getan haben, f\u00fcr den n\u00e4chsten Knoten der Liste, Knoten E. Wir entnehmen E und betrachten dessen Nachbarn A, B, D und F:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"768\" height=\"518\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x.png\" alt=\"Dijkstra-Algorithmus Schritt 3: Von E aus erreichbare Knoten\" class=\"wp-image-17355\" style=\"width:384px;height:259px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x.png 768w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-224x151.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-336x227.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-504x340.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-672x453.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-400x270.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-600x405.png 600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\">Von E aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>F\u00fcr Knoten A und B ist die Gesamtdistanz nach wie vor <em>unendlich<\/em>. Daher setzen wir deren Gesamtdistanz auf die Gesamtdistanz des aktuellen Knotens E (also 1) plus der Distanz von E zum jeweiligen Knoten:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten A<\/td><td>&nbsp;&nbsp;&nbsp;1 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu E)<\/span><br>+ 3 <span style=\"font-size:90%\">(Distanz E\u2013A)<\/span><br>= 4<\/td><\/tr><tr><td>Knoten B<\/td><td>&nbsp;&nbsp;&nbsp;1 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu E)<\/span><br>+ 5 <span style=\"font-size:90%\">(Distanz E\u2013B)<\/span><br>= 6<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Knoten D ist in der Tabelle nicht mehr enthalten. Das bedeutet, dass der k\u00fcrzeste Weg dorthin bereits entdeckt wurde (es ist der Startknoten). Wir brauchen den Knoten daher nicht weiter zu betrachten.<\/p>\n\n\n\n<p>Hier noch einmal der Graph mit aktualisierten Eintr\u00e4gen f\u00fcr A und B:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"768\" height=\"518\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 3: Gesamtdistanz und Vorg\u00e4nger der Knoten A, B wurden aktualisiert\" class=\"wp-image-17392\" style=\"width:384px;height:259px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after.png 768w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after-224x151.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after-336x227.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after-504x340.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after-672x453.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after-400x270.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_3_node_e-2x-after-600x405.png 600w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger der Knoten A, B wurden aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Zu Knoten F ist bereits eine Gesamtdistanz eingetragen (4 \u00fcber Knoten D). Um zu pr\u00fcfen, ob F \u00fcber den aktuellen Knoten E schneller erreicht werden kann, berechnen wir die Gesamtdistanz zu F \u00fcber E:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten F<\/td><td>&nbsp;&nbsp;&nbsp;1 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu E)<\/span><br>+ 6 <span style=\"font-size:90%\">(Distanz E\u2013F)<\/span><br>= 7<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Wir vergleichen diese Gesamtdistanz mit der f\u00fcr F eingetragenen Gesamtdistanz. Die neu berechnete Gesamtdistanz 7 ist gr\u00f6\u00dfer als die gespeicherte Gesamtdistanz 4. Der Weg \u00fcber E ist also l\u00e4nger als der zuvor entdeckte. Er interessiert uns damit nicht weiter, und wir lassen den Tabelleneintrag f\u00fcr F unver\u00e4ndert.<\/p>\n\n\n\n<p>Es ergibt sich folgender Zwischenstand in der Tabelle (die \u00c4nderungen sind fett hervorgehoben):<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Gesamtdistanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">C<\/td><td class=\"has-text-align-center\" data-align=\"center\">D<\/td><td class=\"has-text-align-center\" data-align=\"center\">3<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">F<\/td><td class=\"has-text-align-center\" data-align=\"center\">D<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>A<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>E<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>4<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>B<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>E<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>6<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">G<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">H<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">I<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Die neuen Eintr\u00e4ge sind so zu lesen: A und B wurden entdeckt; A ist \u00fcber Knoten E in insgesamt 4 Minuten erreichbar, B ist \u00fcber Knoten E in insgesamt 6 Minuten erreichbar.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 3: Betrachten aller Nachbarn von Knoten C<\/h4>\n\n\n\n<p>Wir wiederholen den Prozess f\u00fcr den n\u00e4chsten Knoten in der Liste: Knoten C. Wir entfernen ihn aus der Liste und betrachten dessen Nachbarn, A, D und G:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"738\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x.png\" alt=\"Dijkstra-Algorithmus Schritt 4: Von C aus erreichbare Knoten\" class=\"wp-image-17353\" style=\"width:300px;height:369px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-224x276.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-336x413.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-504x620.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-400x492.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Von C aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Knoten D wurde bereits aus der Liste entfernt und wird ignoriert.<\/p>\n\n\n\n<p>Wir berechnen die Gesamtdistanzen \u00fcber C zu A und G:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten A<\/td><td>&nbsp;&nbsp;&nbsp;3 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu C)<\/span><br>+ 2 <span style=\"font-size:90%\">(Distanz C\u2013A)<\/span><br>= 5<\/td><\/tr><tr><td>Knoten G<\/td><td>&nbsp;&nbsp;&nbsp;3 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu C)<\/span><br>+ 2 <span style=\"font-size:90%\">(Distanz C\u2013G)<\/span><br>= 5<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>F\u00fcr A ist bereits ein k\u00fcrzerer Weg \u00fcber E mit Gesamtdistanz 4 eingetragen. Wir ignorieren also den neu entdeckten Weg \u00fcber C zu A mit der gr\u00f6\u00dferen Gesamtdistanz 5 und lassen den Tabelleneintrag f\u00fcr A unver\u00e4ndert.<\/p>\n\n\n\n<p>Knoten G hat noch die Gesamtdistanz <em>unendlich<\/em>. Wir tragen daher f\u00fcr G Gesamtdistanz 5 via Vorg\u00e4nger C ein:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"738\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 4: Gesamtdistanz und Vorg\u00e4nger von Knoten G wurde aktualisiert\" class=\"wp-image-17394\" style=\"width:300px;height:369px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-after.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-after-224x276.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-after-336x413.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-after-504x620.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_4_node_c-2x-after-400x492.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger von Knoten G wurde aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>G hat nun eine k\u00fcrzere Gesamtdistanz als B und rutscht in der Tabelle eine Position nach oben:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Gesamtdistanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">F<\/td><td class=\"has-text-align-center\" data-align=\"center\">D<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">A<\/td><td class=\"has-text-align-center\" data-align=\"center\">E<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><span class=\"has-inline-color has-black-color\"><strong>G<\/strong><\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong><span class=\"has-inline-color has-black-color\">C<\/span><\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>5<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">B<\/td><td class=\"has-text-align-center\" data-align=\"center\">E<\/td><td class=\"has-text-align-center\" data-align=\"center\">6<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">H<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">I<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 4: Betrachten aller Nachbarn von Knoten F<\/h4>\n\n\n\n<p>Wir entfernen den n\u00e4chsten Knoten der Liste, F, und betrachten dessen Nachbarn D, E und H:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"570\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x.png\" alt=\"Dijkstra-Algorithmus Schritt 5: Von F aus erreichbare Knoten\" class=\"wp-image-17347\" style=\"width:300px;height:285px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-224x213.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-336x319.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-504x479.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-400x380.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Von F aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Zu Knoten D und E wurden die k\u00fcrzesten Wege bereits entdeckt; wir m\u00fcssen die Gesamtdistanz \u00fcber den aktuellen Knoten F also nur f\u00fcr H berechnen:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten H<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu F)<\/span><br>+&nbsp;&nbsp;&nbsp;7 <span style=\"font-size:90%\">(Distanz F\u2013H)<\/span><br>= 11<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Knoten H hat noch die Gesamtdistanz <em>unendlich<\/em>; wir tragen daher als Vorg\u00e4nger den aktuellen Knoten F und als Gesamtdistanz 11 ein:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"570\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 5: Gesamtdistanz und Vorg\u00e4nger von Knoten H wurde aktualisiert\" class=\"wp-image-17399\" style=\"width:300px;height:285px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-after.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-after-224x213.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-after-336x319.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-after-504x479.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_5_node_f-2x-after-400x380.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger von Knoten H wurde aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>H ist unser Zielknoten. Wir haben also einen Weg zum Ziel gefunden, mit der Gesamtdistanz 11. Wir wissen allerdings noch nicht, ob dies der k\u00fcrzeste Weg ist. Wir haben in der Tabelle noch drei weitere Knoten mit k\u00fcrzeren Gesamtdistanz als 11: A, G und B:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\">Gesamtd<strong>istanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">A<\/td><td class=\"has-text-align-center\" data-align=\"center\">E<\/td><td class=\"has-text-align-center\" data-align=\"center\">4<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><span class=\"has-inline-color has-black-color\">G<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\"><span class=\"has-inline-color has-black-color\">C<\/span><\/td><td class=\"has-text-align-center\" data-align=\"center\">5<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">B<\/td><td class=\"has-text-align-center\" data-align=\"center\">E<\/td><td class=\"has-text-align-center\" data-align=\"center\">6<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>H<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>F<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>11<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">I<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Eventuell gibt es ja von einem dieser Knoten noch einen kurzen Weg zum Ziel, \u00fcber den wir auf eine Gesamtdistanz von weniger als 11 kommen k\u00f6nnten.<\/p>\n\n\n\n<p>Wir m\u00fcssen daher den Prozess so lange weiterf\u00fchren, bis es in der Tabelle keine Eintr\u00e4ge vor dem Zielknoten H gibt.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 5: Betrachten aller Nachbarn von Knoten A<\/h4>\n\n\n\n<p>Wir entfernen Knoten A und betrachten dessen Nachbarn C und E:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"600\" height=\"432\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_6_node_a-2x-v3.png\" alt=\"Dijkstra-Algorithmus Schritt 6: Von A aus erreichbare Knoten\" class=\"wp-image-17345\" style=\"width:300px;height:216px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_6_node_a-2x-v3.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_6_node_a-2x-v3-224x161.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_6_node_a-2x-v3-336x242.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_6_node_a-2x-v3-504x363.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_6_node_a-2x-v3-400x288.png 400w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption class=\"wp-element-caption\">Von A aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Beide sind nicht mehr in der Tabelle enthalten, f\u00fcr beide wurden also bereits die k\u00fcrzesten Wege entdeckt \u2013 wir k\u00f6nnen sie somit ignorieren. \u00dcber Knoten A f\u00fchrt also kein Weg zum Ziel. Damit ist Schritt 6 beendet.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 6: Betrachten aller Nachbarn von Knoten G<\/h4>\n\n\n\n<p>Wir entnehmen Knoten G und betrachten dessen Nachbarn C und H:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"658\" height=\"522\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2.png\" alt=\"Dijkstra-Algorithmus Schritt 7: Von G aus erreichbare Knoten\" class=\"wp-image-17337\" style=\"width:329px;height:261px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2.png 658w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2-224x178.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2-336x267.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2-504x400.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2-400x317.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-v2-600x476.png 600w\" sizes=\"(max-width: 658px) 100vw, 658px\" \/><figcaption class=\"wp-element-caption\">Von G aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>C wurde bereits bearbeitet; es bleibt die Berechnung der Gesamtdistanz zu Knoten H \u00fcber G:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten H<\/td><td>&nbsp;&nbsp;&nbsp;5 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu G)<\/span><br>+ 4 <span style=\"font-size:90%\">(Distanz G\u2013H)<\/span><br>= 9<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Knoten H hat aktuell eine Gesamtdistanz von 11 \u00fcber Knoten F. In Schritt 5 hatten wir den entsprechenden Weg entdeckt. Mit einer Gesamtdistanz von 9 haben wir nun einen k\u00fcrzeren Weg gefunden! Wir ersetzen daher in H die 11 durch 9 und den bisherigen Vorg\u00e4nger F durch den aktuellen Knoten G:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"658\" height=\"522\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 7: Gesamtdistanz und Vorg\u00e4nger von Knoten H wurde aktualisiert\" class=\"wp-image-17404\" style=\"width:329px;height:261px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after.png 658w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after-224x178.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after-336x267.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after-504x400.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after-400x317.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_7_node_g-2x-after-600x476.png 600w\" sizes=\"(max-width: 658px) 100vw, 658px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger von Knoten H wurde aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die Tabelle sieht nun so aus:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\">Gesamtd<strong>istanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">B<\/td><td class=\"has-text-align-center\" data-align=\"center\">E<\/td><td class=\"has-text-align-center\" data-align=\"center\">6<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>H<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>G<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>9<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">I<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u2013<\/td><td class=\"has-text-align-center\" data-align=\"center\">\u221e<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u00dcber Knoten B k\u00f6nnten wir einen noch k\u00fcrzeren Weg zum Ziel finden, wir m\u00fcssen also zuletzt auch noch diesen betrachten.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Schritt 7: Betrachten aller Nachbarn von Knoten B<\/h4>\n\n\n\n<p>Wir entnehmen also Knoten B und schauen uns dessen Nachbarn E und I an:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"618\" height=\"722\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3.png\" alt=\"Dijkstra-Algorithmus Schritt 8: Von B aus erreichbare Knoten\" class=\"wp-image-17330\" style=\"width:309px;height:361px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3.png 618w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3-224x262.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3-336x393.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3-504x589.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3-400x467.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-v3-600x701.png 600w\" sizes=\"(max-width: 618px) 100vw, 618px\" \/><figcaption class=\"wp-element-caption\">Von B aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Zu E wurde der k\u00fcrzeste Weg bereits entdeckt; f\u00fcr I berechnen wir die Gesamtdistanz \u00fcber B:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten I<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu B)<\/span><br>+ 15 <span style=\"font-size:90%\">(Distanz B\u2013I)<\/span><br>= 21<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Wir tragen f\u00fcr Knoten I die berechnete Gesamtdistanz und den aktuellen Knoten als Vorg\u00e4nger ein:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"618\" height=\"722\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 8: Gesamtdistanz und Vorg\u00e4nger von Knoten I wurde aktualisiert\" class=\"wp-image-17408\" style=\"width:309px;height:361px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after.png 618w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after-224x262.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after-336x393.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after-504x589.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after-400x467.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_8_node_b-2x-after-600x701.png 600w\" sizes=\"(max-width: 618px) 100vw, 618px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger von Knoten I wurde aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>In der Tabelle bleibt I hinter H:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\">Gesamtd<strong>istanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">H<\/td><td class=\"has-text-align-center\" data-align=\"center\">G<\/td><td class=\"has-text-align-center\" data-align=\"center\">9<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>I<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>B<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>21<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">K\u00fcrzester Weg zum Ziel wurde gefunden <\/h4>\n\n\n\n<p>Der erste Eintrag der Liste ist nun unser Zielknoten H. Es sind keine unentdeckten Knoten mit k\u00fcrzerer Gesamtdistanz mehr vorhanden, von denen aus wir einen noch k\u00fcrzeren Weg finden k\u00f6nnten. <\/p>\n\n\n\n<p>Wir k\u00f6nnen aus der Tabelle ablesen: Der k\u00fcrzeste Weg zum Zielknoten H f\u00fchrt \u00fcber G und hat eine Gesamtdistanz von 9.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"backtrace-zur-bestimmung-des-vollstaendigen-weges\">Backtrace zur Bestimmung des vollst\u00e4ndigen Weges<\/h3>\n\n\n\n<p>Doch wie bestimmen wir den vollst\u00e4ndigen Weg vom Startknoten D zum Zielknoten H? Dazu m\u00fcssen wir uns Schritt f\u00fcr Schritt an den Vorg\u00e4ngern entlanghangeln.<\/p>\n\n\n\n<p>Diesen sogenannten \"Backtrace\" f\u00fchren wir anhand der in der Tabelle gespeicherten Vorg\u00e4ngerknoten durch. Der \u00dcbersicht halber stelle ich diese Daten hier noch einmal im Graphen dar: <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"656\" height=\"568\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x.png\" alt=\"Dijkstra-Algorithmus: Backtrace zur Bestimmung des vollst\u00e4ndigen Weges\" class=\"wp-image-17332\" style=\"width:328px;height:284px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x.png 656w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x-224x194.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x-336x291.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x-504x436.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x-400x346.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_backtrace-2x-600x520.png 600w\" sizes=\"(max-width: 656px) 100vw, 656px\" \/><figcaption class=\"wp-element-caption\">Backtrace zur Bestimmung des vollst\u00e4ndigen Weges<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Der Vorg\u00e4nger des Zielknotens H ist G; der Vorg\u00e4nger von G ist C; und der Vorg\u00e4nger von C ist der Startpunkt D. Der k\u00fcrzeste Weg lautet also: D\u2013C\u2013G\u2013H.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"kuerzeste-wege-zu-allen-knoten-finden\">K\u00fcrzeste Wege zu <em>allen<\/em> Knoten finden<\/h3>\n\n\n\n<p>Wenn wir den Algorithmus an dieser Stelle nicht abbrechen, sondern solange fortfahren, bis die Tabelle nur noch einen einzigen Eintrag enth\u00e4lt, haben wir die k\u00fcrzesten Wege zu <em>allen<\/em> Knoten gefunden! <\/p>\n\n\n\n<p>Im Beispiel m\u00fcssen wir dazu nur noch die Nachbarknoten von Knoten H betrachten \u2013 G und I:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"846\" height=\"190\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x.png\" alt=\"Dijkstra-Algorithmus Schritt 9: Von H aus erreichbare Knoten\" class=\"wp-image-17447\" style=\"width:423px;height:95px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x.png 846w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-224x50.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-336x75.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-504x113.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-672x151.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-400x90.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-600x135.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-800x180.png 800w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><figcaption class=\"wp-element-caption\">Von H aus erreichbare Knoten<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Knoten G wurde bereits abgearbeitet; wir berechnen die Gesamtdistanz zu I \u00fcber H:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-regular black-borders\"><table><tbody><tr><td>Knoten I<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;9 <span style=\"font-size:90%\">(k\u00fcrzeste Gesamtdistanz zu H)<\/span><br>+&nbsp;&nbsp;&nbsp;3 <span style=\"font-size:90%\">(Distanz H\u2013I)<\/span><br>= 12<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Der neu berechnete Weg zu I (12 via H) ist k\u00fcrzer als der bereits hinterlegte (21 via B). Wir ersetzen also Vorg\u00e4nger und Gesamtdistanz in Knoten I:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"846\" height=\"190\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after.png\" alt=\"Dijkstra-Algorithmus Schritt 9: Gesamtdistanz und Vorg\u00e4nger von Knoten I wurde aktualisiert\" class=\"wp-image-17452\" style=\"width:423px;height:95px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after.png 846w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-224x50.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-336x75.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-504x113.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-672x151.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-400x90.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-600x135.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_step_9_node_h-2x-after-800x180.png 800w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><figcaption class=\"wp-element-caption\">Gesamtdistanz und Vorg\u00e4nger von Knoten I wurde aktualisiert<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die Tabelle enth\u00e4lt nun nur noch Knoten I:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Knoten<\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Vorg\u00e4nger<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Distanz<\/strong><\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>I<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>B<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>12<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Wenn wir nun Knoten I entnehmen, ist die Tabelle leer, d. h. zu allen Nachbarknoten von I wurden bereits die k\u00fcrzesten Wege gefunden.<\/p>\n\n\n\n<p>Wir haben somit f\u00fcr <em>alle<\/em> Knoten des Graphes den k\u00fcrzesten Weg vom (oder zum) Startknoten D gefunden!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstras-kuerzester-pfad-algorithmus-informelle-beschreibung\">Dijkstras \"K\u00fcrzester Pfad\"-Algorithmus \u2013 Informelle Beschreibung<\/h2>\n\n\n\n<p>Vorbereitung:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Erstelle eine Tabelle aller Knoten mit Vorg\u00e4ngerknoten und Gesamtdistanz.<\/li>\n\n\n\n<li>Setze die Gesamtdistanz des Startknotens auf 0 und die aller anderer Knoten auf <em>unendlich<\/em>.<\/li>\n<\/ol>\n\n\n\n<p>Abarbeitung der Knoten:<\/p>\n\n\n\n<p>Solange die Tabelle nicht leer ist, entnehme das Element mit der kleinsten Gesamtdistanz und mache damit folgendes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ist das entnommene Element der Zielknoten? Wenn ja, ist die Abbruchbedingung erf\u00fcllt. Folge dann den Vorg\u00e4ngerknoten zur\u00fcck zum Startknoten, um den k\u00fcrzesten Weg zu bestimmen.<\/li>\n\n\n\n<li>Andersfalls betrachte alle Nachbarknoten des entnommenen Elements, die sich noch in der Tabelle befinden. F\u00fcr jeden Nachbarknoten:\n<ol class=\"wp-block-list\">\n<li>Berechne die Gesamtdistanz als Summe der Gesamtdistanz des entnommenen Knotens plus der Distanz zum betrachteten Nachbarknoten.<\/li>\n\n\n\n<li>Ist diese Gesamtdistanz k\u00fcrzer als die bisher gespeicherte, setze den Vorg\u00e4nger des Nachbarknotens auf den entnommenen Knoten und die Gesamtdistanz auf die neu berechnete.<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstras-algorithmus-java-quellcode-mit-priorityqueue\">Dijkstras Algorithmus \u2013 Java-Quellcode mit PriorityQueue<\/h2>\n\n\n\n<p>Wie implementiert man Dijkstras Algorithmus am besten in Java?<\/p>\n\n\n\n<p>Im folgenden stelle ich dir den Quellcode Schritt f\u00fcr Schritt vor. Den vollst\u00e4ndigen Code findest Du in meinem <a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/\" target=\"_blank\" rel=\"noopener\">GitHub-Repository<\/a>. Die einzelnen Klassen sind im folgenden ebenfalls verlinkt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"datenstruktur-fuer-den-graph-guava-valuegraph\">Datenstruktur f\u00fcr den Graph: Guava ValueGraph<\/h3>\n\n\n\n<p>Als allererstes ben\u00f6tigen wir eine Datenstruktur, die den Graph, also die Knoten und die sie verbindenden Kanten mit ihren Gewichten speichert.<\/p>\n\n\n\n<p>Hierf\u00fcr eignet sich beispielsweise der <a rel=\"noopener\" href=\"https:\/\/guava.dev\/releases\/30.0-jre\/api\/docs\/com\/google\/common\/graph\/ValueGraph.html\" target=\"_blank\">ValueGraph<\/a> der <em>Google Core Libraries for Java<\/em>. Die verschiedenen Typen von Graphen, die die Library bereitstellt, werden <a rel=\"noopener\" href=\"https:\/\/github.com\/google\/guava\/wiki\/GraphsExplained\" target=\"_blank\">hier<\/a> erl\u00e4utert.<\/p>\n\n\n\n<p>Einen <code>ValueGraph<\/code>, der dem Beispiel oben entspricht, k\u00f6nnen wir wie folgt erstellen (Klasse <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/TestWithSampleGraph.java\" target=\"_blank\">TestWithSampleGraph<\/a> im GitHub-Repository):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> ValueGraph&lt;String, Integer&gt; <span class=\"hljs-title\">createSampleGraph<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n   MutableValueGraph&lt;String, Integer&gt; graph = ValueGraphBuilder.undirected().build();\n   graph.putEdgeValue(<span class=\"hljs-string\">\"A\"<\/span>, <span class=\"hljs-string\">\"C\"<\/span>, <span class=\"hljs-number\">2<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"A\"<\/span>, <span class=\"hljs-string\">\"E\"<\/span>, <span class=\"hljs-number\">3<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"B\"<\/span>, <span class=\"hljs-string\">\"E\"<\/span>, <span class=\"hljs-number\">5<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"B\"<\/span>, <span class=\"hljs-string\">\"I\"<\/span>, <span class=\"hljs-number\">15<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"C\"<\/span>, <span class=\"hljs-string\">\"D\"<\/span>, <span class=\"hljs-number\">3<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"C\"<\/span>, <span class=\"hljs-string\">\"G\"<\/span>, <span class=\"hljs-number\">2<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"D\"<\/span>, <span class=\"hljs-string\">\"E\"<\/span>, <span class=\"hljs-number\">1<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"D\"<\/span>, <span class=\"hljs-string\">\"F\"<\/span>, <span class=\"hljs-number\">4<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"E\"<\/span>, <span class=\"hljs-string\">\"F\"<\/span>, <span class=\"hljs-number\">6<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"F\"<\/span>, <span class=\"hljs-string\">\"H\"<\/span>, <span class=\"hljs-number\">7<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"G\"<\/span>, <span class=\"hljs-string\">\"H\"<\/span>, <span class=\"hljs-number\">4<\/span>);\n   graph.putEdgeValue(<span class=\"hljs-string\">\"H\"<\/span>, <span class=\"hljs-string\">\"I\"<\/span>, <span class=\"hljs-number\">3<\/span>);\n   <span class=\"hljs-keyword\">return<\/span> graph;\n }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Typparameter des <code>ValueGraph<\/code> sind:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Typ der Knoten: in unserem Fall <code>String<\/code> f\u00fcr die Knotennamen \"A\" bis \"I\"<\/li>\n\n\n\n<li>Typ der Kantenwerte: in unserem Fall <code>Integer<\/code> f\u00fcr die Entfernungen zwischen den Knoten<\/li>\n<\/ol>\n\n\n\n<p>Da der Graph ungerichtet ist, spielt die Reihenfolge, in der die Knoten angegeben werden, keine Rolle.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"datenstruktur-knoten-gesamtdistanz-und-vorgaenger\">Datenstruktur: Knoten, Gesamtdistanz und Vorg\u00e4nger<\/h3>\n\n\n\n<p>Neben dem Graph ben\u00f6tigen wir eine Datenstruktur, die die Knoten und die zugeh\u00f6rige Gesamtdistanz vom Startpunkt sowie den Vorg\u00e4ngerknoten aufnimmt. Hierf\u00fcr erstellen wir den folgenden <code>NodeWrapper<\/code> (<a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/NodeWrapper.java\" target=\"_blank\" rel=\"noopener\">Klasse im GitHub-Repository<\/a>). Die Typvariable <code>N<\/code> ist dabei der Typ der Knoten \u2013 in unserem Beispiel wird das <code>String<\/code> sein f\u00fcr die Knotennamen.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">NodeWrapper<\/span>&lt;<span class=\"hljs-title\">N<\/span>&gt; <span class=\"hljs-keyword\">implements<\/span> <span class=\"hljs-title\">Comparable<\/span>&lt;<span class=\"hljs-title\">NodeWrapper<\/span>&lt;<span class=\"hljs-title\">N<\/span>&gt;&gt; <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> N node;\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> totalDistance;\n  <span class=\"hljs-keyword\">private<\/span> NodeWrapper&lt;N&gt; predecessor;\n\n  NodeWrapper(N node, <span class=\"hljs-keyword\">int<\/span> totalDistance, NodeWrapper&lt;N&gt; predecessor) {\n    <span class=\"hljs-keyword\">this<\/span>.node = node;\n    <span class=\"hljs-keyword\">this<\/span>.totalDistance = totalDistance;\n    <span class=\"hljs-keyword\">this<\/span>.predecessor = predecessor;\n  }\n\n  <span class=\"hljs-comment\">\/\/ getter for node<\/span>\n  <span class=\"hljs-comment\">\/\/ getters and setters for totalDistance and predecessor<\/span>\n\n  <span class=\"hljs-meta\">@Override<\/span>\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">compareTo<\/span><span class=\"hljs-params\">(NodeWrapper&lt;N&gt; o)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> Integer.compare(<span class=\"hljs-keyword\">this<\/span>.totalDistance, o.totalDistance);\n  }\n\n  <span class=\"hljs-comment\">\/\/ equals(), hashCode()<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der <code>NodeWrapper<\/code> implementiert das <a href=\"\/de\/java\/comparator-comparable-compareto\/#Das_Java_Comparable_Interface\">Comparable<\/a>-Interface: \u00fcber die <code>compareTo()<\/code>-Methode definieren wir die nat\u00fcrliche Ordnung derart, dass <code>NodeWrapper<\/code>-Objekte entsprechend der Gesamtentfernung aufsteigend sortiert werden.<\/p>\n\n\n\n<p>Der in den folgenden Abschnitten gezeigte Code bildet die <code>findShortestPath()<\/code>-Methode der Klasse <code>DijkstraWithPriorityQueue<\/code> (<a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/DijkstraWithPriorityQueue.java\" target=\"_blank\" rel=\"noopener\">Klasse in GitHub<\/a>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"datenstruktur-priorityqueue-als-tabelle\">Datenstruktur: PriorityQueue als Tabelle<\/h3>\n\n\n\n<p>Des Weiteren ben\u00f6tigen wir eine Datenstruktur f\u00fcr die Tabelle. <\/p>\n\n\n\n<p>Hierf\u00fcr wird h\u00e4ufig eine <a href=\"\/de\/algorithmen\/priorityqueue-java\/\">PriorityQueue<\/a> verwendet. Die <code>PriorityQueue<\/code> h\u00e4lt am Kopf immer das kleinste Element bereit, welches wir mit der <code>poll()<\/code>-Methode entnehmen k\u00f6nnen. Die nat\u00fcrliche Ordnung der <code>NodeWrapper<\/code>-Objekte wird sp\u00e4ter daf\u00fcr sorgen, dass <code>poll()<\/code> immer denjenigen <code>NodeWrapper<\/code> mit der geringsten Gesamtdistanz zur\u00fcckliefert.<\/p>\n\n\n\n<p>Tats\u00e4chlich ist die <code>PriorityQueue<\/code> <em>nicht<\/em> die optimale Datenstruktur. Ich werde sie dennoch vorerst einsetzen. Sp\u00e4ter im Abschnitt <a href=\"#Laufzeit_mit_PriorityQueue\">\"Laufzeit mit PriorityQueue\"<\/a> werde ich die Performance der Implementierung messen, dann erkl\u00e4ren, warum die <code>PriorityQueue<\/code> zu einer schlechten Performance f\u00fchrt \u2013 und schlie\u00dflich eine besser geeignete Datenstruktur mit einer um Gr\u00f6\u00dfenordnungen besseren Performance zeigen.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">PriorityQueue&lt;NodeWrapper&lt;N&gt;&gt; queue = <span class=\"hljs-keyword\">new<\/span> PriorityQueue&lt;&gt;();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"datenstruktur-lookup-map-fuer-nodewrapper\">Datenstruktur: Lookup Map f\u00fcr NodeWrapper<\/h3>\n\n\n\n<p>Wir ben\u00f6tigen au\u00dferdem eine Map, die uns f\u00fcr einen Knoten des Graphen den entsprechenden <code>NodeWrapper<\/code> liefert. Hierf\u00fcr eignet sich eine <code>HashMap<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Map&lt;N, NodeWrapper&lt;N&gt;&gt; nodeWrappers = <span class=\"hljs-keyword\">new<\/span> HashMap&lt;&gt;();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"datenstruktur-erledigte-knoten\">Datenstruktur: Erledigte Knoten<\/h3>\n\n\n\n<p>Wir m\u00fcssen im Verlauf des Algorithmus pr\u00fcfen k\u00f6nnen, ob wir einen Knoten bereits erledigt haben, d. h. den k\u00fcrzesten Weg dorthin gefunden haben. Daf\u00fcr eignet sich ein <code>HashSet<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Set&lt;N&gt; shortestPathFound = <span class=\"hljs-keyword\">new<\/span> HashSet&lt;&gt;();<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"vorbereitung-fuellen-der-tabelle\">Vorbereitung: F\u00fcllen der Tabelle<\/h3>\n\n\n\n<p>Kommen wir zum ersten Schritt des Algorithmus, dem F\u00fcllen der Tabelle.<\/p>\n\n\n\n<p>Hier optimieren wir direkt ein bisschen. Wir brauchen n\u00e4mlich gar nicht <em>alle<\/em> Knoten in die Tabelle zu schreiben \u2013 es reicht der Startknoten. Die weiteren Knoten schreiben wir erst dann in die Tabelle, wenn wir einen Weg dorthin finden. <\/p>\n\n\n\n<p>Dies hat zwei Vorteile:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Wir sparen uns Tabelleneintr\u00e4ge f\u00fcr Knoten, die vom Startpunkt entweder gar nicht erreichbar sind \u2013 oder nur \u00fcber solche Zwischenknoten, die vom Startpunkt weiter entfernt sind als das Ziel.<\/li>\n\n\n\n<li>Wenn wir im sp\u00e4teren Verlauf die Gesamtdistanz eines Knotens berechnen, wird dieser in der <code>PriorityQueue<\/code> <em>nicht<\/em> automatisch umsortiert. Stattdessen muss man den Knoten entfernen und wieder einf\u00fcgen. Da f\u00fcr alle entdeckten Knoten die Gesamtdistanz kleiner als <em>unendlich<\/em> sein wird, werden wir dementsprechend auch alle Knoten wieder aus der Queue entfernen und sie neu einf\u00fcgen m\u00fcssen. Auch dies k\u00f6nnen wir uns sparen, wenn wir die Knoten in der Vorbereitungsphase gar nicht erst einf\u00fcgen.<\/li>\n<\/ol>\n\n\n\n<p>Wir verpacken also zun\u00e4chst nur unseren Startknoten in ein <code>NodeWrapper<\/code>-Objekt (mit Gesamtdistanz 0 und ohne Vorg\u00e4nger) und f\u00fcgen dieses in die Lookup-Map und die Tabelle ein:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">NodeWrapper&lt;N&gt; sourceWrapper = <span class=\"hljs-keyword\">new<\/span> NodeWrapper&lt;&gt;(source, <span class=\"hljs-number\">0<\/span>, &lt;strong&gt;<span class=\"hljs-keyword\">null<\/span>&lt;\/strong&gt;);\nnodeWrappers.put(source, sourceWrapper);\nqueue.add(sourceWrapper);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"iteration-ueber-alle-knoten\">Iteration \u00fcber alle Knoten<\/h3>\n\n\n\n<p>Kommen wir zum Herzen des Algorithmus: der schrittweisen Abarbeitung der Tabelle (bzw. der Queue, die wir als Datenstruktur f\u00fcr die Tabelle gew\u00e4hlt haben):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">while<\/span> (!queue.isEmpty()) {\n  NodeWrapper&lt;N&gt; nodeWrapper = queue.poll();\n  N node = nodeWrapper.getNode();\n  shortestPathFound.add(node);\n\n  <span class=\"hljs-comment\">\/\/ Have we reached the target? --&gt; Build and return the path<\/span>\n  <span class=\"hljs-keyword\">if<\/span> (node.equals(target)) {\n    <span class=\"hljs-keyword\">return<\/span> buildPath(nodeWrapper);\n  }\n\n  <span class=\"hljs-comment\">\/\/ Iterate over all neighbors<\/span>\n  Set&lt;N&gt; neighbors = graph.adjacentNodes(node);\n  <span class=\"hljs-keyword\">for<\/span> (N neighbor : neighbors) {\n    <span class=\"hljs-comment\">\/\/ Ignore neighbor if shortest path already found<\/span>\n    <span class=\"hljs-keyword\">if<\/span> (shortestPathFound.contains(neighbor)) {\n      <span class=\"hljs-keyword\">continue<\/span>;\n    }\n\n    <span class=\"hljs-comment\">\/\/ Calculate total distance to neighbor via current node<\/span>\n    <span class=\"hljs-keyword\">int<\/span> distance =\n        graph.edgeValue(node, neighbor).orElseThrow(IllegalStateException::<span class=\"hljs-keyword\">new<\/span>);\n    <span class=\"hljs-keyword\">int<\/span> totalDistance = nodeWrapper.getTotalDistance() + distance;\n\n    <span class=\"hljs-comment\">\/\/ Neighbor not yet discovered?<\/span>\n    NodeWrapper&lt;N&gt; neighborWrapper = nodeWrappers.get(neighbor);\n    <span class=\"hljs-keyword\">if<\/span> (neighborWrapper == &lt;strong&gt;<span class=\"hljs-keyword\">null<\/span>&lt;\/strong&gt;) {\n      neighborWrapper = <span class=\"hljs-keyword\">new<\/span> NodeWrapper&lt;&gt;(neighbor, totalDistance, nodeWrapper);\n      nodeWrappers.put(neighbor, neighborWrapper);\n      queue.add(neighborWrapper);\n    }\n\n    <span class=\"hljs-comment\">\/\/ Neighbor discovered, but total distance via current node is shorter?<\/span>\n    <span class=\"hljs-comment\">\/\/ --&gt; Update total distance and predecessor<\/span>\n    <span class=\"hljs-keyword\">else<\/span> <span class=\"hljs-keyword\">if<\/span> (totalDistance &lt; neighborWrapper.getTotalDistance()) {\n      neighborWrapper.setTotalDistance(totalDistance);\n      neighborWrapper.setPredecessor(nodeWrapper);\n\n      <span class=\"hljs-comment\">\/\/ The position in the PriorityQueue won't change automatically;<\/span>\n      <span class=\"hljs-comment\">\/\/ we have to remove and reinsert the node<\/span>\n      queue.remove(neighborWrapper);\n      queue.add(neighborWrapper);\n    }\n  }\n}\n\n<span class=\"hljs-comment\">\/\/ All reachable nodes were visited but the target was not found<\/span>\n<span class=\"hljs-keyword\">return<\/span> &lt;strong&gt;<span class=\"hljs-keyword\">null<\/span>&lt;\/strong&gt;;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der Code sollte dank der Kommentare keiner weiteren Erkl\u00e4rung bed\u00fcrfen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"backtrace-bestimmung-des-weges-vom-start-zum-ziel\">Backtrace: Bestimmung des Weges vom Start zum Ziel<\/h3>\n\n\n\n<p>Wenn der aus der Queue entnommene Knoten der Zielknoten ist (Block <em>\"Have we reached the target?\"<\/em> in der <code>while<\/code>-Schleife oben), wird die Methode <code>buildPath()<\/code> aufgerufen. Diese folgt dem Pfad entlang der Vorg\u00e4nger r\u00fcckw\u00e4rts vom Ziel- zum Startknoten, schreibt dabei die Knoten in eine Liste und gibt diese in umgekehrter Reihenfolge zur\u00fcck:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> &lt;N&gt; <span class=\"hljs-function\">List&lt;N&gt; <span class=\"hljs-title\">buildPath<\/span><span class=\"hljs-params\">(NodeWrapper&lt;N&gt; nodeWrapper)<\/span> <\/span>{\n  List&lt;N&gt; path = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n  <span class=\"hljs-keyword\">while<\/span> (nodeWrapper != &lt;strong&gt;<span class=\"hljs-keyword\">null<\/span>&lt;\/strong&gt;) {\n    path.add(nodeWrapper.getNode());\n    nodeWrapper = nodeWrapper.getPredecessor();\n  }\n  Collections.reverse(path);\n  <span class=\"hljs-keyword\">return<\/span> path;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die vollst\u00e4ndige <code>findShortestPath()<\/code>-Methode findest Du in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/DijkstraWithPriorityQueue.java\" target=\"_blank\" rel=\"noopener\">DijkstraWithPriorityQueue im GitHub-Repository<\/a>. Aufrufen kannst Du die Methode dann beispielsweise so:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">ValueGraph&lt;String, Integer&gt; graph = createSampleGraph();\nList&lt;String&gt; shortestPath = DijsktraWithPriorityQueue.findShortestPath(graph, <span class=\"hljs-string\">\"D\"<\/span>, <span class=\"hljs-string\">\"H\"<\/span>);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>createSampleGraph()<\/code>-Methode hatte ich am Anfang dieses Kapitels gezeigt.<\/p>\n\n\n\n<p>Kommen wir als n\u00e4chstes zur Zeitkomplexit\u00e4t.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zeitkomplexitaet-von-dijkstras-algorithmus\">Zeitkomplexit\u00e4t von Dijkstras Algorithmus<\/h2>\n\n\n\n<p>Um die <a href=\"\/de\/algorithmen\/o-notation-zeitkomplexitaet\/\">Zeitkomplexit\u00e4t<\/a> des Algorithmus zu bestimmen, schauen wir uns den Code blockweise an. Im folgenden bezeichnen wir mit <em>m<\/em> die Anzahl der Kanten und mit <em>n<\/em> die Anzahl der Knoten.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Einf\u00fcgen des Startknotens in die Tabelle: <\/strong>Der Aufwand ist unabh\u00e4ngig von der Gr\u00f6\u00dfe des Graphen, also konstant: <em>O(1)<\/em>.<\/li>\n\n\n\n<li><strong>Entnehmen der Knoten aus der Tabelle:<\/strong> Jeder Knoten wird maximal einmal aus der Tabelle entnommen. Der Aufwand hierf\u00fcr h\u00e4ngt von der verwendeten Datenstruktur ab; wir bezeichnen ihn mit <em>T<sub>em<\/sub><\/em> (\"extract minimum\"). Der Aufwand f\u00fcr alle Knoten ist somit <em>O(n \u00b7 T<sub>em<\/sub>)<\/em>.<\/li>\n\n\n\n<li><strong>Pr\u00fcfen, ob der k\u00fcrzeste Pfad zu einem Knoten bereits gefunden wurde:<\/strong> Diese Pr\u00fcfung erfolgt f\u00fcr jeden Knoten und alle Kanten, die von diesen wegf\u00fchren. Da jede Kante an zwei Knoten anschlie\u00dft, geschieht dies also maximal zweimal pro Kante, also <em>2m<\/em> mal. Da wir f\u00fcr die Pr\u00fcfung ein Set verwenden, erfolgt dies mit konstantem Aufwand; f\u00fcr <em>2m<\/em> Knoten betr\u00e4gt der Gesamtaufwand damit <em>O(m)<\/em>.<\/li>\n\n\n\n<li><strong>Berechnung der Gesamtdistanz:<\/strong> Die Gesamtdistanz wird maximal einmal pro Kante berechnet, da wir maximal einmal pro Kante einen neuen Weg zu einem Knoten finden. Die Berechnung selbst erfolgt mit konstantem Aufwand, der Gesamtaufwand f\u00fcr diesen Schritt ist somit auch <em>O(m)<\/em>.<\/li>\n\n\n\n<li><strong>Zugriff auf NodeWrapper:<\/strong> Auch dies passiert mit konstantem Aufwand maximal einmal pro Kante; somit haben wir auch hier <em>O(m)<\/em>.<\/li>\n\n\n\n<li><strong>Einf\u00fcgen in die Tabelle:<\/strong> Jeder Knoten wird maximal einmal in die Queue eingetragen. Der Aufwand f\u00fcr das Eintragen h\u00e4ngt von der verwendeten Datenstruktur ab. Wir bezeichnen ihn mit <em>T<sub>i<\/sub><\/em> (\"insert\"). Der Gesamtaufwand f\u00fcr alle Knoten ist also <em>O(n \u00b7 T<sub>i<\/sub>)<\/em>.<\/li>\n\n\n\n<li><strong>Aktualisieren der Gesamtdistanz in der Tabelle:<\/strong> Dies geschieht f\u00fcr jede Kante maximal einmal; es gilt die gleiche Begr\u00fcndung wie bei der Berechnung der Gesamtdistanz. Wir haben dies im Quellcode durch Entfernen und Neueinf\u00fcgen gel\u00f6st. Es gibt allerdings auch Datenstrukturen, die das in einem Schritt optimiert ausf\u00fchren k\u00f6nnen. Wir bezeichnen daher den Aufwand hierf\u00fcr allgemein <em>T<sub>dk<\/sub><\/em> (\"decrease key\"). F\u00fcr <em>m<\/em> Kanten also <em>O(m \u00b7 T<sub>dk<\/sub>)<\/em>.<\/li>\n<\/ol>\n\n\n\n<p>F\u00fcgen wir alle Punkte zusammen, kommen wir auf:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(1) + O(n \u00b7 T<sub>em<\/sub>) + O(m) + O(m) + O(m) + O(n \u00b7 T<sub>i<\/sub>) + O(m \u00b7 T<sub>dk<\/sub>)<\/em><\/p>\n\n\n\n<p>Den konstantem Aufwand <em>O(1)<\/em> k\u00f6nnen wir vernachl\u00e4ssigen; ebenso wird <em>O(m)<\/em> gegen\u00fcber <em>O(m \u00b7 T<sub>dk<\/sub>)<\/em> vernachl\u00e4ssigbar. Der Term verk\u00fcrzt sich somit auf:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n \u00b7 (T<sub>em<\/sub>+T<sub>i<\/sub>) + m \u00b7 T<sub>dk<\/sub>)<\/em><\/p>\n\n\n\n<p>Wie die Werte f\u00fcr <em>T<sub>em<\/sub><\/em>, <em>T<sub>i<\/sub><\/em>, <em>T<sub>dk<\/sub><\/em> f\u00fcr die <code>PriorityQueue<\/code> und andere Datenstrukturen lauten \u2013 und was das f\u00fcr die Gesamtkomplexit\u00e4t bedeutet, erf\u00e4hrst du in den folgenden Abschnitten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstra-algorithmus-mit-priorityqueue\">Dijkstra-Algorithmus mit PriorityQueue<\/h3>\n\n\n\n<p>F\u00fcr die Java-<code>PriorityQueue<\/code> gelten folgende Werte, die man der <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/15\/docs\/api\/java.base\/java\/util\/PriorityQueue.html\" target=\"_blank\">Dokumentation der Klasse<\/a> entnehmen kann. (F\u00fcr ein leichteres Verst\u00e4ndnis gebe ich die <em>T<\/em>-Parameter hier mit voller Schreibweise an.)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kleinsten Eintrag entnehmen mit <code>poll()<\/code>: <em>T<sub>extractMinimum<\/sub> = O(log n)<\/em><\/li>\n\n\n\n<li>Wert einf\u00fcgen mit <code>offer()<\/code>: <em>T<sub>insert<\/sub> = O(log n)<\/em><\/li>\n\n\n\n<li>Gesamtdistanz verringen mit <code>remove()<\/code> und <code>offer()<\/code>: <em>T<sub>decreaseKey<\/sub> = O(n) + O(log n) = O(n)<\/em><\/li>\n<\/ul>\n\n\n\n<p>Setzen wir diese Werte in die Formel von oben ein \u2013 <em>T<sub>em<\/sub>+T<sub>i<\/sub> = log n + log n<\/em> k\u00f6nnen wir dabei zu einmal <em>log n<\/em> zusammenfassen \u2013 dann ergibt sich:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n \u00b7 <em>lo<em>g n<\/em><\/em><\/em><em> + m \u00b7 n)<\/em><\/p>\n\n\n\n<p>F\u00fcr den Sonderfall, dass die Anzahl der Kanten ein Vielfaches der Anzahl der Knoten ist \u2013 in Landau-Notation: <em>m \u2208 O(n)<\/em> \u2013 k\u00f6nnen <em>m<\/em> und <em>n<\/em> bei der Betrachtung der Zeitkomplexit\u00e4t gleichgesetzt werden. Dann vereinfacht sich die Formel zu <em>O(n \u00b7 log n + n\u00b2)<\/em>. Der quasilineare Anteil kann neben dem quadratischen vernachl\u00e4ssigt werden, und es bleibt:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n\u00b2)<\/em> \u2013 f\u00fcr <em>m \u2208 O(n)<\/em><\/p>\n\n\n\n<p>Genug der Theorie ... im n\u00e4chsten Abschnitt pr\u00fcfen wir unsere Annahme in der Praxis!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"laufzeit-mit-priorityqueue\">Laufzeit mit PriorityQueue<\/h3>\n\n\n\n<p>Um zu pr\u00fcfen, ob die theoretisch bestimmte Zeitkomplexit\u00e4t korrekt ist, habe ich das Programm <a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/TestDijkstraRuntime.java\" target=\"_blank\" rel=\"noopener\">TestDijkstraRuntime<\/a> geschrieben. Dieses erstellt zuf\u00e4llige Graphen verschiedener Gr\u00f6\u00dfen von 10.000 bis etwa 300.000 Knoten und sucht darin den k\u00fcrzesten Weg zwischen zwei zuf\u00e4llig ausgew\u00e4hlten Knoten.<\/p>\n\n\n\n<p>Die Graphen enthalten jeweils viermal so viele Kanten wie Knoten. Dies soll einer Stra\u00dfenkarte nahe kommen, auf der im Mittel grob gesch\u00e4tzt vier Stra\u00dfen von jeder Kreuzung wegf\u00fchren.<\/p>\n\n\n\n<p>Jeder Test wird 50 mal wiederholt; folgende Grafik zeigt den Median der gemessenen Zeiten im Verh\u00e4ltnis zur Graphengr\u00f6\u00dfe:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1476\" height=\"922\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2.png\" alt=\"Zeitkomplexit\u00e4t von Dijkstras Algorithmus mit PriorityQueue\" class=\"wp-image-17700\" style=\"width:738px;height:461px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2.png 1476w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-224x140.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-336x210.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-504x315.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-672x420.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-400x250.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-600x375.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-800x500.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-944x590.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_PriorityQueue-v2-1200x750.png 1200w\" sizes=\"(max-width: 1476px) 100vw, 1476px\" \/><figcaption class=\"wp-element-caption\">Zeitkomplexit\u00e4t von Dijkstras Algorithmus mit PriorityQueue<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Das vorhergesagte quadratische Wachstum ist gut zu erkennen \u2013 unsere Herleitung der Zeitkomplexit\u00e4t von <em>O(n\u00b2)<\/em> war also korrekt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstra-algorithmus-mit-treeset\">Dijkstra-Algorithmus mit TreeSet<\/h3>\n\n\n\n<p>Wir haben bei der Bestimmung der Zeitkomplexit\u00e4t erkannt, dass die <code>PriorityQueue.remove()<\/code>-Methode eine Zeitkomplexit\u00e4t von <em>O(n)<\/em> hat. Dies f\u00fchrt f\u00fcr den Gesamtalgorithmus zu quadratischem Aufwand.<\/p>\n\n\n\n<p>Eine besser geeignete Datenstruktur ist das <code>TreeSet<\/code>. Dieses bietet uns mit der <code>pollFirst()<\/code>-Methode ebenfalls eine M\u00f6glichkeit das kleinste Element zu entnehmen. F\u00fcr das <code>TreeSet<\/code> gelten laut <a rel=\"noopener\" href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/15\/docs\/api\/java.base\/java\/util\/TreeSet.html\" target=\"_blank\">Dokumentation<\/a> folgende Laufzeiten:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kleinsten Eintrag entnehmen mit <code>pollFirst()<\/code>: <em>T<sub>extractMinimum<\/sub> = O(log n)<\/em><\/li>\n\n\n\n<li>Wert einf\u00fcgen mit <code>add()<\/code>: <em>T<sub>insert<\/sub> = O(log n)<\/em><\/li>\n\n\n\n<li>Gesamtdistanz verringen mit <code>remove()<\/code> und <code>add()<\/code>: <em>T<sub>decreaseKey<\/sub> = O(log n) + O(log n) = O(log n)<\/em><\/li>\n<\/ul>\n\n\n\n<p>Setzen wir diese Werte in die allgemeine Formel <em>O(n \u00b7 (T<sub>em<\/sub>+T<sub>i<\/sub>) + m \u00b7 T<sub>dk<\/sub>)<\/em> ein, erhalten wir:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n \u00b7 log n + m \u00b7 log n)<\/em><\/p>\n\n\n\n<p>Betrachten wir wieder den Sonderfall, dass die Anzahl der Kanten ein Vielfaches der Anzahl der Knoten ist, <em>m<\/em> und <em>n<\/em> also gleichgesetzt werden k\u00f6nnen, kommen wir auf:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n \u00b7 log n)<\/em> \u2013 f\u00fcr <em>m \u2208 O(n)<\/em><\/p>\n\n\n\n<p>Bevor wir dies in der Praxis \u00fcberpr\u00fcfen, zun\u00e4chst noch ein paar Anmerkungen zum <code>TreeSet<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Nachteil des TreeSet<\/h4>\n\n\n\n<p>Das <code>TreeSet<\/code> ist beim Hinzuf\u00fcgen und Entnehmen von Elementen etwas langsamer als die <code>PriorityQueue<\/code>, da es intern eine <code>TreeMap<\/code> verwendet. Diese wiederum arbeitet mit einem <a href=\"\/de\/algorithmen\/rot-schwarz-baum-java\/\">Rot-Schwarz-Baum<\/a>, welcher mit Knotenobjekten und Referenzen arbeitet, w\u00e4hrend der in der <code>PriorityQueue<\/code> verwendete <a href=\"\/de\/algorithmen\/heapsort\/#Was_ist_ein_Heap\">Heap<\/a> auf ein Array gemappt ist.<\/p>\n\n\n\n<p>Bei ausreichend gro\u00dfen Graphen f\u00e4llt dies jedoch nicht mehr ins Gewicht, wie wir in den folgenden Messungen sehen werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">TreeSet verletzt die Interface-Definition!<\/h4>\n\n\n\n<p>Eine Sache m\u00fcssen wir beim Einsatz des <code>TreeSet<\/code>s beachten: Es verletzt die Schnittstellendefinition der <code>remove()<\/code>-Methode sowohl des <code>Collection<\/code>- als auch des <code>Set<\/code>-Interfaces!<\/p>\n\n\n\n<p>Und zwar pr\u00fcft das <code>TreeSet<\/code> auf Gleichheit zweier Objekte nicht \u2013 wie in Java sonst \u00fcblich und wie in der Interface-Methode spezifiziert \u2013 mittels der <code>equals()<\/code>-Methode, sondern \u00fcber <code>Comparable.compareTo()<\/code> \u2013 bzw. <code>Comparator.compare()<\/code> bei Verwendung eines Comparators. Zwei Objekte werden als gleich angesehen, wenn <code>compareTo()<\/code> bzw. <code>compare()<\/code> 0 zur\u00fcckliefert.<\/p>\n\n\n\n<p>Dies ist beim L\u00f6schen von Elementen in zweierlei Hinsicht relevant: <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Wenn es mehrere Knoten mit derselben Gesamtdistanz gibt, k\u00f6nnte beim Versuch solch einen Knoten zu entfernen \"versehentlich\" ein anderer Knoten mit gleicher Gesamtdistanz entfernt werden.<\/li>\n\n\n\n<li>Wichtig ist au\u00dferdem, dass wir den Knoten entfernen, <em>bevor<\/em> wir dessen Gesamtdistanz \u00e4ndern. Ansonsten wird die <code>remove()<\/code>-Methode ihn nicht mehr finden.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Implementierung: NodeWrapperForTreeSet<\/h4>\n\n\n\n<p>Deshalb m\u00fcssen wir f\u00fcr die Verwendung eines <code>TreeSet<\/code>s die <code>compareTo()<\/code>-Methode dahingehend erweitern, dass sie bei gleicher Gesamtdistanz auch noch den Knoten vergleicht. <\/p>\n\n\n\n<p>Da dazu auch die Knoten (und damit der Typparameter <code>N<\/code>) das Interface <code>Comparable<\/code> implementieren m\u00fcssen, legen wir eine neue Klasse <code>NodeWrapperForTreeSet<\/code> an (<a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/NodeWrapperForTreeSet.java\" target=\"_blank\" rel=\"noopener\">Klasse im GitHub-Repository<\/a>):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">NodeWrapperForTreeSet<\/span>&lt;<span class=\"hljs-title\">N<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Comparable<\/span>&lt;<span class=\"hljs-title\">N<\/span>&gt;&gt;\n    <span class=\"hljs-keyword\">implements<\/span> <span class=\"hljs-title\">Comparable<\/span>&lt;<span class=\"hljs-title\">NodeWrapperForTreeSet<\/span>&lt;<span class=\"hljs-title\">N<\/span>&gt;&gt; <\/span>{\n  <span class=\"hljs-comment\">\/\/ fields, constructors, getters, setters<\/span>\n\n  <span class=\"hljs-meta\">@Override<\/span>\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">compareTo<\/span><span class=\"hljs-params\">(NodeWrapperForTreeSet&lt;N&gt; o)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> compare = Integer.compare(<span class=\"hljs-keyword\">this<\/span>.totalDistance, o.totalDistance);\n    <span class=\"hljs-keyword\">if<\/span> (compare == <span class=\"hljs-number\">0<\/span>) {\n      compare = node.compareTo(o.node);\n    }\n    <span class=\"hljs-keyword\">return<\/span> compare;\n  }\n\n  <span class=\"hljs-comment\">\/\/ equals(), hashCode()<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Des weiteren m\u00fcssen wir sicherstellen, dass wir als Knotentyp nur solche Klassen verwenden, bei denen <code>compareTo()<\/code> genau dann 0 liefert, wenn auch <code>equals()<\/code> die Objekte als gleich wertet. In unseren Beispielen verwenden wir <code>String<\/code>, was diese Forderung erf\u00fcllt.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Vollst\u00e4ndiger Code in GitHub<\/h4>\n\n\n\n<p>Den Algorithmus mit <code>TreeSet<\/code> findest du in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/DijkstraWithTreeSet.java\" target=\"_blank\" rel=\"noopener\">DijkstraWithTreeSet im GitHub-Repository<\/a>. Dieser unterscheidet sich in nur wenigen Punkten von <code>DijkstraWithPriorityQueue<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Der Knotentyp <code>N<\/code> erweitert <code>Comparable&lt;N&gt;<\/code>.<\/li>\n\n\n\n<li>Statt der <code>PriorityQueue<\/code> wird ein <code>TreeSet<\/code> erstellt.<\/li>\n\n\n\n<li>Das erste Element wird mit <code>pollFirst()<\/code> entnommen anstatt mit <code>poll()<\/code>.<\/li>\n\n\n\n<li>Statt <code>NodeWrapper<\/code> wird <code>NodeWrapperForTreeSet<\/code> verwendet.<\/li>\n<\/ul>\n\n\n\n<p>Sollten wir nicht Code-Duplikation vermeiden und die gemeinsame Funktionalit\u00e4t in einer einzigen Klasse unterbringen? Ja, wenn beide Varianten in der Praxis eingesetzt werden sollen. Hier sollen aber lediglich beide Ans\u00e4tze verglichen werden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"laufzeit-mit-treeset\">Laufzeit mit TreeSet<\/h3>\n\n\n\n<p>Um die Laufzeit zu messen, brauchen wir nur in <a href=\"https:\/\/github.com\/SvenWoltmann\/pathfinding\/blob\/main\/src\/main\/java\/eu\/happycoders\/pathfinding\/dijkstra\/TestDijkstraRuntime.java#L71\" target=\"_blank\" rel=\"noopener\">TestDijkstraRuntime<\/a> in Zeile 71 die Klasse <code>DijkstraWithPriorityQueue<\/code> durch <code>DijkstraWithTreeSet<\/code> zu ersetzen.<\/p>\n\n\n\n<p>Der folgende Graph zeigt das Testergebnis im Vergleich zur vorherigen Implementierung:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1476\" height=\"922\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2.png\" alt=\"Zeitkomplexit\u00e4t von Dijkstras Algorithmus mit TreeSet im Vergleich zur PriorityQueue\" class=\"wp-image-17699\" style=\"width:738px;height:461px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2.png 1476w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-224x140.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-336x210.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-504x315.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-672x420.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-400x250.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-600x375.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-800x500.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-944x590.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_TreeSet-v2-1200x750.png 1200w\" sizes=\"(max-width: 1476px) 100vw, 1476px\" \/><figcaption class=\"wp-element-caption\">Zeitkomplexit\u00e4t von Dijkstras Algorithmus mit TreeSet<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Das erwartete quasilineare Wachstum ist gut zu erkennen, die Zeitkomplexit\u00e4t ist wie vorhergesagt <em>O(n \u00b7 log n)<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"dijkstra-algorithmus-mit-fibonacci-heap\">Dijkstra-Algorithmus mit Fibonacci-Heap<\/h3>\n\n\n\n<p>Eine noch besser geeignete, im JDK allerdings nicht verf\u00fcgbare Datenstruktur ist der <a href=\"https:\/\/de.wikipedia.org\/wiki\/Fibonacci-Heap\" target=\"_blank\" rel=\"noreferrer noopener\">Fibonacci-Heap<\/a>. Dessen Operationen weisen folgenden Laufzeiten auf:<\/p>\n\n\n\n<ul id=\"block-8d734928-cfe2-4147-9b20-a6a62a006bae\" class=\"wp-block-list\">\n<li>Kleinsten Eintrag entnehmen: <em>T<sub>extractMinimum<\/sub> = O(log n)<\/em><\/li>\n\n\n\n<li>Wert einf\u00fcgen: <em>T<sub>insert<\/sub> = O(1)<\/em><\/li>\n\n\n\n<li>Gesamtdistanz verringen: <em>T<sub>decreaseKey<\/sub> = O(1)<\/em><\/li>\n<\/ul>\n\n\n\n<p>In die allgemeine Formel <em>O(n \u00b7 (T<sub>em<\/sub>+T<sub>i<\/sub>) + m \u00b7 T<sub>dk<\/sub>)<\/em> eingesetzt, ergibt das:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n \u00b7 log n + m)<\/em><\/p>\n\n\n\n<p>F\u00fcr den Spezialfall, dass die Anzahl der Kanten ein Vielfaches der Anzahl der Knoten ist, kommen wir wie beim <code>TreeSet<\/code> auf quasilinearen Aufwand:<\/p>\n\n\n\n<p class=\"has-text-align-center\"><em>O(n \u00b7 log n<\/em>)&nbsp;\u2013 f\u00fcr&nbsp;<em>m \u2208 O(n)<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"laufzeit-mit-fibonacci-heap\">Laufzeit mit Fibonacci-Heap<\/h3>\n\n\n\n<p>Mangels passender Datenstruktur im JDK, habe ich die <a rel=\"noopener\" href=\"https:\/\/keithschwarz.com\/interesting\/code\/?dir=fibonacci-heap\" target=\"_blank\">Fibonacci-Heap-Impementierung von Keith Schwarz<\/a> verwendet. Da ich den Code nicht einfach kopieren wollte, habe ich den entsprechenden Test nicht in mein GitHub-Repository hochgeladen. Das Ergebnis siehst du hier im Vergleich zu den zwei vorherigen Tests:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1476\" height=\"922\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap.png\" alt=\"Zeitkomplexit\u00e4t von Dijkstras Algorithmus mit Fibonacci-Heap im Vergleich mit TreeSet und PriorityQueue\" class=\"wp-image-17698\" style=\"width:738px;height:461px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap.png 1476w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-224x140.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-336x210.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-504x315.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-672x420.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-400x250.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-600x375.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-800x500.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-944x590.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstras_algorithm_time_complexity_FibonacciHeap-1200x750.png 1200w\" sizes=\"(max-width: 1476px) 100vw, 1476px\" \/><figcaption class=\"wp-element-caption\">Zeitkomplexit\u00e4t von Dijkstras Algorithmus mit Fibonacci-Heap<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Dijkstras Algorithmus ist mit Fibonacci-Heap also noch einmal einen Tick schneller als mit dem <code>TreeSet<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zeitkomplexitaet-zusammenfassung\">Zeitkomplexit\u00e4t \u2013 Zusammenfassung<\/h3>\n\n\n\n<p>In der folgenden Tabelle findest du eine \u00dcbersicht der Zeitkomplexit\u00e4t von Dijkstras Algorithmus in Abh\u00e4ngigkeit der verwendeten Datenstruktur. Dijkstra selbst hatte den Algorithmus \u00fcbrigens mit einem Array implementiert, dieses habe ich der Vollst\u00e4ndigkeithalber ebenfalls mit aufgef\u00fchrt:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><thead><tr><th>Datenstruktur<\/th><th class=\"has-text-align-center\" data-align=\"center\">T<sub>em<\/sub><\/th><th class=\"has-text-align-center\" data-align=\"center\">T<sub>i<\/sub><\/th><th class=\"has-text-align-center\" data-align=\"center\">T<sub>dk<\/sub><\/th><th class=\"has-text-align-center\" data-align=\"center\">Zeitkomplexit\u00e4t<br>allgemein<\/th><th class=\"has-text-align-center\" data-align=\"center\">Zeitkomplexit\u00e4t<br>f\u00fcr <em>m \u2208 O(n)<\/em><\/th><\/tr><\/thead><tbody><tr><td>Array<\/td><td class=\"has-text-align-center\" data-align=\"center\"><em><span class=\"has-inline-color has-vivid-red-color\">O(n)<\/span><\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em><span class=\"has-inline-color has-vivid-green-cyan-color\">O(1)<\/span><\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em><span class=\"has-inline-color has-vivid-green-cyan-color\">O(1)<\/span><\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n\u00b2 + m)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n\u00b2)<\/em><\/td><\/tr><tr><td>PriorityQueue<\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em><span class=\"has-inline-color has-vivid-red-color\">O(n)<\/span><\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n \u00b7 <em>log n<\/em> + m \u00b7 n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n\u00b2)<\/em><\/td><\/tr><tr><td>TreeSet<\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n \u00b7 log n + m \u00b7 log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n \u00b7 log n)<\/em><\/td><\/tr><tr><td>FibonacciHeap<\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(log n)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em><span class=\"has-inline-color has-vivid-green-cyan-color\">O(1)<\/span><\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em><span class=\"has-inline-color has-vivid-green-cyan-color\">O(1)<\/span><\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n \u00b7 log n + m)<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\"><em>O(n \u00b7 log n)<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zusammenfassung-und-ausblick\">Zusammenfassung und Ausblick<\/h2>\n\n\n\n<p>Dieser Artikel hat an einem Beispiel, mit einer informellen Beschreibung und mit Java-Quellcode gezeigt, wie Dijkstras Algorithmus funktionert.<\/p>\n\n\n\n<p>F\u00fcr die Zeitkomplexit\u00e4t wurde zun\u00e4chst eine allgemeine Landau-Notation hergeleitet, und diese wurde f\u00fcr die Datenstrukturen <code>PriorityQueue<\/code>, <code>TreeSet<\/code> und <code>FibonacciHeap<\/code> konkretisiert.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Nachteil des Dijkstra-Algorithmus<\/h4>\n\n\n\n<p>Der Algorithmus hat allerdings ein Manko: Er folgt den Kanten in <em>alle<\/em> Richtungen, unabh\u00e4ngig davon, in welcher Richtung der Zielknoten liegt. Das Beispiel in diesem Artikel war recht klein, so dass dies nicht aufgefallen ist. <\/p>\n\n\n\n<p>Schau dir einmal folgende Stra\u00dfenkarte an:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" width=\"962\" height=\"304\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5.png\" alt=\"F\u00fcr Dijkstras Algorithmus ungeeigneter Graph\" class=\"wp-image-17588\" style=\"width:481px;height:152px\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5.png 962w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-224x71.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-336x106.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-504x159.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-672x212.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-400x126.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-600x190.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-800x253.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra_algorithm_downside-v5-944x298.png 944w\" sizes=\"(max-width: 962px) 100vw, 962px\" \/><figcaption class=\"wp-element-caption\">F\u00fcr Dijkstras Algorithmus ungeeigneter Graph<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Die Strecken von A nach D und von D nach H sind Schnellstra\u00dfen; von D nach E f\u00fchrt ein schwer passierbarer Feldweg. Wenn wir jetzt von D nach E kommen wollen, sehen wir sofort, dass wir keine andere Wahl haben als diesen Feldweg zu nehmen.<\/p>\n\n\n\n<p>Doch was macht der Dijkstra-Algorithmus?<\/p>\n\n\n\n<p>Da dieser sich ausschlie\u00dflich an Kantenl\u00e4ngen orientiert, pr\u00fcft er die Knoten C und F (Gesamtdistanz 2), B und G (Gesamtdistanz 4) und A und H (Gesamtdistanz 6), bevor er sicher ist, keinen k\u00fcrzeren Weg zu H zu finden als den direkten Weg mit der L\u00e4nge 5.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Vorschau: A*-Suchalgorithmus<\/h4>\n\n\n\n<p>Es gibt eine Weiterentwicklung des Dijkstra-Algorithmus, die mit Hilfe einer Heuristik das Pr\u00fcfen von Pfaden in die falsche Richtung vorzeitig beendet und trotzdem deterministisch den k\u00fcrzesten Weg findet: der <a href=\"\/de\/algorithmen\/a-stern-algorithmus-java\/\">A*-Algorithmus<\/a> (ausgesprochen \"A Stern\" oder englisch \"A Star\"). Diesen stelle ich im n\u00e4chsten Teil der Artikelserie vor.<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>M\u00f6chtest du auf dem Laufenden bleiben und informiert werden, wenn neue Artikel auf HappyCoders.eu ver\u00f6ffentlicht werden? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Wie funktioniert Dijkstras Algorithmus? Wie implementiert man den Dijkstra-Algorithmus in Java? Wie bestimmt man die Zeitkomplexit\u00e4t?<\/p>\n","protected":false},"author":1,"featured_media":43213,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"","_seopress_titles_desc":"Wie funktioniert Dijkstras Algorithmus? Wie implementiert man den Dijkstra-Algorithmus in Java? Wie bestimmt man die Zeitkomplexit\u00e4t?","_seopress_robots_index":"","_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":34555,"_post_count":0,"footnotes":""},"categories":[127],"tags":[137],"class_list":["post-16720","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algorithmen","tag-algorithmen-pathfinding"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/11\/dijkstra-algorithm-feature-image.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":2,"uagb_excerpt":"Wie funktioniert Dijkstras Algorithmus? Wie implementiert man den Dijkstra-Algorithmus in Java? Wie bestimmt man die Zeitkomplexit\u00e4t?","public_identification_id":"794d957451444c0e938a1a18fafe74a2","private_identification_id":"3df9defc4dfa4305aa4306c4b3ff798f","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/16720","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=16720"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/16720\/revisions"}],"predecessor-version":[{"id":52497,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/16720\/revisions\/52497"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/43213"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=16720"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=16720"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=16720"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}