More applications of DFS and BFS Tyler Moore CSE 3353, SMU, Dallas, - - PDF document

more applications of dfs and bfs
SMART_READER_LITE
LIVE PREVIEW

More applications of DFS and BFS Tyler Moore CSE 3353, SMU, Dallas, - - PDF document

Notes More applications of DFS and BFS Tyler Moore CSE 3353, SMU, Dallas, TX March 21, 2013 Reminder: HW3 due next Tues Mar 26 Notes Im holding extra office hours from 4-5:30pm Monday, March 26 Come see me if you have questions 2 / 24


slide-1
SLIDE 1

More applications of DFS and BFS

Tyler Moore

CSE 3353, SMU, Dallas, TX

March 21, 2013

Reminder: HW3 due next Tues Mar 26

I’m holding extra office hours from 4-5:30pm Monday, March 26 Come see me if you have questions

2 / 24

First, a correction from last time

Back edges can be made to a processed node Let’s take a more careful look at the definition of edge types.

3 / 24

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

4 / 24

Notes Notes Notes Notes

slide-2
SLIDE 2

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 a

descendant v.

4 All other edges are cross edges

See board for examples

5 / 24

Some observations about edge types

In an undirected graph, the DFS tree has only tree edges and back edges What about for a directed graph? Exercise 1: make a directed graph with a forward edge in the DFS tree Exercise 2: make a directed graph with a cross edge in the DFS tree What can you say about the edges in a BFS tree for an undirected graph? What can you say about the edges in a BFS tree for an directed graph?

6 / 24

What is the running time of DFS?

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 y S . add ( s ) # We ’ ve v i s i t e d s for u in G[ s ] : # Explore neighbors i f u in S : continue# Already v i s i t e d : Skip r e c d f s (G, u , S) # New : Explore 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 / 24

What is the running time of DFS? Θ(V + E)

Undirected Graph a b c d e f

Discovered:

a a b b c c d d e e f f

Processed:

e e d d c c b b f f a a Depth-First Search Tree a b c d e f

1 2 3 4 7 5 6

8 / 24

Notes Notes Notes Notes

slide-3
SLIDE 3

Connected Components

A connected component of an undirected graph is a maximal set of vertices such that there is a path between every pair of vertices a b c d e f g Exercise: Explain in English how you could find all connected components of a graph using breadth-first search.

9 / 24

Code to find connected components

def find components (G ) : v e r t i c e s = G. keys ( ) u = v e r t i c e s [ 0 ] #p i c k s t a r t i n g v e r t e x components =[] #l i s t

  • f

components S =s e t ( ) #d i s c o v e r e d v e r t i c e s while True : cc = l i s t ( b f s (G, u ) ) #do BFS from v e r t e x S . update ( cc ) #update d i s c o v e r e d components . append ( cc )#update component l i s t f o r v i n cc : #remove component ’ s v e r t i c e s v e r t i c e s . remove ( v )#from s e t to check i f not v e r t i c e s : break u = v e r t i c e s [ 0 ] #p i c k the next u n d i s c o v e r e d v e r t e x return components > > > find components (G) [ [ ’ a ’ , ’ g ’ , ’ f ’ ] , [ ’ c ’ , ’ e ’ , ’ d ’ ] , [ ’ b ’ ] ]

11 / 24

Strongly connected components

A strongly connected component is the maximal subset of a graph with a directed path between any two vertices A B C a b c d e f g h i To find an SCC, we first need to understand how to do a topological sort

12 / 24

Application of topological sorting

Figure: Directed acyclic graph for clothing dependencies Figure: Topological sort of clothes

13 / 24

Notes Notes Notes Notes

slide-4
SLIDE 4

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

Undirected Graph a b c d e f

Discovered:

a a b b c c d d e e f f

Processed:

e e d d c c b b f f a a Depth-First Search Tree a b c d e f

1 2 3 4 7 5 6

/

14 / 24

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 to be able to verify if node A is encountered before node B, etc. We add one timestamp for when a node is discovered (during preorder processing) and another timestamp for when a node is processed (during postorder processing)

15 / 24

Code for depth-first timestamps

def dfs (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 y d [ s ] = t ; t += 1 # Set d i s c o v e r time S . add ( s ) # We ’ ve v i s i t e d s for u in G[ s ] : # Explore neighbors i f u in S : continue# Already v i s i t e d . Skip t = dfs (G, u , d , f , S , t ) # Recurse ; update timestamp f [ s ] = t ; t += 1 # Set f i n i s h time return t # Return timestamp

pre : a pre : b pre : c pre : d pre : e − − − − − − post : e − − − − − − post : d − − − − − − post : c − − − − − − post : b pre : f − − − − − − post : f − − − − − − post : a [ ’ a ’ , ’ c ’ , ’ b ’ , ’ e ’ , ’ d ’ , ’ f ’ ] 16 / 24

Topological sorting on DAGs

Directed Acyclic Graph a b c d e f g

Discovered:

g g f f e e d d a a c c b b

Processed:

d d e e f f c c b b a a g g Depth-First Search Tree g f e d a c b

1 2 3 4 5 8 6 7 10 11 Topological sort: g a b c f e d

17 / 24

Notes Notes Notes Notes

slide-5
SLIDE 5

Using depth-first timestamps for topological sorting

> > > f ={} > > > d={} > > > dfs (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} > > > f ={} > > > d={} > > > dfs (DAG, ’ g ’ ,d , f ) 14 > > > t o p s o r t = [ k for k , v in s o r t e d ( f . i t e r i t e m s () , key=lambda(k , v ) : v ) ] > > > t o p s o r t . r e v e r s e () > > > t o p s o r t [ ’ g ’ , ’ a ’ , ’b ’ , ’ c ’ , ’ f ’ , ’ e ’ , ’ d ’ ]

18 / 24

Topological sort using custom DFS (iterative)

def i t e r d f s t o p s o r t (G) : S , Q, r e s = s e t () , [ ] , [ ] # V i s i t e d −s e t and queue for u in G: #Cover e n t i r e graph

  • Q. append (u)

while Q: # Planned nodes l e f t ? v = Q. pop () # Get one i f u in S : continue S . add ( v ) # We ’ ve v i s i t e d i t now

  • Q. extend (G[ v ] )

r e s . append (u) # Postorder process : add node when f i n i s h e d r e s . r e v e r s e () return r e s

19 / 24

Topological sort using custom DFS (recursive)

def d f s t o p s o r t (G) : S , r e s = s e t () , [ ] # H i s t o r y and r e s u l t def r e c u r s e (u ) : # T r a v e r s a l s u b r o u t i n e i f u in S : return# Ignore v i s i t e d nodes S . add (u) # Otherwise : Add to h i s t o r y for v in G[ u ] : r e c u r s e ( v ) # Recurse through neighbors r e s . append (u) # F i n i s h e d with u : Append i t for u in G: r e c u r s e (u) # Cover e n t i r e graph r e s . r e v e r s e () # I t ’ s a l l backward so f a r return r e s

20 / 24

Strongly connected components

A B C a b c d e f g h i A B C Are supernodes in a DAG?

21 / 24

Notes Notes Notes Notes

slide-6
SLIDE 6

Strongly connected components

What if we transpose all edges? A B C a b c d e f g h i SCCs don’t change A B C Supernodes still in DAG

21 / 24

Kosaraju’s algorithm for finding SCCs

1 Get a topological sort of all vertices 2 Transpose the graph (reverse all edges) 3 Traverse the graph in topologically sorted order, adding an SCC each

time a dead end is reached.

22 / 24

Kosaraju’s Algorithm for Finding Strongly Connected Components

  • 1. Get a topological sort of all vertices

a b c d e f g h i topsort: [a, b, e, f, g, c, d, h, i] seen: {} sccs: []

23 / 24

Kosaraju’s Algorithm for Finding Strongly Connected Components

  • 2. Reverse all edges

a b c d e f g h i topsort: [a, b, e, f, g, c, d, h, i] seen: {} sccs: []

23 / 24

Notes Notes Notes Notes

slide-7
SLIDE 7

Kosaraju’s Algorithm for Finding Strongly Connected Components

  • 3. Traverse the graph in topologically sorted order, adding an SCC each

time a dead end is reached. 1st SCC a b c d e f g h i topsort: [a, b, e, f, g, c, d, h, i] seen: {a,b,c,d} sccs: [{a,b,c,d}]

23 / 24

Kosaraju’s Algorithm for Finding Strongly Connected Components

  • 3. Traverse the graph in topologically sorted order, adding an SCC each

time a dead end is reached. 1st SCC 2nd SCC a b c d e f g h i topsort: [a, b, e, f, g, c, d, h, i] seen: {a,b,c,d,e,g,f} sccs: [{a,b,c,d},{e,g,f}]

23 / 24

Kosaraju’s Algorithm for Finding Strongly Connected Components

  • 3. Traverse the graph in topologically sorted order, adding an SCC each

time a dead end is reached. 1st SCC 2nd SCC 3rd SCC a b c d e f g h i topsort: [a, b, e, f, g, c, d, h, i] seen: {a,b,c,d,e,g,f,h,i} sccs: [{a,b,c,d},{e,g,f},{h,i}]

23 / 24

Code for Kosaraju’s SCC Algorithm

def t r (G) : # Transpose ( rev . edges

  • f ) G

GT = {} for u in G: GT[ u ] = s e t () # Get a l l the nodes in there for u in G: for v in G[ u ] : GT[ v ] . add (u) # Add a l l r e v e r s e edges return GT def scc (G) : GT = t r (G) # Get the transposed graph sccs , seen = [ ] , s e t () for u in d f s t o p s o r t (G) : # DFS s t a r t i n g p o i n t s i f u in seen : continue # Ignore covered nodes C = walk (GT, u , seen ) # Don ’ t go ”backward” ( seen ) seen . update (C) # We ’ ve now seen C sccs . append (C) # Another SCC found return sccs

24 / 24

Notes Notes Notes Notes