Shortest Path Properties

Weighted Graphs (§ 12.5)
In a weighted graph, each edge has an associated numerical
value, called the weight of the edge
Edge weights may represent, distances, costs, etc.
Example:
A
8
B
2
8
7
4
2
9
D
8
3
SFO
5
F
HNL
Shortest Paths
1
Shortest Paths (§ 12.6)
„
1843
2
LAX
1233
DFW
Shortest Paths
7
138
2
14
PVD
LGA
1120
10
99
SFO
HNL
2555
MIA
3
© 2004 Goodrich, Tamassia
1843
43
17
LAX
1233
ORD
DFW
Shortest Paths
849
2
14
PVD
LGA
7
138
1120
10
99
1205
43
17
849
ORD
337
© 2004 Goodrich, Tamassia
Shortest Paths
© 2004 Goodrich, Tamassia
There is a tree of shortest paths from a start vertex to all the other
vertices
1205
2555
MIA
Tree of shortest paths from Providence
337
HNL
1120
Example:
Internet packet routing
Flight reservations
Driving directions
SFO
10
99
A subpath of a shortest path is itself a shortest path
Shortest path between Providence and Honolulu
802
„
LGA
7
138
Property 2:
Applications
„
DFW
PVD
Property 1:
Length of a path is the sum of the weights of its edges.
Example:
„
LAX
1233
2
14
Shortest Path Properties
Given a weighted graph and two vertices u and v, we want to
find a path of minimum total weight between u and v.
„
43
17
849
ORD
802
© 2004 Goodrich, Tamassia
2555
1843
1205
3
1
In a flight route graph, the weight of an edge represents the
distance in miles between the endpoint airports
337
5
E
2
C
„
0
802
Shortest Paths
MIA
4
Dijkstra’s Algorithm (§ 12.6.1)
The distance of a vertex
v from a vertex s is the
length of a shortest path
between s and v
Dijkstra’s algorithm
computes the distances
of all the vertices from a
given start vertex s
Assumptions:
the graph is connected
the edges are
undirected
the edge weights are
nonnegative
„
„
„
Consider an edge e = (u,z)
such that
We grow a “cloud” of vertices,
beginning with s and eventually
covering all the vertices
We store with each vertex v a
label d(v) representing the
distance of v from s in the
subgraph consisting of the cloud
and its adjacent vertices
At each step
„
„
„
„
A
B
2
8
7
∞
2
C
3
B
A
2
2
7
5
E
1
∞
C
3
© 2004 Goodrich, Tamassia
0
2
4
5
B
9
z
10 d(z) = 60
z
Shortest Paths
© 2004 Goodrich, Tamassia
F
7
5
E
3
5
B
2
Shortest Paths
7
C
3
4
2
1
9
D
8
2
7
C
3
0
2
3
B
5
F
A
5
E
0
A
8
2
8
D
11
8
2
4
1
A
8
D
F
8
8
4
9
E
e
u
10 d(z) = 75
6
Example (cont.)
0
2
d(u) = 50
s
5
e
u
s
d(z) ← min{d(z),d(u) + weight(e)}
Example
8
d(u) = 50
u is the vertex most recently
added to the cloud
z is not in the cloud
The relaxation of edge e
updates distance d(z) as
follows:
We add to the cloud the vertex
u outside the cloud with the
smallest distance label, d(u)
We update the labels of the
vertices adjacent to u
Shortest Paths
© 2004 Goodrich, Tamassia
Edge Relaxation
2
2
7
7
C
3
5
E
0
2
4
1
9
D
8
F
3
5
4
1
9
D
8
F
A
8
B
3
2
5
7
© 2004 Goodrich, Tamassia
Shortest Paths
2
7
7
C
3
5
E
0
2
4
1
9
D
8
F
3
5
8
Dijkstra’s Algorithm
A priority queue stores
the vertices outside the
cloud
„
„
Key: distance
Element: vertex
Locator-based methods
„
„
insert(k,e) returns a
locator
replaceKey(l,k) changes
the key of an item
We store two labels
with each vertex:
„
„
Distance (d(v) label)
locator in priority
queue
© 2004 Goodrich, Tamassia
Analysis of Dijkstra’s Algorithm
Graph operations
Algorithm DijkstraDistances(G, s)
Q ← new heap-based priority queue
for all v ∈ G.vertices()
if v = s
setDistance(v, 0)
else
setDistance(v, ∞)
l ← Q.insert(getDistance(v), v)
setLocator(v,l)
while ¬Q.isEmpty()
u ← Q.removeMin()
for all e ∈ G.incidentEdges(u)
{ relax edge e }
z ← G.opposite(u,e)
r ← getDistance(u) + weight(e)
if r < getDistance(z)
setDistance(z,r)
Q.replaceKey(getLocator(z),r)
Shortest Paths
„
„
„
„
parent edge in the
shortest path tree
In the edge relaxation
step, we update the
parent label
© 2004 Goodrich, Tamassia
„
„
Each vertex is inserted once into and removed once from the priority
queue, where each insertion or removal takes O(log n) time
The key of a vertex in the priority queue is modified at most deg(w)
times, where each key change takes O(log n) time
Dijkstra’s algorithm runs in O((n + m) log n) time provided the
graph is represented by the adjacency list structure
„
Recall that
Σv deg(v) = 2m
The running time can also be expressed as O(m log n) since the
graph is connected
9
© 2004 Goodrich, Tamassia
Shortest Paths
10
Why Dijkstra’s Algorithm Works
Dijkstra’s algorithm is based on the greedy
method. It adds vertices by increasing distance.
Algorithm DijkstraShortestPathsTree(G, s)
…
„
for all v ∈ G.vertices()
…
setParent(v, ∅)
…
„
for all e ∈ G.incidentEdges(u)
{ relax edge e }
z ← G.opposite(u,e)
r ← getDistance(u) + weight(e)
if r < getDistance(z)
setDistance(z,r)
setParent(z,e)
Q.replaceKey(getLocator(z),r)
Shortest Paths
We set/get the distance and locator labels of vertex z O(deg(z)) times
Setting/getting a label takes O(1) time
Priority queue operations
Shortest Paths Tree
Using the template
method pattern, we
can extend Dijkstra’s
algorithm to return a
tree of shortest paths
from the start vertex
to all other vertices
We store with each
vertex a third label:
Method incidentEdges is called once for each vertex
Label operations
„
„
11
Suppose it didn’t find all shortest
distances. Let F be the first wrong
vertex the algorithm processed.
When the previous node, D, on the
true shortest path was considered,
its distance was correct.
But the edge (D,F) was relaxed at
that time!
Thus, so long as d(F)>d(D), F’s
distance cannot be wrong. That is,
there is no wrong vertex.
© 2004 Goodrich, Tamassia
Shortest Paths
A
8
B
2
2
7
7
C
3
5
E
0
2
4
1
9
D
8
F
5
12
3
Why It Doesn’t Work for
Negative-Weight Edges
Bellman-Ford Algorithm
(not in book)
Dijkstra’s algorithm is based on the greedy
method. It adds vertices by increasing distance.
If a node with a negative
incident edge were to be added
late to the cloud, it could mess
up distances for vertices already
in the cloud.
„
A
8
B
6
7
7
4
5
0
5
2
C
0
1
-8
9
E
4
D
F
5
C’s true distance is 1, but
it is already in the cloud
with d(C)=5!
Shortest Paths
© 2004 Goodrich, Tamassia
13
Works even with negative- Algorithm BellmanFord(G, s)
weight edges
for all v ∈ G.vertices()
if v = s
Must assume directed
setDistance(v, 0)
edges (for otherwise we
else
would have negativesetDistance(v, ∞)
weight cycles)
for i ← 1 to n-1 do
Iteration i finds all shortest
for each e ∈ G.edges()
paths that use i edges.
{ relax edge e }
Running time: O(nm).
u ← G.origin(e)
z ← G.opposite(u,e)
Can be extended to detect
r ← getDistance(u) + weight(e)
a negative-weight cycle if it
if r < getDistance(z)
exists
„
setDistance(z,r)
How?
© 2004 Goodrich, Tamassia
Shortest Paths
14
DAG-based Algorithm
(not in book)
Bellman-Ford Example
Nodes are labeled with their d(v) values
0
8
4
-2
∞
7
-2
∞
∞
3
0
8
1
∞
∞
5
8
-2
∞
7
-2
∞
3
9
0
8
∞
4
7
1
-2
6
∞
© 2004 Goodrich, Tamassia
1
∞
∞
5
0
8
4
4
Works even with
negative-weight edges
Uses topological order
Doesn’t use any fancy
data structures
Is much faster than
Dijkstra’s algorithm
Running time: O(n+m).
-2
1
-2
3
-2
9
-2
5 8
4
9
9
∞
4
-1
5
7
3
5
-2
Shortest Paths
1
1
-2
9
4
9
-1
Algorithm DagDistances(G, s)
for all v ∈ G.vertices()
if v = s
setDistance(v, 0)
else
setDistance(v, ∞)
Perform a topological sort of the vertices
for u ← 1 to n do {in topological order}
for each e ∈ G.outEdges(u)
{ relax edge e }
z ← G.opposite(u,e)
r ← getDistance(u) + weight(e)
if r < getDistance(z)
setDistance(z,r)
5
15
© 2004 Goodrich, Tamassia
Shortest Paths
16
DAG Example
Nodes are labeled with their d(v) values
1
1
0
8
4
-2
3
2
7
∞
3
-5
∞
4
1
∞
0
8
3
∞
∞
8
-2
2
7
3
9
∞
6
5
-5
∞
5
8
-5
5
∞
6
4
1
∞
∞
5
5
0
8
-2
2
4
1
1
0
7
-2
9
1
8
3
∞
4
6
© 2004 Goodrich, Tamassia
4
1
-2
3
4
-2
9
7
∞
4
-1
5
3
5
-5
5
Shortest Paths
2
7
0
1
3
6
4
1
-2
9
7
(two steps)
4
-1
5
5
17
4