col351 slides for lecture components 06 and 07
play

COL351: Slides for Lecture Components 06 and 07 Thanks to Miles - PowerPoint PPT Presentation

COL351: Slides for Lecture Components 06 and 07 Thanks to Miles Jones, Russell Impagliazzo, and Sanjoy Dasgupta at UCSD for these slides. Algorithm Mining Algorithms designed for one problem are often usable for a number of other


  1. COL351: Slides for Lecture Components 06 and 07 Thanks to Miles Jones, Russell Impagliazzo, and Sanjoy Dasgupta at UCSD for these slides.

  2. Algorithm Mining • Algorithms designed for one problem are often usable for a number of other computational tasks, some of which seem unrelated to the original goal • Today, we are going to look at how to use the depth-first search algorithm to solve a variety of graph problems

  3. Algorithm Mining techniques • Deeper Analysis: What else does the algorithm already give us? • Augmentation: What additional information could we glean just by keeping track of the progress of the algorithm? • Modification: How can we use the same idea to solve new problems in a similar way? • Reduction: How can we use the algorithm as a black box to solve new problems?

  4. Graph Reachability and DFS • Graph reachability: Given a directed graph 𝐻 , and a starting vertex 𝑤 , return an array that specifies for each vertex 𝑣 whether 𝑣 is reachable from 𝑤 • Depth-First Search (DFS): An efficient algorithm for Graph reachability • Breadth-First Search (BFS): Another efficient algorithm for Graph reachability.

  5. DFS as recursion • procedure explore( 𝐻, 𝑤 ) • Input: graph 𝐻 = (𝑊, 𝐹) ; node 𝑤 in 𝑊 output: • Output: array visited[ 𝑣 ] • 1. visited[ 𝑤 ] = true • 2. for each edge 𝑤, 𝑣 ∈ 𝐹 do: if not visited[ 𝑣 ]: explore( 𝐻, 𝑣 ) •

  6. Key Points of DFS • No matter how the recursions are nested, for each vertex 𝑣 , we only run explore( 𝐻, 𝑣 ) ONCE, because after that, it is marked visited. (We need this for termination and efficiency) • On the other hand, we discover a path to a new destination, we always explore all new vertices reachable (We need this for correctness, to guarantee that we find ALL the reachable vertices)

  7. DFS as iterative algorithm REACHABILITY: procedure explore ( 𝐻 : directed graph, 𝑤 : vertex) Initialize array visited[ 𝑣 ] to False Initialize stack of vertices 𝐺 , PUSH 𝑤 ; Visited[ 𝑤 ]=True; While 𝐺 is not empty: 𝑤 =Pop; For each neighbor 𝑣 of 𝑤 (in reverse order): If not visited[ 𝑣 ]: procedure explore ( 𝐻 = (𝑊, 𝐹), 𝑡 ) Push 𝑣 ; visited[ 𝑣 ] = True; visited( 𝑡 )=true for each edge ( 𝑡, 𝑣 ): Return visited if not visited( 𝑣 ): explore( 𝐻, 𝑣 )

  8. DFS on Directed Graphs A E G C F B H D F = A

  9. DFS on Directed Graphs A E G C F B H D F= A. Pop A. Neighbors of A = (C) Push C, visited C == True F= C

  10. DFS on Directed Graphs A E G C F B H D F= C. Pop C. Neighbors of C = (F,E,B) Push F, Push E, Push B, F= B, E, F

  11. DFS on Directed Graphs A E G C F B H D F= B,E,F. Pop B. Neighbors of B = (D,A) Push D , F= E, F, D

  12. DFS on Directed Graphs A E G C F B H D F= E,F, D Pop E. Neighbors of E = (H,G,F) Push G, H F= F, D, G, H. Pop, Pop, Pop, Pop

  13. Running time of DFS procedure explore ( 𝐻 = (𝑊, 𝐹), 𝑡 ) visited( 𝑡 )=true for each edge ( 𝑡, 𝑣 ): if not visited( 𝑣 ): explore( 𝐻, 𝑣 )

  14. DFS as iterative algorithm REACHABILITY: procedure explore ( 𝐻 : directed graph, 𝑤 : vertex) Initialize array visited[ 𝑣 ] to False. O(|V|) Initialize stack of vertices 𝐺 , PUSH 𝑤 ; Visited[ 𝑤 ]=True; O(1) While 𝐺 is not empty: done at most |V| times, once per v 𝑤 =Pop; For each neighbor 𝑣 of 𝑤 (in reverse order): 𝑃(1 + deg(𝑤)) = 𝑃(|𝑊|) If not visited[ 𝑣 ]: Push 𝑣 ; visited[ 𝑣 ] == True; Return visited. Tighter : Loop runs once for each v, 𝑃(1 + deg(𝑤)) time on that loop. So total time at most : 𝑃(∑ ! 1 + deg 𝑤 ) = 𝑃( 𝑊 + 𝐹 )

  15. Complete DFS • DFS actually just costs O(number of reachable nodes + number of reachable edges ). Parts of the graph that weren’t found don’t cost either. • So, still in total O(|V|+|E|) time, we can run also keep on running explore from undiscovered vertices, until we’ve found the whole graph. We usually keep track of which iteration each vertex was discovered in. • Alternative viewpoint: Add a new vertex with edges to all vertices. Run DFS from the new vertex.

  16. All reachable vertices, not all paths • While DFS finds all the reachable vertices, it doesn’t consider all paths between them. No feasible algorithm could. A A A A n 1 3 2 How many paths from A1 to An?

  17. All reachable vertices, not all paths • While DFS finds all the reachable vertices, it doesn’t consider all paths between them. No feasible algorithm could. A A A A n 1 3 2 2 "#$ paths from A1 to An

  18. Finding paths: the DFS tree • After the DFS, we know which vertices are reachable, but not how to get there How long could a path in a graph be? How about a simple path? How many paths do we have to find?

  19. Finding paths: the DFS tree • After the DFS, we know which vertices are reachable, but not how to get there • We have up to |V|-1 paths to find, and each path can be up to length |V|.

  20. Synergy • After the DFS, we know which vertices are reachable, but not how to get there • We have up to |V|-1 paths to find, and each path can be up to length |V|. • Sometimes, doing something similar many times costs less than doing it from scratch each time. For DFS, the paths overlap, and form a |V|-1 edge tree

  21. DFS augmented to create DFS tree • procedure explore( 𝐻, 𝑤 ) • Input: graph 𝐻 = (𝑊, 𝐹) ; node 𝑤 in 𝑊 output: • Output: array visited[ 𝑣 ]; parent[ 𝑣 ] • 1. visited[ 𝑤 ] = true 2. for each edge 𝑤, 𝑣 ∈ 𝐹 do: • if not visited[ 𝑣 ]: parent[ 𝑣 ]= 𝑤 ; explore( 𝐻, 𝑣 ); •

  22. keeping track of paths

  23. DFS augmtd. with pre, post numbers • procedure explore( 𝐻, 𝑤 ) • Input: graph 𝐻 = (𝑊, 𝐹) ; node 𝑤 ∈ 𝑊 output: count starts at 1 • Output: array visited[ 𝑣 ]; parent[ 𝑣 ]; pre[ 𝑣 ]; post[ 𝑣 ] • 1. visited[ 𝑤 ] = true ; • 2. for each edge 𝑤, 𝑣 ∈ 𝐹 do: • if not visited[ 𝑣 ]: parent[ 𝑣 ]= 𝑤 ; pre[ 𝑣 ]=count; count++; explore( 𝐻, 𝑣 ); • 3. post[ 𝑤 ] = count, count++

  24. Depth first search procedure DFS(G) procedure DFS(G) procedure previsit(v) cc = 0 cc = 0 pre(v)=clock clock = 1 for each vertex v: clock++ for each vertex v: visited(v) = false visited(v) = false for each vertex v: for each vertex v: if not visited(v): procedure post visit(v) if not visited(v): cc++ post(v)=clock cc++ explore(G,v) clock++ explore(G,v)

  25. keeping track of paths

  26. Inferring relative position in tree • 𝑣 is below 𝑤 in the DFS tree iff pre( 𝑤 ) < pre( 𝑣 ) and post( 𝑣 ) < post( 𝑤 ). • In this case, an edge from 𝒗 to 𝒘 creates a cycle • 𝑣 is to the right of 𝑤 iff pre( 𝑤 ) < pre( 𝑣 ) and post( 𝑤 ) < post( 𝑣 )

  27. Edge types (directed graph) • Tree edge: solid edge included in the DFS output tree • Back edge: leads to an ancestor • Forward edge: leads to a descendent • Cross edge: leads to neither anc. or des.: always from right to left

  28. DFS on Directed Graphs 1 16 A A A 2 15 C C C A A A C C C E E G G G E 3 14 6 7 B B B E E E B B B D D D F F H H H F 4 8 5 9 13 10 D D D G F F F G G 12 11 H H H

  29. Edge types and pre/post numbers The different types of edges can be determined from the pre/post numbers for the edge (𝑣, 𝑤) • (𝑣, 𝑤) is a tree/forward edge then 𝑞𝑠𝑓 𝑣 < 𝑞𝑠𝑓 𝑤 < 𝑞𝑝𝑡𝑢 𝑤 < 𝑞𝑝𝑡𝑢(𝑣) • (𝑣, 𝑤) is a back edge then 𝑞𝑠𝑓 𝑤 < 𝑞𝑠𝑓 𝑣 < 𝑞𝑝𝑡𝑢 𝑣 < 𝑞𝑝𝑡𝑢(𝑤) • (𝑣, 𝑤) is a cross edge then 𝑞𝑠𝑓 𝑤 < 𝑞𝑝𝑡𝑢 𝑤 < 𝑞𝑠𝑓 𝑣 < 𝑞𝑝𝑡𝑢(𝑣)

  30. Cycles in Directed Graphs • A cycle in a directed graph is a path that starts and ends with the same vertex 𝑤 4 → 𝑤 5 → 𝑤 6 → ⋯ → 𝑤 7 → 𝑤 4 𝐵 → 𝐷 → 𝐹 → 𝐵

  31. A directed graph has a directed cycle iff its dfs output tree has a back edge Proof: → Suppose G has a cycle: 𝑤 4 → 𝑤 5 → 𝑤 6 → ⋯ → 𝑤 7 → 𝑤 4

  32. A directed graph has a directed cycle iff its dfs output tree has a back edge Proof: → Suppose G has a cycle: 𝑤 4 → 𝑤 5 → 𝑤 6 → ⋯ → 𝑤 7 → 𝑤 4 Suppose 𝑤 4 is the first vertex to be discovered. (What does that mean about 𝑤 4 ?)

  33. A directed graph has a directed cycle iff its dfs output tree has a back edge Proof: → Suppose G has a cycle: 𝑤 4 → 𝑤 5 → 𝑤 6 → ⋯ → 𝑤 7 → 𝑤 4 Suppose 𝑤 4 is the first vertex to be discovered. (the vertex with the lowest pre-number.) All other 𝑤 8 are reachable from it and therefore, they are all descendants in the DFS tree.

  34. A directed graph has a directed cycle iff its dfs output tree has a back edge Proof: → Suppose G has a cycle: 𝑤 ! → 𝑤 " → 𝑤 # → ⋯ → 𝑤 $ → 𝑤 ! Suppose 𝑤 ! is the first vertex to be discovered. (the vertex with the lowest pre-number.) All other 𝑤 % are reachable from it and therefore, they are all descendants in the dfs tree. Therefore the edge 𝑤 $ , 𝑤 ! is a back edge.

  35. A directed graph has a directed cycle iff its dfs output tree has a back edge Proof: ← Suppose 𝑐, 𝑏 is a back edge.

Recommend


More recommend