Analysis of Algorithms CS 465/665

Download Report

Transcript Analysis of Algorithms CS 465/665

Introduction To Algorithms
CS 445
Discussion Session 6
Instructor: Dr Alon Efrat
TA : Pooja Vaswani
03/21/2005
This Lecture
• Single-source shortest paths in weighted graphs
–
–
–
–
Shortest-Path Problems
Properties of Shortest Paths, Relaxation
Dijkstra’s Algorithm
Bellman-Ford Algorithm
2
Shortest Path
• Generalize distance to weighted setting
• Digraph G = (V,E) with weight function W: E 
R (assigning real values to edges)
• Weight of path p = v1  v2  …  vk is
k 1
w( p)   w(vi , vi 1 )
i 1
• Shortest path = a path of the minimum weight
• Applications
– static/dynamic network routing
– robot motion planning
– map/route generation in traffic
3
Shortest-Path Problems
• Shortest-Path problems
– Single-source (single-destination). Find a shortest
path from a given source (vertex s) to each of the
vertices.
– Single-pair. Given two vertices, find a shortest path
between them. Solution to single-source problem
solves this problem efficiently, too.
– All-pairs. Find shortest-paths for every pair of
vertices. Dynamic programming algorithm.
4
Negative Weights and Cycles?
• Negative edges are OK, as long as there are no
negative weight cycles (otherwise paths with
arbitrary small “lengths” would be possible)
• Shortest-paths can have no cycles (otherwise
we could improve them by removing cycles)
– Any shortest-path in graph G can be no longer than n
– 1 edges, where n is the number of vertices
5
Relaxation
• For each vertex v in the graph, we maintain
v.d(), the estimate of the shortest path from s,
initialized to at the start
• Relaxing an edge (u,v) means testing whether
we can improve the shortest path to v found so
far by going through u
u
5
2
v
u
9
5
Relax(u,v)
5
u
2
2
v
6
Relax(u,v)
7
5
v
u
2
6
Relax (u,v,G)
if v.d() > u.d()+G.w(u,v) then
v.setd(u.d()+G.w(u,v))
v.setparent(u)
v
6
Dijkstra's Algorithm
• Non-negative edge weights
• Greedy, similar to Prim's algorithm for MST
• Like breadth-first search (if all weights = 1, one
can simply use BFS)
• Use Q, a priority queue ADT keyed by v.d()
(BFS used FIFO queue, here we use a PQ,
which is re-organized whenever some d
decreases)
• Basic idea
– maintain a set S of solved vertices
– at each step select "closest" vertex u, add it to S, and
relax all edges from u
7
Dijkstra’s Pseudo Code
• Input: Graph G, start vertex s
Dijkstra(G,s)
01
02
03
04
05
06
07
08
09
10
11
12
for each vertex u  G.V()
u.setd()
u.setparent(NIL)
s.setd(0)
S 
// Set S is used to explain the algorithm
Q.init(G.V()) // Q is a priority queue ADT
while not Q.isEmpty()
u  Q.extractMin()
S  S  {u}
for each v  u.adjacent() do
relaxing
Relax(u, v, G)
edges
Q.modifyKey(v)
8
Dijkstra’s Example
u
Dijkstra(G,s)
01
02
03
04
05
06
07
08
09
10
11
12
for each vertex u  G.V()
u.setd()
u.setparent(NIL)
s.setd(0)
S 
Q.init(G.V())
while not Q.isEmpty()
u  Q.extractMin()
S  S  {u}
for each v  u.adjacent() do
Relax(u, v, G)
Q.modifyKey(v)
s
0
1

10
2
3

u
2
3
x
6

y
v

9
7
5
4
1
10
10
5
9
2
x
0

7
5
s
v
2
4
6

y
9
Dijkstra’s Example (2)
u
Dijkstra(G,s)
01
02
03
04
05
06
07
08
09
10
11
12
for each vertex u  G.V()
u.setd()
u.setparent(NIL)
s.setd(0)
S 
Q.init(G.V())
while not Q.isEmpty()
u  Q.extractMin()
S  S  {u}
for each v  u.adjacent() do
Relax(u, v, G)
Q.modifyKey(v)
s
0
1
8
10
2
5
2
3
x
y
v
13
9
7
5
6
7
1
8
10
4
2
u
5
9
3
x
0
14
7
5
s
v
2
4
6
7
y
10
Dijkstra’s Example (3)
u
Dijkstra(G,s)
01
02
03
04
05
06
07
08
09
10
11
12
for each vertex u  G.V()
u.setd()
u.setparent(NIL)
s.setd(0)
S 
Q.init(G.V())
while not Q.isEmpty()
u  Q.extractMin()
S  S  {u}
for each v  u.adjacent() do
Relax(u, v, G)
Q.modifyKey(v)
0
1
8
10
2
9
3
5
u
2
3
x
y
v
9
9
7
5
6
7
1
8
10
4
2
x
5
9
7
5
0
v
2
4
6
7
y
11
Dijkstra’s Running Time
•
•
•
•
Extract-Min executed |V| time
Decrease-Key executed |E| time
Time = |V| TExtract-Min + |E| TDecrease-Key
T depends on different Q implementations
Q
T(ExtractMin)
T(Decrease-Key) Total
array
O(V)
O(lg V)
O(lg V)
O(1)
O(lg V)
O(1) (amort.)
binary heap
Fibonacci heap
O(V 2)
O(E lg V)
O(V lgV + E)
12
Bellman-Ford Algorithm
• Dijkstra’s doesn’t work when there are negative
edges:
– Intuition – we can not be greedy any more on the
assumption that the lengths of paths will only increase
in the future
• Bellman-Ford algorithm detects negative cycles
(returns false) or returns the shortest path-tree
13
Bellman-Ford Algorithm
Bellman-Ford(G,s)
01
02
03
04
05
06
07
08
09
10
11
for each vertex u  G.V()
u.setd()
u.setparent(NIL)
s.setd(0)
for i  1 to |G.V()|-1 do
for each edge (u,v)  G.E() do
Relax (u,v,G)
for each edge (u,v)  G.E() do
if v.d() > u.d() + G.w(u,v) then
return false
return true
14
Bellman-Ford Example
t

6
s
0
2

y
t
6
6
0

7
-4
s
5
-2
2
7
y
0
9
2
7
z
y
x
t
4
-4
2
z
2
6
7
s
0
x

9
5
-2
-4
7

z
x
4
-3
8
7
5
-2
-3
8
7

9
6
6
-3
8
7
t
x
-3
8
7
s
5
-2
2
7
y
9
-4
7
2
z
15
Bellman-Ford Example
t
2
6
s
0
x
4
-3
8
7
5
-2
2
7
y
9
-4
7
2
z
• Bellman-Ford running time:
– (|V|-1)|E| + |E| = Q(VE)
16