graph algorithm: breadth first search
DESCRIPTION
Nattee Niparnan. Graph Algorithm: Breadth First Search. Distance of nodes. The distance between two nodes is the length of the shortest path between them. S A 1. S C 1. S B 2. DFS and Length. DFS finds all nodes reachable from the starting node - PowerPoint PPT PresentationTRANSCRIPT
GRAPH ALGORITHM:BREADTH FIRST SEARCH
Nattee Niparnan
Distance of nodes
The distance between two nodes is the length of the shortest path between them
SA 1
SC 1
SB 2
DFS and Length
DFS finds all nodes reachable from the starting node But it might not be “visited” according to
the distance
Ball and Strings
We can compute distance by proceeding from “layer” to “layer”
Shortest Path Problem (Undi, Unit) Input:
A graph, undirected A starting node S
Output: A label on every node, giving the
distance from S to that node
Breadth-First-Search Visit node according to its layer
procedure bfs(G; s)//Input: Graph G = (V,E), directed or undirected; vertex s V//Output: visit[u] is set to true for all nodes u reachable from vfor all u V : visit[u] = false
visit[s] = trueQueue Q = [s] (queue containing just s)while Q is not empty: u = eject(Q) previsit(u) visit[u] = true; for all edges (u,v) E: if visit[v] = false: visit[v] = true; inject(Q,v); postvisit(u)
Distance using BFSprocedure shortest_bfs(G, s)//Input: Graph G = (V,E), directed or undirected; vertex s V//Output: For all vertices u reachable from s, dist(u) is setto the distance from s to u.
for all u V : dist[u] = -1
dist[s] = 0Queue Q = [s] (queue containing just s)while Q is not empty: u = eject(Q); for all edges (u,v) E: if dist[v] = -1: inject(Q,v); dist[v] = dist[u] + 1;
Use dist as visit
DFS by Stackprocedure dfs(G, s)//Input: Graph G = (V,E), directed or undirected; vertex s V//Output: visit[u] is set to true for all nodes u reachable from v
for all u V : visit[u] = false
visit[s] = trueStack S = [s] (queue containing just s)while S is not empty: u = pop(S) previsit(u) for all edges (u,v) E: if visit [v] = false: push(S,v) visit[v] = true; postvisit(u)
DFS vs BFS
DFS goes depth first Trying to go further if possible Backtrack only when no other possible
way to go Using Stack
BFS goes breadth first Trying to visit node by the distance from
the starting node Using Queue
Dijkstra’s Algorithm
Graph with Length
Edge with Length
Length functionl(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 slowImagine 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 BFSprocedure 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 setto the distance from s to u.
for all u V : dist[u] = + prev(u) = nil
dist[s] = 0H = makequeue(V) (using dist-values as keys)while H is not empty: u = deletemin(H) for all edges (u; v) E: if dist[v] > dist[u] + l(u, v): dist[v] = dist[u] + l(u, v) prev[v] = u decreasekey(H, 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 #2procedure 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 setto 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,z) E: if dist[z] > dist[v] + l(v,z): dist[z] = dist[v] + l(v,z)
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 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)
Might be V2
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
now, a shortest path must has at most |V| - 1 edges
Bellman-Ford Algorithmprocedure 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 setto 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)
Shortest Path in DAG
Path in DAG appears in linearized orderprocedure 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 setto the distance from s to u.
for all u V : dist[u] = + prev(u) = nil
dist[s] = 0Linearize GFor 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)