Dijkstra's Algorithm
Sources:
S. Skiena. The Algorithm Design Manual.
S. Sedgewick. Algorithms in C++ (3rd Edition)
Problem
Two algorithms, depending on what information
we want
Recall: All pairs shortest path: Floyd's algorithm
Single source shortest path: Dijkstra's algorithm
Dijkstra's Algorithm
Dijkstra's algorithm solves related problem to
APSP (Floyd's algorithm): Single source
shortest path (SSSP)
Idea: For a single node, what is shortest path to any
other node?
More restricted question
Can answer somewhat more quickly
Dijkstra's algorithm: Greedy approach
Dijkstra's Algorithm
Basic idea: Divide vertices into three groups
Tree vertices: We know the shortest path to these
Fringe vertices: Adjacent to a tree vertex; we don't
know the shortest path to these yet
Distant vertices: Not adjacent to a tree vertex; we
don't consider them at all
Iterate n times:
Find fringe vertex with lowest distance from source
Move from fringe to tree
Update any vertices that are now fringe vertices
Example
Assume we start at A
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
BB
CC
DD
EE
FF
GG
HH
II
JJ
Dist
Dist
00
77
-33
-------
Neigh
Neigh
-AA
-AA
-------
C
3
5
Tree
Fringe
Distant
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
BB
CC
D*
D*
EE
FF
GG
HH
II
JJ
Dist
Dist
00
77
-33
44
-10
10
----
Neigh
Neigh
-AA
-AA
DD
-DD
----
C
3
5
Tree
Fringe
Distant
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
BB
CC
D*
D*
E*
E*
FF
GG
HH
II
JJ
Dist
Dist
00
77
-33
44
88
10
10
----
Neigh
Neigh
-AA
-AA
DD
EE
DD
----
C
3
5
Tree
Fringe
Distant
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
CC
D*
D*
E*
E*
FF
GG
HH
II
JJ
Dist
Dist
00
77
-33
44
88
10
10
----
Neigh
Neigh
-AA
-AA
DD
EE
DD
----
C
3
5
Tree
Fringe
Distant
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
CC
D*
D*
E*
E*
F*
F*
GG
HH
II
JJ
Dist
Dist
00
77
-33
44
88
99
--14
14
Neigh
Neigh
-AA
-AA
DD
EE
FF
--FF
C
3
5
Tree
Fringe
Distant
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
CC
D*
D*
E*
E*
F*
F*
G*
G*
HH
II
JJ
Dist
Dist
00
77
-33
44
88
99
--14
14
Neigh
Neigh
-AA
-AA
DD
EE
FF
--FF
C
3
5
Tree
Fringe
Distant
10
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
CC
D*
D*
E*
E*
F*
F*
G*
G*
HH
II
J*
J*
Dist
Dist
00
77
19
19
33
44
88
99
22
22
23
23
14
14
Neigh
Neigh
-AA
JJ
AA
DD
EE
FF
JJ
JJ
FF
C
3
5
Tree
Fringe
Distant
11
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
C*
C*
D*
D*
E*
E*
F*
F*
G*
G*
HH
II
J*
J*
Dist
Dist
00
77
19
19
33
44
88
99
22
22
23
23
14
14
Neigh
Neigh
-AA
JJ
AA
DD
EE
FF
JJ
JJ
FF
C
3
5
Tree
Fringe
Distant
12
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
C*
C*
D*
D*
E*
E*
F*
F*
G*
G*
H*
H*
II
J*
J*
Dist
Dist
00
77
19
19
33
44
88
99
22
22
23
23
14
14
Neigh
Neigh
-AA
JJ
AA
DD
EE
FF
JJ
JJ
FF
C
3
5
Tree
Fringe
Distant
13
Example
Add closest
3
D
F
7
4
H
8
3
E
4
J
9
Vertex
Vertex
A*
A*
B*
B*
C*
C*
D*
D*
E*
E*
F*
F*
G*
G*
H*
H*
I*I*
J*
J*
Dist
Dist
00
77
19
19
33
44
88
99
22
22
23
23
14
14
Neigh
Neigh
-AA
JJ
AA
DD
EE
FF
JJ
JJ
FF
C
3
5
Tree
Fringe
Distant
14
Implementation
Question: How to implement?
Solution: A priority queue, implemented with a
heap
Need to be able to find fringe vertices quickly
Also need to be able to find least valued fringe
vertex
Order = distance from source vertex
Need to specify graph structure...
15
Graph Structure
class Vertex
data
index
qindex
neighbors
integer
Used for SSSP
nearestw
Elements are (float,int) pairs
First = weight of edge, second = index of neighbor
nearestv
label or similar
integer: Index in G.vertices
integer: Index in priority queue
list
float
Used for SSSP
class Graph
vertices
list of Vertex objects
16
Example
Example for this small graph:
G: Graph object
data = A, index=0
neighbors = [(7,1),(3,3)]
data = C, index=2
neighbors=[ (1,3) ]
<D>: Vertex object
data = D, index=3
neighbors = [ ]
D
7
2
B
data = B, index=1
neighbors=[ (2,0) ,(4,3) ]
<C>: Vertex object
<B>: Vertex object
vertices = [ <A>, <B>, <C>, <D> ]
<A>: Vertex object
1
4
C
17
Dijkstra's Algorithm
def dijkstra(G,src):
#G = graph
Q=[ ]
for v in G.vertices:
v.nearestv = None
if v.name == src:
v.nearestw=0
else:
v.nearestw=None
Q.append(tmp)
heapify(Q)
#None counts as infinity
for i in range(len(Q)):
Q[i].qindex = i
...continued...
18
Dijkstra's Algorithm
while len(Q) > 0:
x=heappop(Q) #updates qindex
for nn in x.neighbors:
ew = nn[0]
#edge weight
ni = nn[1]
#neighbor index
n = G.vertices[ ni ]
#neighbor itself
if n.nearestw == None or
n.nearestw > x.nearestw + ew:
n.nearestv = x.index
n.nearestw = x.nearestw + ew
reheapify(Q,n)
19
Reheapify
Remember, priority queue is sorted based on
distance from source vertex
If we change a vertex's nearest neighbor, we
might move it up in the queue
So this is what reheapify does
Parameters: The queue (array) and the index
node we have altered
20
Reheapify
def reheapify(Q,v):
vi = v.qindex
#index in queue
pi = (vi-1)/2
#parent's index in queue
p = Q[pi]
#parent node itself
while vi > 0 and p.nearestw > v.nearestw:
#swap queue entries for parent & v
tmp = Q[pi]
Q[pi] = Q[vi]
Q[vi] = tmp
#update qslot data
Q[pi].qslot = pi
Q[vi].qslot = vi
vi = pi
pi = (vi-1)/2
21
heappop
def heappop(Q):
x = Q[0]; y = Q.pop(); Q[0]=y; Q[0].qindex=0
vi = 0; li = vi*2+1 ; ri = vi*2+2
#li,ri=left/right children
while 1:
if li < len(Q): v1=Q[li].nearestw
else: v1 = infinity
if ri < len(Q): v2=Q[ri].nearestw
else: v2 = infinity
if v1 < Q[vi].value and v1<=v2:
tmp = Q[li]; Q[li]=Q[vi]; Q[vi]=tmp
Q[li].qindex = li; Q[vi].qindex=vi
vi=li
elif v2 < Q[vi].value and v2 <= v1:
...swap items vi and ri, move down to ri
else:
break
22
Analysis
How much time for Dijkstra?
Does V loop iterations
Each loop iteration takes time lg(V) (to pop and
reheapify)
Thus, O(V lg V) for vertex processing
Also, within loop, we consider all neighbors of
popped vertex
Each edge gets considered exactly once
So O(V lg V + E) time total
Dense graph: EV2
Thus, O(V2 + V lg V)
23