Breadth-First Search
Breadth-first search: a method to search a graph and an
exemplar of many important graph algorithms. Given G = ( V, E ), chose a
vertex, s, to be the source. Move out from s, systematically to find
all v Î V that are accessible from s, and
compute their distances from s. Distance from s to v is the "shortest
path".
Words: start at s, find all vertices distance 1 from
s, keep going until all vertices have been discovered.
Dye analogy: s is the dye injection point and you
watch the progress of the dye through the graph. Each time step a single
edge is crossed. In breadth-first search, each vertex is colored:
-
White: not yet discovered
-
Gray: discovered but still some undiscovered adjacent
vertices .
-
Black: discovered and all adjacent vertices discovered
Gray vertices are the frontier/interface between
discovered/undiscovered.
Constructing a breadth-first tree:
-
Start with s (the root)
-
Scan the adjacency list of all previously discovered
nodes. If u was previously discovered and we just found v, then we add
v. u is the predecessor/parent of v in the breadth-first tree.
This progresses, iteratively. Note: Start with all nodes
white. When you first encounter a white node, you make it gray. When you go
through that node's adjacency list, you make it black.
Code: Store
-
Color (white or gray or black)
-
Predecessor p[n]
-
Distance from s d[n]
BFS ( G, s )
-
for each vertex u Î V[G] -
{s}
-
do color [u] ¬ white
// white out all but s
-
d[u] ¬
¥
-
p[u]
¬ nil
-
color [s] ¬ gray // s
starts out gray
-
d[s] ¬ 0
-
p[s] ¬
nil
-
Q ¬ {s} // end
initialization
-
while Q ¹ Æ
-
do u ¬ head[Q]
-
for each v Adj[u]
-
do if
color[v] = white
-
then color[v] ¬ gray
-
d[v] ¬ d[u] + 1
-
p[v] ¬ u
-
Enqueue ( Q, v )
-
Dequeue ( Q ) //
Q stores grays
-
color[u] ¬
black // all of u's adjacents have been seen, so color it black
and
// move on
Running time of Breadth-First search:
-
Each node is enqueued once (white ®
gray)
-
Each node is dequeued once (gray ® black)
-
Each adjacency list is scanned only once.
-
O ( | V | )
-
O ( | V | )
-
O ( | E | )
Overall running time is O ( | V | + | E | ). Clearly
better to use the adjacency list representation. (What differs with the
matrix representation?)
Shortest-path distance: d ( s, v
) is the minimum number of edges in any path from s to v, or ¥
if there is no path. A path from s to v with distance d
( s, v ) is a shortest-path. Note, there may be more than one shortest path.
Lemma: Let G = ( V, E ) be a graph, s Î
V an arbitrary vertex, then " ( u, v
) Î E d ( s, v ) £
d ( s, v ) + 1. If u is reachable from s, then it holds. If not then
both d ( s, v ) = ¥ and
it holds.
Suppose BFS is run on G from s. " v
Î V d[v] ³ d ( s, v
)
Induction on vertices:
-
d[s] = 0 = d ( s, s )
-
d[v] = ¥ ³ d ( s, v
) " s ¹ v
at the first step
v is discovered from u (u is at the head of Q), v is
white.
Induction when u is at the head of Q
Assume d[u] ³ d ( s, v )
d[v] = d[u] + 1
³
d ( s, v ) + 1
³ d ( s, v )
Proved.
Suppose during BFS Q contains v1, ... vv)
Þ d[vv] £ d[v1],
d[vi] £ d[vi+1], i = 1,
..., v - 1
Proof:
Induction on queue operations.
-
When Q = <s> it holds
-
Must prove it holds after both dequeuing and
enqueuing a vertex when v1 is is dequeued v2 becomes
the head
d[vr] £ d[v1]
+ 1 £ d[v2] + 1
Ö
What happens we enqueue? vv+1 is enqueued
Adj[v1] vv+1.
d[vv+1] = d[v1] + 1
Ö
d[vv] £ d[v1]
+ 1 = d[vv+1]
Ö
Let G = ( V, E ) and s Î V
for BFS.
-
BFS discovers all v Î V
that are reachable from s
-
d[v] = d ( s, v ) "
v Î V (even ¥)
-
" v ¹
s reachable, a shortest path is the shortest path from s to p[v]
followed on ( p[v], v )
Proof:
If v is unreachable it's true. d[v] = ¥
= d ( s, v ). If v is reachable from s
define:
Vk = { v Î V: d
( s, v ) = k}
Inductions on k, " v Î
Vk
the above 4 bullets all happen during the same loop
k = 0 = V0 {s}
Ö
Q is never empty until the end. Once u is enqueued, d[u]
and p[u] are set and do not change. From
previous results we have that d[vi] £ d[vi+1],
and v Î Vk Þ
d[v] ³ k and v is discovered after all Vk-1
vertices are enqueued. Since d ( s, v )
= k $ u Î Vk-1
'( u, v ) Î E.
Let u be the first of these grayed. U must also eventually appear
at the head of Q, when it is Adj[u] is scanned and v is discovered, this
is the first time it could be (would be in Vk-1,
then).
BFS:
d[v] = d[u] + 1
p[v] = u
enqueues
Ö
This proof by induction is done. (Clearly ( p[u],
u )is in a shortest path.)
Breadth-First Trees:
G = ( V, E ), s Î V source. G
= ( Vp, Ep
) is the predecessor sub graph. Vp =
{ v Î V | p[v] ¹
nil } v {s} (accessible vertices) Ep
= { ( p[v], v ) Î E
: v Î Vp
- {s}} (tree edges) . Gp is a
breadth first tree. " v Î
Vp $ a unique simple path
from s to v.
BFS to G constructs p so Gp
is a BF Tree.
Proof:
v Î Vp
only if reachable p[v] = u only if ( v, v ) E
by previous the unique path must be the shortest.
Print-Path ( G, s, v )
-
if v = s
-
then print s
-
else if p[v] =
nil
-
then print "no
path from " s " to " v " exists"
-
else Print-Path ( G, s,
p[v] )
-
print
v
Prints out the vertices from s to b in G.
|