Breadth First Search

Download Report

Transcript Breadth First Search

Nattee Niparnan
SHORTEST PATH
Graph with Length
Dijkstra’s Algorithm
Edge with Length
Length function
l(a,b) = distance
from a to b
Finding Shortest Path
 BFS can give us the shortest path
 Just convert the length edge into unit edge
However, this is very slow
Imagine a case when the length is 1,000,000
Alarm Clock Analogy
 No need to walk to every node
 Since it won’t change
anything
 We skip to the “actual” node
 Set up the clock at alarm at the
target node
Alarm Clock Algorithm
 Set an alarm clock for node s at time 0.
 Repeat until there are no more alarms:
 Say the next alarm goes off at time T, for node u.
Then:
 The distance from s to u is T.
 For each neighbor v of u in G:
 If there is no alarm yet for v, set one for time T + l(u, v).
 If v's alarm is set for later than T + l(u, v), then reset it to
this earlier time.
Dijkstra’s Algo from BFS
procedure dijkstra(G, l, s)
//Input: Graph G = (V;E), directed or undirected; vertex s  V;
positive edge lengths l
// Output: For all vertices u reachable from s, dist[u] is set
to the distance from s to u.
for all v  V
dist[v] = +
prev[v] = nil
dist[s] = 0
Priority_Queue H = makequeue(V) // enqueue all vertices (using
dist as keys)
while H is not empty
v = H.deletemin()
for each edge (v,u)  E
if dist[u] > dist[v] + l(v, u)
dist[u] = dist[v] + l(v, u)
prev[u] = v
H.decreasekey(v,dist[v]) // change the value of v to dist[v]
Another Implementation of
Dijkstra’s
 Growing from Known Region of shortest path
 Given a graph and a starting node s
 What if we know a shortest path from s to some
subset S’  V?
 Divide and Conquer Approach?
Dijktra’s Algo #2
procedure dijkstra(G, l, s)
//Input: Graph G = (V;E), directed or undirected; vertex s  V;
positive edge lengths l
// Output: For all vertices u reachable from s, dist[u] is set
to the distance from s to u.
for all u  V :
dist[u] = +
prev[u] = nil
dist[s] = 0
R = {}
// (the “known region”)
while R ≠ V :
Pick the node v  R with smallest dist[]
Add v to R
for all edges (v,u)  E:
if dist[u] > dist[v] + l(v,u)
dist[u] = dist[v] + l(v,u)
prev[u] = v
Analysis
 There are |V| ExtractMin
 Need to check all edges
 At most |E|, if we use adjacency list
 Maybe |V2|, if we use adjacency matrix
 Value of dist[] might be changed
 Depends on underlying data structure
Choice of DS
 Using simple array
 Each ExtractMin uses O(V)
 Each change of dist[] uses O(1)
 Result = O(V2 + E) = O(V2)
 Using binary heap
Might be V2
 Each ExtractMin uses O(lg V)
 Each change of dist[] uses O(lg V)
 Result = O( (V + E) lg V)
 Can be O (V2 lg V)
Good when
the graph is
sparse
Fibonacci Heap
 Using simple array
 Each ExtractMin uses O( lg V) (amortized)
 Each change of dist[] uses O(1) (amortized)
 Result = O(V lg V + E)
Graph with Negative Edge
 Disjktra’s works because a shortest path to v
must pass throught a node closer than v
 Shortest path to A pass through B which is…
in BFS sense… is further than A
Negative Cycle
 A graph with a negative cycle has no shortest
path
 The shortest.. makes no sense..
 Hence, negative edge must be a directed
Key Idea in Shortest Path
 Update the distance
if (dist[z] > dist[v] + l(v,z))
dist[z] = dist[v] + l(v,z)
 This is safe to perform
Another Approach to Shortest
Path
 A shortest path must has at most |V| - 1 edges
 Writing a recurrent
 d(n, v) = shortest distance from s to v using
at most n edges
 d(n,v) = min of
 d(n – 1, v)
 min( d(n – 1, u) + l(u,v) )
over all edges
(u,v)
 Initial d(*,s) = 0, d(|V| - 1,v) = inf
Bellman-Ford Algorithm
 Dynamic Programming
 Since d(n,*) use d(n – 1,*), we use only 1D
array to store D
Bellman-Ford Algorithm
procedure BellmanFord(G, l, s)
//Input: Graph G = (V,E), directed; vertex s  V; edge lengths l
(may be negative), no negative cycle
// Output: For all vertices u reachable from s, dist[u] is set
to the distance from s to u.
for all u  V :
dist[u] = +
prev[u] = nil
dist[s] = 0
repeat |V| - 1 times:
for all edges (a,b)  E:
if dist[b] > dist[a] + l(a,b)
dist[b] = dist[a] + l(a,b)
prev[b] = a
Analysis
 Very simple
 Loop |V| times
 Each loop takes |E| iterations
 O(V E)
 Dense graph O(V3)
 Bellman-Ford is slower but can detect
negative cycle
Detecting Negative Cycle
 After repeat the loop |V|-1 times
 If we can still do
 dist[v] = dist[u] + l(y,v)
 Then, there is a negative cycle
 Because there is a shorter path eventhough we
have repeat this |V|-1 time
for all edges (a,b)  E
if dist[b] > dist[a] + l(a,b)
printf(“negative cycle\n”)
Shortest Path in DAG
 Path in DAG appears in linearized order
procedure dag-shortest-path(G, l, s)
//Input: DAG G = (V;E), vertex s  V; edge lengths l (may be
negative)
// Output: For all vertices u reachable from s, dist[u] is set
to the distance from s to u.
for all u  V :
dist[u] = +
prev[u] = nil
dist[s] = 0
Linearize G
For each u  V , in linearized order:
for all edges (u,v)  E:
if dist[v] > dist[u] + l(u,v)
dist[v] = dist[u] + l(y,v)
prev[b] = a
All Pair Shortest Path
All Pair Shortest Path
Problem
 Input:
 A graph
 Output:
 A matrix D[1..v,1..v] giving the shortest distance
between every pair of vertices
Approach
 Standard shortest path gives shortest path
from a given vertex s to every vertex
 Repeat this for every starting vertex s
 Dijkstra O(|V| * (|E| log |V|) )
 Bellman-Ford O(|V| * (|V|3) )
 Dynamic Algorithm Approach
 Floyd-Warshall
Dynamic Algorithm Approach
 Using the previous recurrent
 d(n, v) = shortest distance from s to v using at
most n edges
 Change to
 dn(a,b) = shortest distance from a to b using at most
n edges
 dn(a,b) = min of
 dn-1(a,b)
 min(dn-1(a,k) + l(k,b) ) over all edges (k,b)
 Initial d0(a,a) = 0, d0 (a,b) = inf , d1(a,b) = l(a,b)
Dynamic Algorithm Approach
 Again, A shortest path must has at most |V| -
1 edges
 What we need to find is d|V|(a,b)
 Let D{M} be the matrix dm(a,b)
 Start with D{1} and compute D{2}
 Similar to computation of dist[] in Bellman-Ford
 Repeat until we have D{|V|}
Floyd-Warshall
 Use another recurrent
 dk(a,b) is a shortest distance from a to b that
can travel via a set of vertex {1,2,3,…,k}
 d0(a,b) = l(a,b) because it can not go pass any
vertex
 d1(a,b) means a shortest distance that the
path can have only vertex 1 (not including a
and b)
Recurrent Relation
 dk(a,b) = min of
 dk-1(a,b)
 dk-1(a,k) + dk-1 (k,b)
 Initial d0(a,b) = l(a,b)
Floyd-Warshall
procedure FloydWarshall(G, l)
//Input: Graph G = (V,E); vertex s  V; edge lengths l (may be
negative), no negative cycle
// Output: dist[u,v] is the shortest distance from u to v.
dist = l
for k = 0 to |V| - 1
for i = 0 to |V| - 1
for j = 0 to |V| - 1
dist[i][j] = min (dist[i][j],
dist[i][k] + dist[k][j])
Analysis
 Very simple
 3 nested loops of |V|
 O(|V|3)