Korteste vei fra alle til alle
Input: En vektet, rettet graf $G = <V,E>$ uten negative sykler, der $V = \{1, \ldots, n\}$, og vektene er gitt av matrisen $W = (W_{ij})$
Output: En $n × n$-matrise $D = (d_{ij})$ med avstander, dvs., $d_{ij} = \delta(i,j)$
For spinkle grafer: Dijkstra fra hver node!
Men hva om vi har negative kanter?
Fast økning: STier med mange kanter taper på det, dvs at den korteste stien kan bli ‘ødelagt’
Vi kan tillate oss en teleskopsum…
Vekten $w(u, v)$ økes med differansen $h(u) - h(v)$
For hver node i midten av en sti, vil kansellere hverandre
Vi må ha $w(u, v) + h(u) - h(v) \geqslant 0$, dvs $w(u, v) + h(u) \geqslant h(v)$
Fra én-til-alle: $\delta(s, v) \leqslant \delta(s, u) + w(u, v)$. Kan la $h(v) = \delta(s, v)$!
Men hva er $s$? Vi må sikre at vi når alle… (uendelighet)
Må sørge for at kantene våres er endelige. Vi kan legge til en ny node (midlertidlig)!
(Merk: VI verken innfører eller fjerner negative sykler!)
function johnson(G, w)
construct G' with start node s
bellman-ford(G', w, s)
for each vertex v ∈ G.V
h(v) = v.d
for each edge (u, v) ∈ G.E
w_hat(u,v) = w(u,v) + h(u) - h(v)
let D = (d_uv) be a new n × n matrix
for each vertex v ∈ G.V
dijkstra(G, w_hat, u)
for each vertex v ∈ G.V
d_uv = v.d + h(v) - h(u)
return D
Input: En rettet graf $G =(V, E)$
Output: En rettet graf $G⋆ = (V, E⋆)$ der $(i, j) ∈ E⋆$ hvis og bare hvis det finnes en sti fra $i$ til $j$ i $G$.
Traversér fra hver node?
Det finnes en vei fra $i$ til $j$ via node fra $\{1 \ldots k\}$
Delproblemet blir da å finne en vei fra $i$ til $j$ via nodene vi har fått tildelt.
De mulige stiene $p$, $p_1$ og $p_2$ går kun via noder fra $\{1 \ldots k - 1\}$
function transitive_closure(G)
n = |G.V|
let T^0 = (t_ij^0) be a new n \times n matrix
for i = 1:n
for j = 1:n
if i == j or (i, j) ∈ G.E
t_ij^0 = 1
else
t_ij^0 = 0
for k = 1:n
let T^k = t_ij^k be a new n × n matrix
for i = 1:n
for j = 1:n
t_{ij}^{(k)} = t_{ij}^{(k - 1)} ⋁ (t_{ki}^{(k - 1)} ⋀ t_{kj}^{(k - 1)})
return T^n
function transitive_closure'(G)
n = |G.V|
initialize T
for k = 1:n
for i = 1:n
for j = 1:n
t_{ij} = t_{ij} ⋁ (t_{ki} ⋀ t_{kj})
return T
Totalt: $\Theta(n^3)$
Fra hver node til alle andre?
Kortest vei fra $i$ til $j$ via noder fra $\{1 \ldots … k\}$
Forgjengeren til $j$ om vi starter i $i$ og går via noder fra $\{1 \ldots … k\}$
Det samme som i Transitiv lukning (k-noder).
Stien kan enten være $d_{ij}^{(k - 1)}$ eller $d_{ik}^{(k - 1)} + d_{kj}^{(k - 1)}$
Bruker bare de beste
function floyd_warshall(W)
n = W.rows
D(0) = W
for k = 1:n
let D(k) = d_{ij}^{(k)} be a new n × n matrix
for i = 1:n
for j = 1:n
d_{ij}^{(k)} = min(d_{ij}^{(k - 1)}, d_{ik}^{(k - 1)}, d_{kj}^{(k - 1)})
return D(n)
function floyd_warshall'(W)
n = W.rows
initialize D and Π
for k = 1:n
for i = 1:n
for j = 1:n
if d_ij > d_ik + d_kj
d_ij = d_ik + d_kj
π.ij = π.kj
return D, Π
function print_all_shortest_path(Π, i, j)
if i == j
print i
elseif π_ij == NIL
print "no path from" i "to" j "exists"
else
print_all_shortest_path(Π, i, π_ij)
print j
Totalt $\Theta(n^3)$