• Keine Ergebnisse gefunden

Kürzeste Pfade

N/A
N/A
Protected

Academic year: 2022

Aktie "Kürzeste Pfade"

Copied!
12
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

VL-17: Kürzeste Pfade

(Datenstrukturen und Algorithmen, SS 2017) Walter Unger

SS 2017, RWTH

DSAL/SS 2017 VL-17: Kürzeste Pfade 1/44

Organisatorisches

• Vorlesung: Gerhard Woeginger (Zimmer 4024 im E1) Sprechstunde: Mittwoch 11:15–12:00

• Übungen: Tim Hartmann, David Korzeniewski, Björn Tauer Email:dsal-i1@algo.rwth-aachen.de

• Webseite:http://algo.rwth-aachen.de/Lehre/SS17/DSA.php

• Nächste Vorlesung:

Dienstag, Jul 4, 16:15–17:45 Uhr, Aula 1

DSAL/SS 2017 VL-17: Kürzeste Pfade 2/44

Kürzeste Pfade

• Single-Source Shortest Path

• Bellman-Ford

• Dijkstra

• All-Pairs Shortest Paths

• Transitive Hüllen

• Algorithmus von Warshall

• Algorithmus von Floyd

Das Rechenproblem: Kürzeste Pfade (1)

(2)

Das Rechenproblem: Kürzeste Pfade (2)

DSAL/SS 2017 VL-17: Kürzeste Pfade 5/44

Kürzeste Pfade: Das Problem

Beispiel (kürzester Weg)

Eingabe: 1. Eine Strassenkarte, auf der der Abstand zwischen jedem Paar von benachbarten Kreuzungen eingezeichnet ist,

2. eine Startkreuzungs, 3. eine Zielkreuzungt.

Ausgabe: Der kürzeste Weg vons nacht.

DSAL/SS 2017 VL-17: Kürzeste Pfade 6/44

Kürzeste Pfade: Notation

Gegeben ist ein kanten-gewichteter GraphG = (V,E,W).

• Gewicht eines Pfades =Summeder Gewichte der Kanten

• Ein kürzester Pfadvon KnotensV zu KnotenvV ist ein Pfad vons nachv mitminimalem Gewicht.

Im Folgenden istδ: (V ×V)→(R∪ {+inf})eine Funktion, sodass:

I δ(s,v)ist das Gewicht des kürzesten Pfades vons nachv, und

I δ(s,v) = +inf, fallsv vons nicht erreichbar ist.

Kürzeste Pfade: Varianten

Es gibt viele verschiedene Problemvarianten:

I Kürzeste Pfade von einem Startknotens zu allen anderen Knoten:

Single-Source Shortest Paths(SSSP).

I Kürzeste Pfade von allen Knoten zu einem Zielknoten t.

Lässt sich auf SSSP zurückführen.

I Kürzester Pfad füreinfestes Knotenpaaru,v.

Es ist kein Algorithmus bekannt, der asymptotisch schneller ist als der beste SSSP-Algorithmus.

I Kürzeste Pfade für alleKnotenpaare.

All-Pairs Shortest Paths(APSP, zweiter Teil dieser Vorlesung).

(3)

Single-Source Shortest Path

DSAL/SS 2017 VL-17: Kürzeste Pfade 9/44

Single-Source Shortest Paths

Problem (Single-Source Shortest Path)

Für einen fixen gegebenen Knoten sV (Quelle/source), bestimme für jeden anderen Knoten tV

einen kürzesten Pfad vons zut.

DSAL/SS 2017 VL-17: Kürzeste Pfade 10/44

Bellman-Ford

Der Bellman-Ford Algorithmus

I Berechnet kürzeste Pfade von einemeinzigen Startknoten aus

I ErlaubtnegativeKantengewichte.

I Zeigt an, ob es einen Kreis mit negativem Gewichtgibt, der vom Startknoten aus erreichbar ist.

I Falls ein solcher Kreis gefunden wird, gibt eskeineLösung

(da die Gewichte der kürzesten Pfade nicht mehr wohldefiniert sind).

I Sonst verbessert der Algorithmus iterativ für jeden Knoten v eine obere Grenze dist[v]fürδ(s,v), bis das Minimum gefunden wird.

I Kürzeste Pfade können nach Terminierung mittels der im Array prevgespeichertenVorgängerknotenentlang eines kürzesten Pfades rekonstruiert werden.

(4)

Bellman-Ford: Grundideen

I Initialisierung:dist[v]=+inf; dist[start]=0.

I Für alle Kanten(v,w)∈E:

Relaxierung: Ist das bisher bekannte Gewichtdist[w]grösser als dist[v]+W(v,w), soverbesseredist[w]auf diesen Wert.

I Wiederhole den vorigen Schritt bis sich nichts mehr ändert, oder brich, falls ein negativer Kreis gefunden wird.

Korrektheit von Bellman-Ford

Falls nach|V|−1 Wiederholungen noch Verbesserungen möglich sind, so gibt es einen negativen Kreis.

Andernfalls giltdist[v] =δ(s,v)für alle KnotenvV. Beweisidee:

Pfad ohne Kreis in(V,E,W)enthält ≤ |V|−1 Zwischenknoten.

DSAL/SS 2017 VL-17: Kürzeste Pfade 13/44

Bellman-Ford in Pseudo-Code

1 bool bellmanFord(List adj[n], int n, int start, 2 int &dist[n], int &prev[n]) {

3

4 for (int v = 0; v < n; v++) // f u e r a l l e K n o t e n v 5 dist[v] = +inf;

6 prev[v] = -1; // v hat n o c h k e i n e n V o r g a e n g e r

7 }

8

9 d i s t [ s t a r t ] = 0; // E n t f e r n u n g von s t a r t zu s t a r t ist 0 10 for ( int i = 1; i < n ; i ++) // n -1 D u r c h l a e u f e

11 for ( int v = 0; v < n ; v ++) // f u e r a l l e K n o t e n v 12 f o r e a c h ( e d g e in adj [ v ])

13 if ( d i s t [ e d g e . t a r g e t ] > d i s t [ v ] + e d g e . w e i g h t ) { 14 d i s t [ e d g e . t a r g e t ] = d i s t [ v ] + e d g e . w e i g h t ; 15 p r e v [ e d g e . t a r g e t ] = v ;

16 } // R e l a x i e r u n g 17

18 for (int v = 0; v < n; v++) // f u e r a l l e K n o t e n v 19 foreach (edge in adj[v])

20 if (dist[edge.target] > dist[v] + edge.weight) 21 return false; // K r e i s mit n e g a t i v e m G e w i c h t 22 r e t u r n t r u e ;

23 }

Zeitkomplexität:O(|V| · |E|)

DSAL/SS 2017 VL-17: Kürzeste Pfade 14/44

Bellman-Ford: Beispiel

0

14

18 ∞

6

24

∞ ∞

14

6

4

10

9

-12 3

3

8

2

15

Dijkstra

(5)

Der Dijkstra Algorithmus

Grundlegende Annahme

Alle Kantengewichte sindnicht-negativ:W(u,v)≥0für alle(u,v)E. Ergo: Kürzeste Pfade enthaltenkeine Kreise

Edsger Wybe Dijkstra (1930-2002), Turing Award 1972

DSAL/SS 2017 VL-17: Kürzeste Pfade 17/44

Dijkstra: Grundideen

Wie beim Algorithmus von Prim klassifizieren wir die Knoten in drei Kategorien:

Baumknoten: gehören zum bis jetzt konstruierten Baum

Randknoten: nicht im Baum, aber adjazent zu Knoten im Baum UngeseheneKnoten: alle anderen Knoten.

Grundkonzept:

I Kein Knoten ausserhalb des Baumes hat einen kürzeren Pfad als die Knoten im Baum.

I Jedem Knotenvist ein Wert dist[v]zugeordnet:

I Für Baumknotenv gilt: dist[v] =δ(s,v);

I Für Randknotenv gilt: dist[v] ist Minimum der Gewichte aller Pfade vom Startknoten zuv, wobei die letzte Kante im Schnitt liegt;

I Für ungesehenen Knotenv gilt: dist[v] =+inf.

DSAL/SS 2017 VL-17: Kürzeste Pfade 18/44

Dijkstra Algorithmus: Grundgerüst

1 // u n g e r i c h t e t e r G r a p h G mit n K n o t e n 2 v o i d d i j k s t r a S P ( G r a p h G , int n ) {

3 i n i t i a l i s i e r e a l l e K n o t e n als U N G E S E H E N ( W H I T E ) ; 4 markiere s als BAUM (BLACK) und setze d(s,s) =0;

5 r e k l a s s i f i z i e r e a l l e zu s adj K n o t e n als R A N D ( G R A Y ) ; 6 w h i l e ( es g i b t R a n d k n o t e n ) {

7 w a e h l e von a l l e n K a n t e n z w i s c h e n B a u m k n o t e n t und 8 R a n d k n o t e n v mit minimalem d(s,t) +W(t,v);

9 r e k l a s s i f i z i e r e v als B A U M ( B L A C K ) ; 10 f u e g e K a n t e (t,v) zum B a u m h i n z u ; 11 setze d(s,v) =d(s,t) +W(t,v);

12 r e k l a s s i f i z i e r e a l l e zu v adj U N G E S E H E N e n K n o t e n 13 als R A N D ( G R A Y ) ;

14 }

15 }

Die Unterschiede zu Prim’s Spannbaum Algorithmus sind rot gekennzeichnet

Dijkstra Algorithmus: Beispiel

0

14

6

10

7

5 14

14 6

10 5 5

3 3

4 4

8 8

2

15

15

9

9

(6)

Dijkstra Algorithmus: Korrektheit (1)

Theorem

Wir betrachten einen Zeitpunkt während der Exekution des Dijkstra Algorithmus. Es seiB der zu diesem Zeitpunkt konstruierte (rote) Teilbaum. Dann gilt:

1. dist[v]≥δ(s,v) für alle KnotenvV 2. dist[v] =δ(s,v) für alle BaumknotenvB

3. dist[v] =min({∞} ∪ {δ(s,x) +W(x,v)|xB und(x,v)∈E}) für alle Nicht-BaumknotenvV \B;

4. δ(s,v)δ(s,u) für alle BaumknotenvB und uV\B.

DSAL/SS 2017 VL-17: Kürzeste Pfade 21/44

Dijkstra Algorithmus: Korrektheit (2)

1. dist[v]δ(s,v) für alle KnotenvV 2. dist[v] =δ(s,v) für alle BaumknotenvB

3. dist[v] =min({∞} ∪ {δ(s,x) +W(x,v)|xB, (x,v)E})fürvV\B 4. δ(s,v)δ(s,u)für alle BaumknotenvBunduV\B

Beweis.

1. und 3. und 4. sind (ziemlich) trivial.

Wir beweisen 2. durch Induktion über die Anzahl der Baumknoten:

I Basis:Bist leer undB={s}(nach erster Iteration): trivial.

I Ind. Schritt: Nimm an, Behauptung gilt für|B|=k>0. Seiv der Knoten der als nächster zum BaumBhinzugefügt wird. Der Falldist[v] = +infist trivial.

Betrachtedist[v]6= +inf. Dann gibt es eine Kante vom Baumknoten

x=prev[v]Bzuv6∈B. Aus 3. folgt, dassdist[v]das Gewicht des kürzesten Pfades vonsnachvüber Baumknoten ist. Aus 4. und der Wahl vonvfolgt, dass es keinen kürzeren Pfad gibt, d.h.,dist[v] =δ(s,v).

DSAL/SS 2017 VL-17: Kürzeste Pfade 22/44

Korrektheit

Theorem (Korrektheit)

Der Dijkstra Algorithmus berechnet die kürzesten Abstände

zwischen Knotens und jedem vons aus erreichbaren Knoten inG.

Dijkstra Algorithmus: Implementierung

1 // I n p u t : g e w i c h t e t e r G r a p h mit n Knoten , S t a r t k n o t e n 2 void dijkstra(int adj[n], int n, int start, int &dist[n],

3 int &prev[n]) {

4 for (int i = 0; i < n; i++) { 5 dist[i] = inf; prev[i] = -1;

6 }

7 dist[start] = 0; // s t a r t ist R a n d k n o t e n mit K o s t e n 0 8 Q = 0,...,n-1; // Q e n t h a e l t a l l e u n g e s e h e n e n K n o t e n

9 // und a l l e R a n d k n o t e n

10 w h i l e ( Q not e m p t y ) {

11 // v e r s c h i e b e b i l l i g s t e n R a n d k n o t e n v in B a u m :

12 // e x t r a c t M i n ( Q ) b e s t i m m t E l e m e n t e aus Q mit m i n i m a l e m 13 // d i s t [ e ] , e n t f e r n t e aus Q und g i b t e z u r u e c k 14 v = e x t r a c t M i n ( Q ) ;

15 for e a c h ( e d g e in adj [ v ]) // a k t u a l i s i e r e K o s t e n

16 // f u e r R a n d k n o t e n

17 if ( e d g e . t a r g e t in Q and

18 d i s t [ v ]+ e d g e . w e i g h t < d i s t [ e d g e . t a r g e t ]) { 19 d i s t [ e d g e . t a r g e t ] = d i s t [ v ] + e d g e . w e i g h t ; 20 p r e v [ e d g e . t a r g e t ] = v ;

21 }

22 }

23 }

(7)

Dijkstra Algorithmus: Anmerkungen

I Die kürzesten Wege werden mit zunehmendem Abstand zur Quelles gefunden.

I Implementierung: Ähnlich zum Spannbaum Algorithmus von Prim.

I Zeitkomplexität im Worst-Case:Θ(|V|2).

I Untere Schranke der Komplexität:Ω(|E|)

(Im schlimmsten Fall müssen alle Kanten überprüft werden.)

I Platzkomplexität:O(|V|).

I Dijkstra erlaubt keine negative Kosten. Warum?

DSAL/SS 2017 VL-17: Kürzeste Pfade 25/44

All-Pairs Shortest Paths

DSAL/SS 2017 VL-17: Kürzeste Pfade 26/44

All-Pairs Shortest Paths

Wir betrachten gewichtete gerichtete GraphenG= (V,E,W).

I Negative Gewichte sind erlaubt, aber keine Kreise mit negativem Gewicht.

I Nicht vorhandene Kanten haben GewichtW(·,·) = +inf.

Problem (All-Pairs Shortest Path)

Berechne für jedes Paari,j das GewichtD[i,j]des kürzesten Pfades.

Naive Lösung:

• Wende SSSP-Algorithmus (z.B. Bellman-Ford)|V|mal an.

• Dies führt zu Worst-Case ZeitkomplexitätO(|V|4).

• Effizientere Version:Floyd’s Algorithmus

Binäre Relationen

Binäre Relation

Eine(binäre) RelationR über einer MengeS ist eine TeilmengeRS×S =S2.

Reflexivität, Transitivität

Eine RelationR ist

• reflexiv, wenn(u,u)R für alleuS

• transitiv, wenn aus(u,v)∈R und (v,w)∈R immer (u,w)R folgt

Transitive Hülle

Dietransitive Hülle R einer RelationR ist die kleinste Erweiterung (Obermenge)RRS2, sodassR reflexiv und transitiv ist.

Transitive Hülle eines Graphen

Für Graphen mit MengeS =V und RelationR=E gilt:

(u,v)∈R gdw. es gibt Pfad vonunachv.

(8)

Transitive Hülle: Beispiel

R=

0 1 0 0 1

0 0 0 1 0

0 1 0 0 0

0 0 1 0 0

0 0 0 1 0

und transitive HülleR=

1 1 1 1 1

0 1 1 1 0

0 1 1 1 0

0 1 1 1 0

0 1 1 1 1

D

C B

A

E

Binäre RelationR

D

C B

A

E

Transitive HülleR

DSAL/SS 2017 VL-17: Kürzeste Pfade 29/44

Algorithmus von Warshall

DSAL/SS 2017 VL-17: Kürzeste Pfade 30/44

Algorithmus von Warshall: Idee (1)

AusR[i,k]und R[k,j]folgt ErreichbarkeitR[i,j].

k

i j

1 f o r e a c h (kV)

2 f o r e a c h ( e i n g e h e n d e K a n t e (i,k)E) 3 f o r e a c h ( a u s g e h e n d e K a n t e (k,j)E) 4 F u e g e (i,j) zu E h i n z u .

Algorithmus von Warshall: Idee (2)

Das reicht bereits aus, um längere Pfade zu berücksichtigen:

1 2

Die Reihenfolge spielt dabei keine Rolle:

2 1

(9)

Algorithmus von Warshall: Idee (3)

Allgemeiner Fall:

i j

k

⊆ {1, . . .,k−1} ⊆ {1, . .. ,k−1}

Das lässt sich als Rekursionsgleichung schreiben, wobeitij(k)=true

besagt, dass nach Berücksichtigung der Zwischenknoten{1, . . . ,k}der Knotenj voni aus erreichbar ist:

tij(k)=tij(k−1)

tik(k−1)tkj(k−1)

DSAL/SS 2017 VL-17: Kürzeste Pfade 33/44

Algorithmus von Warshall: Idee (4)

tij(k) =





false fürk =0, falls(i,j)6∈E

true fürk =0, falls(i,j)E

tij(k−1)

tik(k−1)tkj(k−1)

fürk >0

Da zur Berechnung vontij(k) nur die Wertetuv(k−1) gebraucht werden und da keine älteren Wertetuv(j) mitj <k−1 gebraucht werden, kann die Berechnungdirektim Ausgabearray (in-place) erfolgen.

DSAL/SS 2017 VL-17: Kürzeste Pfade 34/44

Algorithmus von Warshall: Beispiel (1)

Eine mögliche Nummerierung der Knoten:

0

1

2

3

5

4 6

7

x x x x xx· ·

·x·x·x· ·

· ·x·x· · ·

· · ·x·x· ·

· · · ·x·x·

· · · ·x x·x

· · · ·x·

· · · ·x

Algorithmus von Warshall: Beispiel (2)

Eine andere Nummerierung der Knoten:

0

1

4

7

6

5 2

3

x x x·x x·x

·x· · · · ·x

· ·x· · · · ·

· · ·x· · · ·

· ·x·x x· ·

· ·x· ·x· ·

· ·x x·x x·

· ·x x·xx x

Permutierung der Knoten liefert gleiche Matrixdarstellung vonRwie zuvor

(10)

1 f o r e a c h (kV)

2 f o r e a c h ( e i n g e h e n d e K a n t e (i,k)E) 3 f o r e a c h ( a u s g e h e n d e K a n t e (k,j)E) 4 F u e g e (i,j) zu E h i n z u .

1 v o i d t r a n s C l o s ( b o o l A [ n ][ n ] , int n , b o o l & R [ n ][ n ]) { 2 for ( int i = 0; i < n ; i ++)

3 for ( int j = 0; j < n ; j ++)

4 R [ i , j ] = A [ i , j ]; // K o p i e r e A n a c h R 5

6 for ( int i = 0; i < n ; i ++)

7 R [ i , i ] = t r u e ; // r e f l e x i v e H u e l l e 8

9 for ( int k = 0; k < n ; k ++) 10 for ( int i = 0; i < n ; i ++)

11 for ( int j = 0; j < n ; j ++)

12 R [ i , j ] = R [ i , j ] || ( R [ i , k ] && R [ k , j ]) ; 13 }

Zeitkomplexität:Θ(|V|3); Platzkomplexität:Θ(|V|2)

DSAL/SS 2017 VL-17: Kürzeste Pfade 37/44

Algorithmus von Floyd

DSAL/SS 2017 VL-17: Kürzeste Pfade 38/44

Der Algorithmus von Floyd

Zurück zu All-Pairs Shortest Paths:

• Algorithmus von Floyd löst APSP

• Grundidee: Erweiterung von Algorithmus von Warshall (Literatur nennt den Algorithmus oft“Floyd-Warshall”)

Der Algorithmus von Floyd: Idee

i j

k

⊆ {1

, . . .,k1} ⊆ {1, . .. ,k1}

25 10

36

Wir gehen wie bei Warshall vor, jedoch mit der folgenden angepassten Rekursionsgleichung:

dij(k)=

W(i,j) fürk =0

min

dij(k−1),dik(k−1)+dkj(k−1)

fürk >0

statt:tij(k)=tij(k−1)

tik(k−1)tkj(k−1)

(11)

Der Algorithmus von Floyd: Idee

i j

k

⊆ {1

, . . .,k1} ⊆ {1, . .. ,k1}

25 10

35

Wir gehen wie bei Warshall vor, jedoch mit der folgenden angepassten Rekursionsgleichung:

dij(k) =

W(i,j) fürk =0

min

dij(k−1),dik(k−1)+dkj(k−1)

fürk >0

statt:tij(k)=tij(k−1)

tik(k−1)tkj(k−1)

DSAL/SS 2017 VL-17: Kürzeste Pfade 40/44

Der Algorithmus von Floyd: Beispiel

https://www.cs.usfca.edu/~galles/visualization/Floyd.html

DSAL/SS 2017 VL-17: Kürzeste Pfade 41/44

Der Algorithmus von Floyd: Implementierung

1 v o i d f l o y d S P ( d o u b l e W [ n ][ n ] , int n , d o u b l e & D [ n ][ n ]) { 2 for ( int i = 0; i < n ; i ++)

3 for ( int j = 0; j < n ; j ++)

4 D [ i , j ] = W [ i , j ]; // K o p i e r e W n a c h D 5

6 for ( int i = 0; i < n ; i ++) // r e f l e x i v e H u e l l e 7 D [ i , i ] = 0;

8

9 for ( int k = 0; k < n ; k ++) 10 for ( int i = 0; i < n ; i ++)

11 for ( int j = 0; j < n ; j ++)

12 D [ i , j ] = min ( D [ i , j ] , D [ i , k ] + D [ k , j ]) ; 13 }

I Zeitkomplexität:Θ(|V|3); Platzkomplexität: Θ(|V|2).

I Hier nicht behandelt: Der Algorithmus kann auch mit negativen Kreisen umgehen.

Der Algorithmus von Floyd: Erweiterung

I Der angegebene Algorithmus berechnet nur die Länge der Pfade.

I Der Algorithmus lässt sich leicht auf die Berechung von Pfaden erweitern (z. B. Routingtabellen).

I Dazu speichern wir für jedes Paar (i,j)jeweils den letzten Zwischenknotenπij des kürzesten Pfades voni nachj (das heisst, πij ist der Vorgänger vonj auf diesem Pfad).

π(k)ij =













i fürk =0,i6=j, fallsW(i,j)6= +inf null fürk =0, sonst

π(k−1)kj fürk >0, fallsdij(k−1)>dik(k−1)+dkj(k−1) π(k−1)ij sonst

(12)

Organisatorisches

• Nächste Vorlesung:

Dienstag, Jul 4, 16:15–17:45 Uhr, Aula 1

• Webseite:http://algo.rwth-aachen.de/Lehre/SS17/DSA.php

DSAL/SS 2017 VL-17: Kürzeste Pfade 44/44

Referenzen

ÄHNLICHE DOKUMENTE

I Sonst verbessert der Algorithmus iterativ für jeden Knoten v eine obere Grenze dist[v] an δ(s , v ), bis das Minimum gefunden wird. I Kürzeste Pfade können nach Terminierung

I Sonst verbessert der Algorithmus iterativ für jeden Knoten v eine obere Grenze dist[v] an ”(s , v ), bis das Minimum gefunden wird. I Kürzeste Pfade können nach Terminierung

Sauvignon blanc 2016 / 75cl Adrian Hartmann Oberflachs 49.00 Frisch und fruchtig mit exotischen

Satz DijkKor: Wenn man Dijksta‘s Algorithmus auf einem gewichteten, gerichteten Graphen mit nicht-negativer Gewichtsfunktion w und Startknoten s laufen läßt, gilt für alle Knoten u

Wähle einen einfachen Zyklus, der keine verworfene Kante enthält Verwirf die längste unter den unentschiedenen Kanten im Zyklus. Präzisierung

Aufgabe 4.2.2(9): Gesucht ist das kürzeste Verbindungssystem von sieben Punkten und zwar den sechs Punkten eines regelmäßigen Sechsecks mit der Seite a und dem Umkreismittelpunkt

Sonst verbessert der Algorithmus iterativ für jeden Knoten v eine obere Grenze dist[v] für δ(s, v), bis das Minimum gefunden wird.. Kürzeste Pfade können nach Terminierung mittels

Die Ausleerungen waren in den ersten Tagen regelmässig mehr oder weniger getrübt, auch dann, wenn der Urin in den Gummiblasen aufgefangen wurde, welche sonst auf ihren Inhalt