5
Graph Traversal with DFS/BFS Tyler Moore CSE 3353, SMU, Dallas, TX Lecture 6 Some slides created by or adapted from Dr. Kevin Wayne. For more information see http://www.cs.princeton.edu/ ~ wayne/kleinberg-tardos Graph Traversal One of the most fundamental graph problems is to traverse every edge and vertex in a graph. For correctness, we must do the traversal in a systematic way so that we dont miss anything. For eciency, we must make sure we visit each edge at most twice. Since a maze is just a graph, such an algorithm must be powerful enough to enable us to get out of an arbitrary maze. 2 / 20 Marking Vertices The key idea is that we must mark each vertex when we rst visit it, and keep track of what have not yet completely explored. Each vertex will always be in one of the following three states: 1 undiscovered the vertex in its initial, virgin state. 2 discovered the vertex after we have encountered it, but before we have checked out all its incident edges. 3 processed the vertex after we have visited all its incident edges. A vertex cannot be processed before we discover it, so over the course of the traversal the state of each vertex progresses from undiscovered to discovered to processed. 3 / 20 To Do List We must also maintain a structure containing all the vertices we have discovered but not yet completely explored. Initially, only a single start vertex is considered to be discovered. To completely explore a vertex, we look at each edge going out of it. For each edge which goes to an undiscovered vertex, we mark it discovered and add it to the list of work to do. Note that regardless of what order we fetch the next vertex to explore, each edge is considered exactly twice, when each of its endpoints are explored. 4 / 20

To Do List · 2014. 2. 6. · Edge cases for DFS/BFS traversal Tree edges d b e c a Forward edge d b e c a Back edge d b e c a Cross edges d b e c a 19/20 Edge classification 1 Edge

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: To Do List · 2014. 2. 6. · Edge cases for DFS/BFS traversal Tree edges d b e c a Forward edge d b e c a Back edge d b e c a Cross edges d b e c a 19/20 Edge classification 1 Edge

Graph Traversal with DFS/BFS

Tyler Moore

CSE 3353, SMU, Dallas, TX

Lecture 6

Some slides created by or adapted from Dr. Kevin Wayne. For more information see

http://www.cs.princeton.edu/~wayne/kleinberg-tardos

Graph Traversal

One of the most fundamental graph problems is to traverse everyedge and vertex in a graph.

For correctness, we must do the traversal in a systematic way so thatwe dont miss anything.

For efficiency, we must make sure we visit each edge at most twice.

Since a maze is just a graph, such an algorithm must be powerfulenough to enable us to get out of an arbitrary maze.

2 / 20

Marking Vertices

The key idea is that we must mark each vertex when we first visit it,and keep track of what have not yet completely explored.

Each vertex will always be in one of the following three states:1 undiscovered the vertex in its initial, virgin state.2 discovered the vertex after we have encountered it, but before we have

checked out all its incident edges.3 processed the vertex after we have visited all its incident edges.

A vertex cannot be processed before we discover it, so over the courseof the traversal the state of each vertex progresses from undiscoveredto discovered to processed.

3 / 20

To Do List

We must also maintain a structure containing all the vertices we havediscovered but not yet completely explored.

Initially, only a single start vertex is considered to be discovered.

To completely explore a vertex, we look at each edge going out of it.For each edge which goes to an undiscovered vertex, we mark itdiscovered and add it to the list of work to do.

Note that regardless of what order we fetch the next vertex toexplore, each edge is considered exactly twice, when each of itsendpoints are explored.

4 / 20

Page 2: To Do List · 2014. 2. 6. · Edge cases for DFS/BFS traversal Tree edges d b e c a Forward edge d b e c a Back edge d b e c a Cross edges d b e c a 19/20 Edge classification 1 Edge

In what order should we process vertices?

1 First-in-first-out: if we use a queue to process discovered vertices, weuse breadth-first search

2 Last-in-first-out: if we use a stack to process discovered vertices, weuse depth-first search

5 / 20

Depth-First Traversal

Undirected Graph

a

b

c

d

ef

Discovered:

a

a

b

b

c

c

d

d

e

e

f

fProcessed:

e

e

d

d

c

c

b

b

f

f

a

a

Depth-First Search Tree

a

b

c

d

e

f

1

23

4

7

5

6

6 / 20

Recursive Depth-First Traversal Code

def r e c d f s (G, s , S=None ) :i f S i s None : S = s e t ( )# I n i t i a l i z e the h i s t o r yS . add ( s ) # We ’ ve v i s i t e d sf o r u i n G[ s ] : # Exp l o r e n e i g hbo r s

i f u i n S : continue# Al r eady v i s i t e d : Sk ipr e c d f s (G, u , S ) # New : Exp l o r e r e c u r s i v e l y

>>> r e c d f s t e s t e d (G, 0)[ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ]

7 / 20

Iterative Depth-First Traversal Code

def i t e r d f s (G, s ) :S , Q = s e t ( ) , [ ] # V i s i t e d−s e t and queueQ. append ( s ) # We p lan on v i s i t i n g swhi le Q: # Planned nodes l e f t ?

u = Q. pop ( ) # Get onei f u i n S : continue# Al r eady v i s i t e d ? Sk ip i tS . add ( u ) # We ’ ve v i s i t e d i t nowQ. extend (G[ u ] ) # Schedu l e a l l n e i g hbo r sy i e l d u # Report u as v i s i t e d

>>> l i s t ( i t e r d f s (G, 0 ) )[ 0 , 5 , 7 , 6 , 2 , 3 , 4 , 1 ]

8 / 20

Page 3: To Do List · 2014. 2. 6. · Edge cases for DFS/BFS traversal Tree edges d b e c a Forward edge d b e c a Back edge d b e c a Cross edges d b e c a 19/20 Edge classification 1 Edge

What does the yield command do?

When you execute a function, it normally returns values

Generators only execute code when iterated

Useful when you don’t need to keep the list of values you loop over

Especially helpful when the object you’re iterating over is very large,and you don’t want to keep the entire object in memory

Nice explanation on Stack Overflow: http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained

9 / 20

Breadth-First Traversal

Undirected Graph

a

b

c

d

ef

Discovered:

a

a

b

b

e

e

f

f

c

c

d

dProcessed:

a

a

b

b

e

e

f

f

c

c

d

d

Breadth-First Search Tree

a

b e f

c d

1 2

3

4 6

5

7

10 / 20

Breadth-First Traversal Code

from c o l l e c t i o n s import dequedef i t e r b f s (G, s , S = None ) :

S , Q = s e t ( ) , deque ( ) # V i s i t e d−s e t and queueQ. append ( s ) # We p lan on v i s i t i n g swhi le Q: # Planned nodes l e f t ?

u = Q. p o p l e f t ( ) # Get onei f u i n S : continue# Al r eady v i s i t e d ? Sk ip i tS . add ( u ) # We ’ ve v i s i t e d i t nowQ. extend (G[ u ] ) # Schedu l e a l l n e i g hbo r sy i e l d u # Report u as v i s i t e d

11 / 20

Correctness of Graph Traversal

Every edge and vertex in the connected component is eventuallyvisited. Why?

Suppose it’s not correct, ie. there exists an unvisited vertex A whoseneighbor B was visited.

When B was visited, each of its neighbors was added to the list to beprocessed. Since A is a neighbor of B , it must be visited before thealgorithm completes.

12 / 20

Page 4: To Do List · 2014. 2. 6. · Edge cases for DFS/BFS traversal Tree edges d b e c a Forward edge d b e c a Back edge d b e c a Cross edges d b e c a 19/20 Edge classification 1 Edge

Preorder vs. postorder processing

Many useful algorithms are built on top of BFS or DFS traversal

Frequently, extra code is added either immediately before a node isprocessed (preorder processing) or after a node is processed(postorder processing)

13 / 20

Preorder and postorder processing with BFS

def b f s pp (G, s , S = None ) :S , Q = s e t ( ) , deque ( ) # V i s i t e d−s e t and queueQ. append ( s ) # We p lan on v i s i t i n g swh i l e Q: # Planned nodes l e f t ?

u = Q. p o p l e f t ( ) # Get onei f u i n S : cont inue# Al r eady v i s i t e d ? Sk ip i tp r i n t ’ p r e ’+u # pr e o r d e r p r o c e s s i n g −− aka p r o c e s s v e r t e x e a r l y (ADM)S . add ( u ) # We ’ ve v i s i t e d i t nowQ. extend (G[ u ] ) # Schedu l e a l l n e i g hbo r sy i e l d u # Report u as v i s i t e dp r i n t ’ −−−−−− pos t ’+u # po s t o r d e r p r o c e s s i n g −− aka p r o c e s s v e r t e x l a t e

>>> l i s t ( b f s pp (N, ’ a ’ ) )p re a−−−−−− pos t ap re b−−−−−− pos t bp re e−−−−−− pos t ep re f−−−−−− pos t fp r e c−−−−−− pos t cp re d−−−−−− pos t d[ ’ a ’ , ’ b ’ , ’ e ’ , ’ f ’ , ’ c ’ , ’ d ’ ]

14 / 20

Preorder and postorder processing with DFS

def r e c d f s p p (G, s , S=None ) :i f S i s None : S = s e t ( )# I n i t i a l i z e the h i s t o r yS . add ( s ) # We ’ ve v i s i t e d sp r i n t ’ p r e : ’+s # p r i n t node −− p r e o r d e r p r o c e s s i n gf o r u i n G[ s ] : # Exp l o r e n e i g hbo r s

i f u i n S : cont inue# Al r eady v i s i t e d : Sk ipr e c d f s p p (G, u , S ) # New : Exp l o r e r e c u r s i v e l y

p r i n t ’−−−−−− pos t : ’+s # p r i n t node −− po s t o r d e r p r o c e s s i n gr e t u r n S

>>> l i s t ( r e c d f s p p (N, ’ a ’ ) )p re : ap re : bp re : cp re : dp re : e−−−−−− pos t : e−−−−−− pos t : d−−−−−− pos t : c−−−−−− pos t : bp re : f−−−−−− pos t : f−−−−−− pos t : a[ ’ a ’ , ’ c ’ , ’ b ’ , ’ e ’ , ’ d ’ , ’ f ’ ]

15 / 20

DFS Trees: all descendants of a node u are processed afteru is discovered but before u is processed

Undirected Graph

a

b

c

d

ef

Discovered:

a

a

b

b

c

c

d

d

e

e

f

fProcessed:

e

e

d

d

c

c

b

b

f

f

a

a

Depth-First Search Tree

a

b

c

d

e

f

1

23

4

10

5

6

16 / 20

Page 5: To Do List · 2014. 2. 6. · Edge cases for DFS/BFS traversal Tree edges d b e c a Forward edge d b e c a Back edge d b e c a Cross edges d b e c a 19/20 Edge classification 1 Edge

How can we tell if one node is a descendant of another?

Answer: with depth-first timestamps!

After we create a graph in a depth-first traversal, it would be nice tobe able to verify if node A is encountered before node B , etc.

We add one timestamp for when a node is discovered (during preorderprocessing) and another timestamp for when a node is processed(during postorder processing)

17 / 20

Code for depth-first timestamps

def d f s (G, s , d , f , S=None , t =0):i f S i s None : S = s e t ( )# I n i t i a l i z e the h i s t o r yd [ s ] = t ; t += 1 # Set d i s c o v e r t imeS . add ( s ) # We ’ ve v i s i t e d sf o r u i n G[ s ] : # Exp l o r e n e i g hbo r s

i f u i n S : continue# Al r eady v i s i t e d . Sk ipt = d f s (G, u , d , f , S , t ) # Recur se ; update

f [ s ] = t ; t += 1 # Set f i n i s h t imereturn t # Return t imestamp

>>> f={}>>> d={}>>> d f s (N, ’ a ’ , d , f )12>>> d{ ’ a ’ : 0 , ’ c ’ : 2 , ’ b ’ : 1 , ’ e ’ : 4 , ’ d ’ : 3 , ’ f ’ : 9}>>> f{ ’ a ’ : 11 , ’ c ’ : 7 , ’ b ’ : 8 , ’ e ’ : 5 , ’ d ’ : 6 , ’ f ’ : 10}

18 / 20

Edge cases for DFS/BFS traversal

Tree edges

d

b

e

c

a

Forward edge

d

b

e

c

a

Back edge

d

b

e

c

a

Cross edges

d

b

e

c

a

19 / 20

Edge classification

1 Edge (u, v) is a tree edge if v was first discovered by exploring edge(u, v).

2 Edge (u, v) is a back edge if vertex u is connected to an ancestor v .

3 Edge (u, v) is a forward edge if vertex u is connected to adescendant v .

4 All other edges are cross edges

20 / 20