Download de presentatie
De presentatie wordt gedownload. Even geduld aub
1
All-Pairs Shortest paths
Algoritmiek
2
All Pairs Shortest Paths
Kortste pad tussen alle paren knopen naar A R U 1 2 9 4 5 6 2 A U 5 1 van 4 R Algoritmiek
3
Hoe zouden jullie het doen?
Algoritmiek
4
Simpel idee Single source shortest path vanuit iedere knoop
Zonder lengtes BFS: O(n (n+a)) Alleen niet-negatieve lengtes Dijkstra: O(n (a + n log n)) Negatieve lengtes, maar geen negatieve cycles Bellman-Ford: O(n (na)) Algoritmiek
5
n keer Bellman-Ford direct (1)
In plaats van n aanroepen, doe alles in één dynamisch-programmerings algoritme Schrijf: Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Herinner correctheidsbewijs: Bellman-Ford berekent eigenlijk Tq(s,j) voor iedere q, j Algoritmiek
6
n keer Bellman-Ford direct (2)
Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Basisgeval:T1(i,j) = 0 als i=j L(i,j) als er een pijl (i,j) bestaat ¥ anders Bellman-Ford aanpak: Tq+1(i,j) = min{ Tq(i,j), min(k,j) in A{Tq(i,k)+L(k,j)} } q: iteratienummer, min: te vergelijken met relaxatie Algoritmiek
7
Voorbeeld Algoritmiek
8
n keer Bellman-Ford direct (3)
Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Tq+1(i,j) = min{Tq(i,j), min(k,j) in A{Tq(i,k)+L(k,j)} } Correctheid: kortste pad P met hooguit q+1 pijlen is een kortste pad met hooguit q pijlen of er is een knoop k met (k,j) in A z.d.d. P een kortste pad is van i naar k met (hooguit) q pijlen gevolgd door pijl (k,j) Sub-pad optimaliteit Door inductie en dat we min(k,j) in A nemen, weten we dat Tq+1 correct berekend wordt Algoritmiek
9
n keer Bellman-Ford direct (3)
Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Tq+1(i,j) = min{Tq(i,j), min(k,j) in A{Tq(i,k)+L(k,j)} } n iteraties In iedere iteratie: voor iedere knoop i, voor iedere knoop j, kijk naar alle ingaande buren k van j Hoe snel is dit? O(n4) met simpele analyse O(n2a) is preciezer Algoritmiek
10
n keer Bellman-Ford direct (3)
Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Tq+1(i,j) = min{Tq(i,j), min(k,j) in A{Tq(i,k)+L(k,j)} } Ruimtegebruik: O(n4), O(n3), of O(n2)? Truuk: om Tq+1 te berekenen hebben we alleen Tq nodig, en niet Tq-1, Tq-2, … Dus O(n2) ruimte Algoritmiek
11
Een algemener algoritme
Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Tq(i,j) = minknoop k {Tp(i,k) + Tq-p(k,j) } voor een vaste keuze van p Correctheid: in kortste pad P met hooguit q pijlen bestaat er knoop k z.d.d. P een kortste pad van i naar k is met (hooguit) p pijlen gevolgd door kortste pad van k naar j met (hooguit) q-p pijlen Sub-pad optimaliteit Door inductie en doordat we min over alle knopen nemen, weten we dat Tq correct berekend wordt Algoritmiek
12
Voorbeeld Algoritmiek
13
Een algemener algoritme
Tq(i,j) als lengte van het kortste pad van knoop i naar knoop j dat hooguit q pijlen gebruikt Tq(i,j) = minknoop k {Tp(i,k) + Tq-p(k,j) } voor een vaste keuze van p Wat is een goede keuze van p? p = q/2. Idee: pad halveren (cf. binair zoeken) Dan alleen nodig Tn-1, T(n-1)/2, T(n-1)/4, T(n-1)/8, … Hoeveel iteraties? log n, dus looptijd O(n3 log n) Algoritmiek
14
Kan het sneller? We hebben nu O(n2a) en O(n3 log n)
Hoe snel hangt af van ijlheid van de graaf Hoe doen we dit sneller? Vorige algoritme, maar met soort van snelle matrix-vermenigvuldiging Pad halveren blijft Of: slimmere keuze van de knoop in het midden Floyd-Warshall algoritme Algoritmiek
15
Floyd-Warshall algoritme
Algoritmiek
16
Floyd-Warshall: idee Nummer de knopen 1, 2, …, n
Kijk naar kortste pad P van knoop i naar knoop j Laat k de knoop van P zijn met hoogste nummer P[i,k] is kortste pad van i naar k dat alleen knopen met nummer kleiner dan k gebruikt; zelfde P[k,j] Sub-pad optimaliteit k i j Algoritmiek
17
Floyd-Warshall: algoritme
Nummer de knopen 1, 2, …, n. Dk(i,j) = lengte van het kortste pad van i naar j, waarbij het pad alleen knopen i, j, 1, 2, …, k mag gebruiken Merk op: d(i,j) = Dn(i,j) D2(3,5) = 4 D4(3,5) = 2 D1(1,5) = ¥ D2(1,5) = 20 D3(1,5) = 9 D4(1,5) = D5(1,5) = 7 10 10 2 5 1 4 5 1 3 4 1 Algoritmiek
18
Floyd-Warshall: algoritme
Initialisatie: k = 0 Als (i,j) in A, dan D0(i,j) = L(i,j) Als (i,j) geen pijl in A, dan: D0(i,j) = ¥ k > 0: Dk(i,j) = min{ Dk-1(i,j), Dk-1(i,k) + Dk-1(k,j) } Helpt de nieuwe knoop k? Dk-1(i,k) Dk-1(k,j) k i j Dk-1(i,j)
19
Floyd-Warshall: correctheid
Dk(i,j) = lengte van het kortste pad van i naar j, waarbij het pad alleen knopen i, j, 1, 2, …, k mag gebruiken Dk(i,j) = min{ Dk-1(i,j), Dk-1(i,k) + Dk-1(k,j) } Kortste pad gebruikt knoop k niet of wel; in het tweede geval splitst het pad zich in kortste paden i ~> k en k ~> j die alleen knopen met nummer hooguit k-1 gebruiken k i j
20
Floyd-Warshall: implementatie
Initialiseer 3-dimensionaal array D(0…n, 1…n, 1…n) op ¥ ( D(k,i,j) geeft Dk(i,j) weer ) For i=1 to n do For j=1 to n do if (i,j) in A then D(0,i,j) = L(i,j); For k=1 to n do D(k,i,j) = min { D(k-1,i,j), D(k-1,i,k)+D(k-1,k,j) } Antwoorden staan in D(n,*,*) Algoritmiek
21
Floyd-Warshall: analyse
Triviaal: O(n3) tijd Ruimte: O(n3) Kunnen we minder ruimte gebruiken? Algoritmiek
22
Floyd-Warshall: implementatie
Initialiseer 3-dimensionaal array D(0…n, 1…n, 1…n) op ¥ ( D(k,i,j) geeft Dk(i,j) weer ) For i=1 to n do For j=1 to n do if (i,j) in A then D(0,i,j) = L(i,j); For k=1 to n do D(k,i,j) = min { D(k-1,i,j), D(k-1,i,k)+D(k-1,k,j) } Antwoorden staan in D(n,*,*) Om D(k,*,*) te berekenen, gebruiken we alleen D(k-1,*,*) en niet D(k-2,*,*) etc Algoritmiek
23
Floyd-Warshall: minder geheugen
Maak 2-dimensionale arrays D(1…n, 1…n), C(1…n,1…n) Initaliseer D voor pijlen For k=1 to n do For i=1 to n do For j=1 to n do C(i,j) = min { D(i,j), D(i,k)+D(k,j) } D(i,j) = C(i,j) Antwoorden staan in D For i=1 to n do For j=1 to n do if (i,j) in A then D(0,i,j) = L(i,j); Standaard techniek voor geheugenbesparing Algoritmiek
24
20 10 5 1 4 20 10 5 1 4 20 30 25 10 10 2 5 1 4 5 1 3 4 1 1 10 5 20 1 4 30 25 10 5 6 9 1 4 20 30 25 26 3 10 5 6 7 1 2 20 30 25 26 2 4 10 5 6 7 30 35 36 22 32 1 2 21 31 26 20 25 5 Algoritmiek
25
Eigenschappen C(i,j) = min{ D(i,j), D(i,k)+D(k,j) }
10 5 6 7 1 2 20 30 25 26 Eigenschappen Merk op C(k,k) = D(k,k) = 0 Informatie nodig in ronde k verandert niet in ronde k Waarde van C(i,j) wordt 1 keer geschreven in ronde k D(i,j) wordt 1 keer uitgelezen en wordt dan in C(i,j) geschreven, BEHALVE D(*,k) en D(k,*) worden telkens uitgelezen Maar: C(i,k) = min {D(i,k), D(i,k)+D(k,k) }=D(i,k) Dus: in plaats van 2 kunnen we met 1 matrix werken. 10 5 6 7 30 35 36 22 32 1 2 21 31 26 20 25 C(i,j) = min{ D(i,j), D(i,k)+D(k,j) } Algoritmiek
26
Floyd-Warshall: minste geheugen
Initialiseer 2-dimensionale array D(1…n, 1…n) op ¥ For i=1 to n do For j=1 to n do if (i,j) in A then D(i,j) = L(i,j); For k=1 to n do D(i,j) = min { D(i,j), D(i,k)+D(k,j) } Antwoorden staan in D Algoritmiek
27
Floyd-Warshall: analyse
Triviaal: O(n3) tijd Ruimte: O(n2) Minder ruimte niet zinnig Uitvoer heeft O(n2) ruimte nodig Algoritmiek
28
Floyd-Warshall: constructief
Hoe bepalen we het pad? Houd bij welke knoop we gebruiken Zelfde idee voor Dijkstra, Bellman-Ford, etc. Extra matrix P P(v,w) geeft een knoop die ligt tussen v en w op een kortste pad van v naar w Tijdens algoritme: P(v,w) geeft zo’n knoop van een pad van v naar w met lengte de huidige waarde D(v,w) Algoritmiek
29
Floyd-Warshall: constructief
Maak 2-dimensionale arrays D(1…n, 1…n) en P(1…n,1…n) Initaliseer D met pijlen For i=1 to n do For j=1 to n do P(i,j) = “#” For k=1 to n do If D(i,j) > D(i,k)+D(k,j) Then D(i,j) = D(i,k) + D(k,j); P(i,j) = k For i=1 to n do For j=1 to n do if (i,j) in A then D(i,j) = L(i,j); Algoritmiek
30
Construeer pad van i naar j
Pathconstruct (P, D, i, j) if D(i,j) = ¥ then return “Er is geen pad” if P(i,j) = “#” then return pad met 1 pijl: (i,j). k = P(i,j); Pad1 = Pathconstruct(P,D,i,k); Pad2 = Pathconstruct(P,D,k,j); Plak paden Pad1 en Pad2 achterelkaar, en return dat pad. Algoritmiek
31
Pijlen met negatieve lengte
Algoritme werkt correct als er geen negatieve cycle is Als wel een negatieve cycle: er komt een v met D(v,v) < 0 -2 -1 1 -1 -2 3 2 1 1 -1 4 -2 -1 1 -2 -3 -1 1 -2 -3 -1 1 -2 -3 -1 1 D(4,3)+D(3,4) = – = – 1 Algoritmiek
32
“Huiswerk” Bewijs dat Floyd-Warshall een negatieve waarde geeft voor D(v,v) voor alle knopen v die in een negatieve cycle zitten Algoritmiek
33
Link doen met Dijkstra’s algoritme
Johnson’s algoritme Algoritmiek
34
Dijkstra: ter herinnering
Dijkstra’s algoritme werkt niet met negatieve pijl-lengtes Zelfs niet als we een constante optellen bij iedere pijl-lengtes v 5 s -20 1 t x 2 s v t -1 1 Algoritmiek
35
Johnson’s algoritme voor APSP
Basis-idee: Dijkstra’s algoritme aanroepen vanuit iedere knoop Verrassend: werkt voor negatieve pijl-lengtes Truuk: Tel een waarde bij iedere pijl op die niet constant is, maar goed gekozen wordt Algoritmiek
36
Johnson: pijl-lengte (1)
Kies een waarde p(u) voor iedere knoop u Op een slimme manier (zien we zo) p is een potentie functie Bereken L’(u,v) = p(u) + L(u,v) – p(v) Bewering: Als Q een pad is van s naar t, dan geldt L’(Q) = p(s) + L(Q) – p(t) 4 1 1 u v -2 Algoritmiek
37
Johnson: pijl-lengte (2)
L’(u,v) = p(u) + L(u,v) – p(v) Bewering: Als Q een pad is van s naar t, dan geldt L’(Q) = p(s) + L(Q) – p(t) Stel Q is s = v0 v1 … vk = t L’(Q) = Σi L’(vi-1, vi) = Σi p(vi-1) + L(vi-1, vi) – p(vi) = Σi L(vi-1, vi) + Σi p(vi-1) – p(vi) = L(Q) + p(v0) – p(vk) = L(Q) + p(s) – p(t) Algoritmiek
38
Johnson: pijl-lengte (3)
L’(u,v) = p(u) + L(u,v) – p(v) Bewering: Als Q een pad is van s naar t, dan geldt L’(Q) = p(s) + L(Q) – p(t) Gevolgen: Als Q en R paden van s naar t zijn, dan L’(Q) ≤ L’(R) d.e.s.d.a L(Q) ≤ L(R) Een kortste pad onder L is een kortste pad onder L’, en visa versa Algoritmiek
39
Johnson: pijl-lengte (4)
L’(u,v) = p(u) + L(u,v) – p(v) Een kortste pad onder L is een kortste pad onder L’, en visa versa Truuk: functie p kiezen zodat L’ niet-negatief is Algoritmiek
40
Johnson: keuze van p Voeg een nieuwe knoop x toe
Pijl (x,u) voor iedere knoop u L(x,u) = 0 Bereken d(x,u) voor iedere knoop u Zet p(u) = d(x,u) Bewering: L’(u,v) = p(u) + L(u,v) – p(v) ≥ 0 Want p(u) + L(u,v) ≥ p(v) Pad x ~> u -> v is een x ~> v pad, kortste pad is minstens zo kort G Algoritmiek
41
Johnson: algoritme G x Voeg een nieuwe knoop x toe, pijl (x,u) voor iedere knoop u, L(x,u) = 0 Bereken p(u) = d(x,u) voor iedere knoop u Bereken L’(u,v) = p(u) + L(u,v) – p(v) Bereken dL’(u,v) door n keer Dijkstra’s algoritme Mag omdat L’(u,v) ≥ 0 voor alle pijlen (u,v) Bereken d(u,v) = dL’(u,v) – p(u) + p(v) Herinner: Als Q een pad is van s naar t, dan geldt L’(Q) = p(s) + L(Q) – p(t) Gebruik Bellman-Ford
42
Johnson: correctheid Correctheid van pijl-lengtes al beargumenteerd
Nieuwe pijl-lengtes zijn niet-negatief, dus we mogen Dijkstra gebruiken Graaf G plus knoop x bevat geen negatieve cycles als G geen negatieve cycles bevat, dus we mogen Bellman-Ford gebruiken Kortste pad onder nieuwe pijl-lengtes komt overeen met kortste pad onder oude pijl-lengtes Algoritmiek
43
Johnson: analyse Bellman-Ford om potentie-functie uit te rekenen O(na)
n keer Dijkstra O(n (a + n log n) ) Totaal: O(na + n2 log n) Algoritmiek
44
Reflectie op APSP Algoritmiek
45
Reflectie: theorie Algoritmes: O(n3) en O(na + n2 log n)
Kan het sneller? Ja, voor speciale klassen van grafen Sneller dan O(n2) niet, vanwege formaat uitvoer In het algemeen? Veel andere problemen met algoritme met looptijd O(n3) zijn ‘vergelijkbaar’ Master-vak: Network Science & Analysis Algoritmiek
46
Samenvatting Single source/target
Dijkstra’s algoritme: O((n+a) log n) of O(a + n log n) Alleen niet-negatieve lengtes Bellman-Ford: O(na) Ook negatieve lengtes, geen negatieve cycles All pairs: O(n3) of O(na + n2 log n) Kan ook negatieve lengtes aan; detecteert negatieve cycles Single pair: veel toepassingen, maar er zijn in O-notatie geen snellere algoritmen bekend Wel in de praktijk (o.a. bidirectioneel zoeken, werken met schattingen, …) Algoritmiek
Verwante presentaties
© 2024 SlidePlayer.nl Inc.
All rights reserved.