1 Algorithmen und Datenstrukturen Wintersemester 2016/17 19. Vorlesung Kürzeste Wege & Dijkstras Algorithmus Prof. Dr. Alexander Wolff Lehrstuhl für Informatik I 2 Wozu kürzeste Wege? 3-1 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-2 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-3 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-4 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-5 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-6 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-7 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 3-8 Modellierung des Problems Routenplanung Straßenkreuzung → Knoten Straßenabschnitt → zwei entgegengerichtete Kanten Einbahnstraßenabschnitt → in Fahrtrichtung gerichtete Kante Fahrtzeit für Abschnitt e → Kantengewicht w (e ) ≥ 0 Straßennetz → gerichteter, gewichteter und zusammenhängender Graph G (V , E ) Start → Knoten s ∈ V Ziel → Knoten t ∈ V Start-Ziel-Route → s -t -Weg, d.h. Folge von Kanten (s , v1 ), (v1 , v2 ), . . . , (vk , t ) in G 4-1 Wozu kürzeste Wege? 4-2 Wozu kürzeste Wege? 4-3 Wozu kürzeste Wege? 5 Wozu kürzeste Wege? (II) 6-1 Was ist das Problem? Eingabe: • gerichteter, zusammenhängender Graph G = (V , E ) mit nicht-negativen Kantengewichten w : E → Q+ 0, a 6 3 s 4 2 1 3 5 c 7 b 2 7 t 6-2 Was ist das Problem? Eingabe: • gerichteter, zusammenhängender Graph G = (V , E ) mit nicht-negativen Kantengewichten w : E → Q+ 0, a 6 • Knoten s und t 3 s 4 2 1 3 5 c 7 b 2 7 t 6-3 Was ist das Problem? Eingabe: • gerichteter, zusammenhängender Graph G = (V , E ) mit nicht-negativen Kantengewichten w : E → Q+ 0, b a 6 • Knoten s und t 3 s 4 2 1 2 7 3 5 Ausgabe: c t 7 P • kürzester s -t -Weg W in G , d.h. e ∈W w (e ) minimal. Darstellung durch Vorgänger-Zeiger π: für jeden Knoten v sei π(v ) ∈ V ∪ {nil } Vorgänger von v auf kürzestem s -v -Weg. 6-4 Was ist das Problem? Eingabe: • gerichteter, zusammenhängender Graph G = (V , E ) mit nicht-negativen Kantengewichten w : E → Q+ 0, b a 6 • Knoten s und t 3 s 4 2 1 2 7 3 5 Ausgabe: c t 7 P • kürzester s -t -Weg W in G , d.h. e ∈W w (e ) minimal. Darstellung durch Vorgänger-Zeiger π: für jeden Knoten v sei π(v ) ∈ V ∪ {nil } Vorgänger von v auf kürzestem s -v -Weg. 6-5 Was ist das Problem? Eingabe: • gerichteter, zusammenhängender Graph G = (V , E ) mit nicht-negativen Kantengewichten w : E → Q+ 0, b a 6 • Knoten s und t 3 s 4 2 1 2 7 3 5 Ausgabe: c t f|ür alle t ∈ V 7 {z }P • kürzester s -t -Wege Wt in G , d.h. e ∈W w (e ) minimal. Darstellung durch Vorgänger-Zeiger π: für jeden Knoten v sei π(v ) ∈ V ∪ {nil } Vorgänger von v auf kürzestem s -v -Weg. 6-6 Was ist das Problem? Eingabe: • gerichteter, zusammenhängender Graph G = (V , E ) mit nicht-negativen Kantengewichten w : E → Q+ 0, b a 6 • Knoten s und t 3 s 4 2 1 2 7 3 5 Ausgabe: c t f|ür alle t ∈ V 7 {z }P • kürzester s -t -Wege Wt in G , d.h. e ∈W w (e ) minimal. Darstellung durch Vorgänger-Zeiger π: für jeden Knoten v sei π(v ) ∈ V ∪ {nil } Vorgänger von v auf kürzestem s -v -Weg. Nebenbemerkung: Analoge Berechnungsverfahren? 7-1 Dijkstra – BFS mit Gewichten Dijkstra(WeightedGraph G = (V , E ; w ), Vertex s ) 7-2 Dijkstra – BFS mit Gewichten Dijkstra(WeightedGraph G = (V , E ; w ), Vertex s ) BFS(Graph G , Vertex s ) Initialize(G , s ) Q = new Queue() Q .Enqueue(s ) while not Q .Empty() do u = Q .Dequeue() foreach v ∈ Adj[u ] do if v .color == white then v .color = gray v .d = u .d + 1 v .π = u Q .Enqueue(v ) u .color = black 7-3 Dijkstra – BFS mit Gewichten Dijkstra(WeightedGraph G = (V , E ; w ), Vertex s ) // Gewichtung Initialize(G , s ) Q = new PriorityQueue(V , d ) BFS(Graph G , Vertex s ) Initialize(G , s ) while not Q .Empty() do Q = new Queue() u = Q .ExtractMin() Q .Enqueue(s ) foreach v ∈ Adj[u ] do while not Q .Empty() do Relax(u , v ; w ) u = Q .Dequeue() u .color = black foreach v ∈ Adj[u ] do if v .color == white then v .color = gray v .d = u .d + 1 v .π = u Q .Enqueue(v ) u .color = black 7-4 Dijkstra – BFS mit Gewichten Dijkstra(WeightedGraph G = (V , E ; w ), Vertex s ) // Gewichtung Initialize(G , s ) Q = new PriorityQueue(V , d ) BFS(Graph G , Vertex s ) Initialize(G , s ) while not Q .Empty() do Q = new Queue() u = Q .ExtractMin() Q .Enqueue(s ) foreach v ∈ Adj[u ] do while not Q .Empty() do Relax(u , v ; w ) u = Q .Dequeue() u .color = black foreach v ∈ Adj[u ] do if v .color == white then v .color = gray v .d = u .d + 1 v .π = u Q .Enqueue(v ) u .color = black 7-5 Dijkstra – BFS mit Gewichten Dijkstra(WeightedGraph G = (V , E ; w ), Vertex s ) // Gewichtung Initialize(G , s ) Q = new PriorityQueue(V , d ) BFS(Graph G , Vertex s ) Initialize(G , s ) while not Q .Empty() do Q = new Queue() u = Q .ExtractMin() Q .Enqueue(s ) foreach v ∈ Adj[u ] do while not Q .Empty() do Relax(u , v ; w ) u = Q .Dequeue() u .color = black Relax(u , v ; w ) Was muss in dieser Unterroutine passieren? Schreiben Sie’s auf! foreach v ∈ Adj[u ] do if v .color == white then v .color = gray v .d = u .d + 1 v .π = u Q .Enqueue(v ) u .color = black 7-6 Dijkstra – BFS mit Gewichten Dijkstra(WeightedGraph G = (V , E ; w ), Vertex s ) // Gewichtung Initialize(G , s ) Q = new PriorityQueue(V , d ) BFS(Graph G , Vertex s ) Initialize(G , s ) while not Q .Empty() do Q = new Queue() u = Q .ExtractMin() Q .Enqueue(s ) foreach v ∈ Adj[u ] do while not Q .Empty() do Relax(u , v ; w ) u = Q .Dequeue() u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) foreach v ∈ Adj[u ] do if v .color == white then v .color = gray v .d = u .d + 1 v .π = u Q .Enqueue(v ) u .color = black 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 1 8 2 3 9 t 4 6 5 c 2 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a∞ 8 s 0 2 3 5 c∞ 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-3 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a∞ 8 s 0 2 3 5 c∞ 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-4 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a∞ 8 s 0 2 3 5 c∞ 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-5 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a∞ 8 s 0 2 3 5 c∞ 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-6 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a 8 8 s 0 2 3 5 c∞ 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-7 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a 8 8 s 0 2 3 5 c∞ 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-8 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a 8 8 s 0 2 3 5 c 5 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-9 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 ∞t 4 6 ∞b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 14 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 14 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 14 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 14 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 13 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 13 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 13 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-1 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 13 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 9 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 9 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 9 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 9 t 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 t 9 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 t 9 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 Kürzester-Wege-Baum mit Wurzel s Dijkstra – ein Beispiel Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) a s 0 8 8 2 3 5 c 5 1 9 2 t 9 4 6 7 b Initialize(Graph G , Vertex s ) foreach u ∈ V do u .color = white u .d = ∞ u .π = nil s .color = gray s .d = 0 8-2 9-1 Dijkstra – die Laufzeit Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-2 Dijkstra – die Laufzeit Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-3 Dijkstra – die Laufzeit Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O ( ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-4 Dijkstra – die Laufzeit Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-5 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-6 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-7 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-8 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) 9-9 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) Für jeden Knoten u ∈ V genau |Adj[u ]| mal, 9-1 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) Für jeden Knoten u ∈ V (out-) genau |Adj[u ]|= deg u mal, 9-1 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) Für jeden Knoten u ∈ V (out-) genau |Adj[u ]|= deg u mal, also insg. Θ (E ) mal. 9-1 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) Für jeden Knoten u ∈ V (out-) genau |Adj[u ]|= deg u mal, also insg. Θ (E ) mal. Also wird DecreaseKey O (E ) mal aufgerufen. 9-1 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) Für jeden Knoten u ∈ V (out-) genau |Adj[u ]|= deg u mal, also insg. Θ (E ) mal. Also wird DecreaseKey O (E ) mal aufgerufen. 9-1 Dijkstra – die Laufzeit Abk. für O (V ) Dijkstra(WeightedGraph G , Vertex s ) Initialize(G , s ) O (V ) Zeit Q = new PriorityQueue(V , d ) while not Q .Empty() do genau |V | mal u = Q .ExtractMin() foreach v ∈ Adj[u ] do Relax(u , v ; w ) Wie oft wird Relax aufgerufen? u .color = black Relax(u , v ; w ) if v .d > u .d + w (u , v ) then v .color = gray v .d = u .d + w (u , v ) v .π = u Q .DecreaseKey(v , v .d ) Für jeden Knoten u ∈ V (out-) genau |Adj[u ]|= deg u mal, also insg. Θ (E ) mal. Also wird DecreaseKey O (E ) mal aufgerufen. 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. n = (max.) Anzahl der Elemente in der PriorityQueue Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld O (n ) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld ? ) Das geht, weil O (n ) O (1)? 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld O (n ) O (1)? ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld O (n ) O (1)? O ( V 2 +E ) ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld O (n ) O (1)? O ( V 2 +E ) als Heap ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap O (n ) O (1)? O ( V 2 +E ) O (log n) ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap O (n ) O (1)? O (log n) O (log n) O ( V 2 +E ) ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) als Fibonacci-Heap ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert O (1) amortisiert ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert O (1) amortisiert O (E + V log V ) im Worst-Case! ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert O (1) amortisiert O (E + V log V ) im Worst-Case! ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) siehe Seminar Entwurf und Analyse von Datenstrukturen! 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert O (1) amortisiert O (E + V log V ) im Worst-Case! ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert O (1) amortisiert O (E + V log V ) im Worst-Case! ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) Korollar. In einem Graphen G = (V , E ; w ) mit w : E → Q≥0 kann man in O (E + V log V ) Zeit die kürzesten Wege von einem zu allen Knoten berechnen (SSSP-Problem). 10 - Dijkstra – die Laufzeit Satz. Gegeben ein Graph G = (V , E ), läuft Dijstras Alg. in O (V · TExtractMin (V ) + E · TDecreaseKey (V )) Zeit. Implementierung einer PriorityQueue TExtractMin (n) TDecreaseKey (n) TDijkstra (V , E ) als unsortiertes Feld als Heap als Fibonacci-Heap O (n ) O (1)? O ( V 2 +E ) O (log n) O (log n) O ((E +V ) log V ) O (log n) amortisiert O (1) amortisiert O (E + V log V ) im Worst-Case! ? ) Das geht, weil wir bei ExtractMin Lücken im Feld lassen; daher bleiben die Schlüssel an ihrem Platz (→ Direktzugriff) Korollar. In einem Graphen G = (V , E ; w ) mit w : E → Q≥0 kann man in O (E + V log V ) Zeit die kürzesten Wege von einem zu allen Knoten berechnen (SSSP-Problem). 11 - Dijkstra – die Korrektheit 11 - Dijkstra – die Korrektheit siehe [CLRS], Kapitel 24.3., Satz 24.6: Korrektheisbeweis mittels Schleifeninvariante. 11 - Dijkstra – die Korrektheit siehe [CLRS], Kapitel 24.3., Satz 24.6: Korrektheisbeweis mittels Schleifeninvariante. oder 11 - Dijkstra – die Korrektheit siehe [CLRS], Kapitel 24.3., Satz 24.6: Korrektheisbeweis mittels Schleifeninvariante. oder MIT-Vorlesungsmitschnitt von Erik Demaine: http://videolectures.net/mit6046jf05_demaine_lec17 12 - Wozu kürzeste Wege? (III) – SMSen GHI MNO DEF MNO PQRS MNO ABC TUV GHI JKL 12 - Wozu kürzeste Wege? (III) – SMSen GHI MNO DEF MNO PQRS MNO ABC TUV GHI JKL 12 - Wozu kürzeste Wege? (III) – SMSen GHI MNO DEF MNO PQRS MNO ABC TUV GHI JKL 10:21 für T9 13 - Modellierung – SMSen J K L P W Q X R Y S Z T U V 13 - Modellierung – SMSen J K L Graph: P W Q X R Y S Z T U V 13 - Modellierung – SMSen J K L Graph: P W Q X R Y S Z T U V Knoten = ˆ Buchstaben 13 - Modellierung – SMSen J K L Graph: P W Q X R Y S Z T U V Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. 13 - Modellierung – SMSen J K L Graph: P W Q X R Y S Z T U V Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. 13 - Modellierung – SMSen J K L Graph: P W Q X R Y S Z T U V Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y Graph: 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y Graph: 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w / Häufigkeiten 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y Graph: Gesucht: 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w / Häufigkeiten 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y Graph: 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w / Häufigkeiten Gesucht: Weg P von nach mit größter WK 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w / Häufigkeiten Q Gesucht: Weg P von nach mit größter WK (= e ∈P w (e )) Graph: 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w / Häufigkeiten Q Gesucht: Weg P von nach mit größter WK (= e ∈P w (e )) Graph: Lösung: dynamisches Programmieren. . . 13 - Modellierung – SMSen 0,00001 Q X T 01 00 K 0,15 U 0,0 0 0, 0,0 2 03 0, R 01 0 0 0,00005 10 Y 0,0 03 S 01 0,0 0, L 0,00001 V 0,0 20 0, 02 0,03 W 01 0, 0 J P Z Knoten = ˆ Buchstaben Kanten = ˆ aufeinanderfolgende Buchst. Gewichte = ˆ Wahrscheinlichkeiten w / Häufigkeiten Q Gesucht: Weg P von nach mit größter WK (= e ∈P w (e )) Graph: Lösung: dynamisches Programmieren. . . [kommt noch!] 14 - Literatur • A note on two problems in connexion with graphs. Edsger Wybe Dijkstra: Numerische Mathematik (1) 1959, S. 269–271. Edsger Wybe Dijkstra ∗ 1930 in Rotterdam † 2002 in Nuenen, Niederlande 14 - Literatur • A note on two problems in connexion with graphs. Edsger Wybe Dijkstra: Numerische Mathematik (1) 1959, S. 269–271. • Das Geheimnis des kürzesten Weges. Ein mathematisches Abenteuer. Peter Gritzmann und René Brandenberg: Springer-Verlag, 3. Aufl., 2005. Edsger Wybe Dijkstra ∗ 1930 in Rotterdam † 2002 in Nuenen, Niederlande 14 - Literatur • A note on two problems in connexion with graphs. Edsger Wybe Dijkstra: Numerische Mathematik (1) 1959, S. 269–271. • Das Geheimnis des kürzesten Weges. Ein mathematisches Abenteuer. Peter Gritzmann und René Brandenberg: Springer-Verlag, 3. Aufl., 2005. Beide Werke sind über die UB frei zugänglich und über unsere WueCampus-Seite verlinkt! Edsger Wybe Dijkstra ∗ 1930 in Rotterdam † 2002 in Nuenen, Niederlande 14 - Literatur • A note on two problems in connexion with graphs. Edsger Wybe Dijkstra: Numerische Mathematik (1) 1959, S. 269–271. Lesen Sie • Das Geheimnis des mal rein! kürzesten Weges. Ein mathematisches Abenteuer. Peter Gritzmann und René Brandenberg: Springer-Verlag, 3. Aufl., 2005. Beide Werke sind über die UB frei zugänglich und über unsere WueCampus-Seite verlinkt! Edsger Wybe Dijkstra ∗ 1930 in Rotterdam † 2002 in Nuenen, Niederlande 15 - Kürzeste Wege nach Dijkstra X X nicht-neg. Kantengew. Dijkstra O (E + V log V ) ungewichteter Graph Breitensuche O (E + V ) azyklischer Graph topol. Sortieren O (E + V ) negative Kantengew. Bellman-Ford O (E V ) für alle Knotenpaare V × Dijkstra O (V (E + V log V )) + negative Kantengew. Floyd-Warshall k kürzeste s -t -Wege O (V 3 ) Johnson O (V (E + V log V )) Eppstein O (k + E + V log V ) 15 - Kürzeste Wege nach Dijkstra X O (E + V ) X ächstes O (E + V ) N X Mal! O (E + V log V ) nicht-neg. Kantengew. Dijkstra ungewichteter Graph Breitensuche azyklischer Graph topol. Sortieren negative Kantengew. Bellman-Ford O (E V ) für alle Knotenpaare V × Dijkstra O (V (E + V log V )) + negative Kantengew. Floyd-Warshall k kürzeste s -t -Wege O (V 3 ) Johnson O (V (E + V log V )) Eppstein O (k + E + V log V ) 15 - Kürzeste Wege nach Dijkstra nicht-neg. Kantengew. Dijkstra ungewichteter Graph Breitensuche azyklischer Graph topol. Sortieren X O (E + V ) X ächstes O (E + V ) N X Mal! O (E + V log V ) Vorlesung Alg. Graphentheorie (?) negative Kantengew. Bellman-Ford O (E V ) für alle Knotenpaare V × Dijkstra O (V (E + V log V )) + negative Kantengew. Floyd-Warshall k kürzeste s -t -Wege O (V 3 ) Johnson O (V (E + V log V )) Eppstein O (k + E + V log V ) 15 - Kürzeste Wege nach Dijkstra nicht-neg. Kantengew. Dijkstra ungewichteter Graph Breitensuche azyklischer Graph topol. Sortieren X O (E + V ) X ächstes O (E + V ) N X Mal! O (E + V log V ) Vorlesung Alg. Graphentheorie (?) negative Kantengew. Bellman-Ford O (E V ) für alle Knotenpaare V × Dijkstra O (V (E + V log V )) + negative Kantengew. Floyd-Warshall k kürzeste s -t -Wege 3 O (V ) X Johnson O (V (E + V log V )) Eppstein O (k + E + V log V )