cse 373 graph traversal
play

CSE 373: Graph traversal Michael Lee Friday, Feb 16, 2018 1 Goal: - PowerPoint PPT Presentation

CSE 373: Graph traversal Michael Lee Friday, Feb 16, 2018 1 Goal: How do we traverse graphs? Todays goal: how do we traverse graphs? Idea 1: Just get a list of the vertices and loop over them Problem: What if we want to traverse graphs


  1. Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice For each node, check each edge to see if we should add to Breadth-fjrst traversal, core idea: We visit each node once. 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to 4

  2. Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice For each node, check each edge to see if we should add to Breadth-fjrst traversal, core idea: 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to 4 ◮ We visit each node once.

  3. Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice 4 Breadth-fjrst traversal, core idea: 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to ◮ We visit each node once. ◮ For each node, check each edge to see if we should add to

  4. Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, 4 Breadth-fjrst traversal, core idea: 4. Runtime: 3. Use a set to store nodes we don’t want to recheck/revisit 2. Add and remove nodes from queue until it’s empty visit 1. Use something (e.g. a queue) to keep track of every vertex to ◮ We visit each node once. ◮ For each node, check each edge to see if we should add to ◮ So we check each edge at most twice

  5. Breadth-fjrst search (BFS) Breadth-fjrst traversal, core idea: 1. Use something (e.g. a queue) to keep track of every vertex to visit 2. Add and remove nodes from queue until it’s empty 3. Use a set to store nodes we don’t want to recheck/revisit 4. Runtime: queue 4 ◮ We visit each node once. ◮ For each node, check each edge to see if we should add to ◮ So we check each edge at most twice So, O ( | V | + 2 | E | ) , which simplifjes to O ( | V | + | E | ) .

  6. Breadth-fjrst search (BFS) Pseudocode: 5 search(v): visited = empty set queue.enqueue(v) visited.add(v) while (queue is not empty): curr = queue.dequeue() for (w : v.neighbors()): if (w not in visited): queue.enqueue(w) visited.add(curr)

  7. An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 6

  8. An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 6

  9. An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 6

  10. An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 6

  11. An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 6

  12. An interesting property... Note: We visited the nodes in “rings” – maintained a gradually growing “frontier” of nodes. a b d c e f g h i j 6

  13. An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 7

  14. An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 7

  15. An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 7

  16. An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 7

  17. An interesting property... What does this look like for trees? The algorithm traverses the width, or “breadth” of the tree 7

  18. search(v): search(v): visited = empty set visited = empty set stack.push(v) queue.enqueue(v) visited.add(v) visited.add(v) while (stack is not empty): while (queue is not empty): curr = stack.pop() curr = queue.dequeue() visited.add(curr) for (w : v.neighbors()): for (w : v.neighbors()): if (w not in visited): if (w not in visited): queue.enqueue(w) stack.push(w) visited.add(curr) visited.add(v) Depth-fjrst search (DFS) The DFS algorithm: Question: Why a queue? Can we use other data structures? The BFS algorithm: and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends 8

  19. search(v): search(v): visited = empty set visited = empty set stack.push(v) queue.enqueue(v) visited.add(v) visited.add(v) while (stack is not empty): while (queue is not empty): curr = stack.pop() curr = queue.dequeue() visited.add(curr) for (w : v.neighbors()): for (w : v.neighbors()): if (w not in visited): if (w not in visited): queue.enqueue(w) stack.push(w) visited.add(curr) visited.add(v) Depth-fjrst search (DFS) The DFS algorithm: Question: Why a queue? Can we use other data structures? The BFS algorithm: and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends 8

  20. search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(v) Depth-fjrst search (DFS) The DFS algorithm: 8 The BFS algorithm: Question: Why a queue? Can we use other data structures? and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends search(v): visited = empty set queue.enqueue(v) visited.add(v) while (queue is not empty): curr = queue.dequeue() for (w : v.neighbors()): if (w not in visited): queue.enqueue(w) visited.add(curr)

  21. Depth-fjrst search (DFS) Question: Why a queue? Can we use other data structures? The DFS algorithm: 8 The BFS algorithm: and removes works! For example, what if we try using a stack? Answer: Yes! Any kind of list-like thing that supports appends search(v): search(v): visited = empty set visited = empty set stack.push(v) queue.enqueue(v) visited.add(v) visited.add(v) while (stack is not empty): while (queue is not empty): curr = stack.pop() curr = queue.dequeue() visited.add(curr) for (w : v.neighbors()): for (w : v.neighbors()): if (w not in visited): if (w not in visited): queue.enqueue(w) stack.push(w) visited.add(curr) visited.add(v)

  22. Depth-fjrst search (DFS) example e Visited: a, Stack: a, Current node: j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  23. Depth-fjrst search (DFS) example e Visited: a, Stack: Current node: a j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  24. Depth-fjrst search (DFS) example e Visited: a, b, d, Stack: b, d, Current node: a j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  25. Depth-fjrst search (DFS) example e Visited: a, b, d, Stack: b, Current node: d j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  26. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, Stack: b, e, f, g, Current node: d j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  27. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, Stack: b, e, f, Current node: g j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  28. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, Stack: b, e, f, h, i, Current node: g j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  29. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, Stack: b, e, f, h, Current node: i j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  30. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, Stack: b, e, f, Current node: h j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  31. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, Stack: b, e, Current node: f j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  32. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, Stack: b, e, Current node: e j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  33. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: b, e, c, Current node: e j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  34. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: b, Current node: c j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  35. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: Current node: b j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  36. Depth-fjrst search (DFS) example e Visited: a, b, d, e, f, g, h, i, e, c, Stack: Current node: j c i h g f d b a 9 search(v): visited = empty set stack.push(v) while (stack is not empty): curr = stack.pop() visited.add(curr) for (w : v.neighbors()): if (w not in visited): stack.push(w)

  37. search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(curr) Depth-fjrst search (DFS) Depth-fjrst traversal, core idea: Pseudocode: for same reasons as BFS E V 2. Runtime: also everything the same. 1. Instead of using a queue, use a stack. Otherwise, keep 10

  38. search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(curr) Depth-fjrst search (DFS) Depth-fjrst traversal, core idea: Pseudocode: everything the same. 1. Instead of using a queue, use a stack. Otherwise, keep 10 2. Runtime: also O ( | V | + | E | ) for same reasons as BFS

  39. Depth-fjrst search (DFS) Pseudocode: Depth-fjrst traversal, core idea: 10 everything the same. 1. Instead of using a queue, use a stack. Otherwise, keep 2. Runtime: also O ( | V | + | E | ) for same reasons as BFS search(v): visited = empty set stack.push(v) visited.add(v) while (stack is not empty): curr = stack.pop() for (w : v.neighbors()): if (w not in visited): stack.push(w) visited.add(curr)

  40. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  41. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  42. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  43. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  44. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  45. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  46. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  47. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  48. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  49. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  50. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  51. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  52. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  53. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  54. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  55. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  56. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  57. An interesting property... Note: Rather the growing the node in “rings”, we randomly wandered through the graph until we got stuck, then “backtracked”. a b d c e f g h i j 11

  58. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  59. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  60. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  61. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  62. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  63. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  64. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  65. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  66. An interesting property... What does this look like for trees? The algorithm traverses to the bottom fjrst: it prioritizes the “depth” of the tree Note: rest of algorithm omitted 12

  67. Compare and contrast Question: When do we use BFS vs DFS? Related question: How much memory does BFS and DFS use in the worst case? BFS: V – what if every node is connected to the start? DFS: V – what if the nodes are arranged like a linked list? So, in the worst case, BFS and DFS both have the same worst-case runtime and memory usage. They only difger in what order they visit the nodes. 13

  68. Compare and contrast Question: When do we use BFS vs DFS? Related question: How much memory does BFS and DFS use in the worst case? V – what if every node is connected to the start? V – what if the nodes are arranged like a linked list? So, in the worst case, BFS and DFS both have the same worst-case runtime and memory usage. They only difger in what order they visit the nodes. 13 ◮ BFS: ◮ DFS:

  69. Compare and contrast Question: When do we use BFS vs DFS? Related question: How much memory does BFS and DFS use in the worst case? list? So, in the worst case, BFS and DFS both have the same worst-case runtime and memory usage. They only difger in what order they visit the nodes. 13 ◮ BFS: O ( | V | ) – what if every node is connected to the start? ◮ DFS: O ( | V | ) – what if the nodes are arranged like a linked

  70. Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? BFS: “width” of tree num leaves DFS: height For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 14

  71. Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? BFS: “width” of tree num leaves DFS: height For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 14

  72. Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? “width” of tree num leaves height For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 14 ◮ BFS: ◮ DFS:

  73. Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? For graphs: Use BFS if graph is “narrow”, or if solution is “near” start Use DFS if graph is “wide” In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 14 ◮ BFS: O ( “width” of tree ) = O ( num leaves ) ◮ DFS: O ( height )

  74. Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? For graphs: In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 14 ◮ BFS: O ( “width” of tree ) = O ( num leaves ) ◮ DFS: O ( height ) ◮ Use BFS if graph is “narrow”, or if solution is “near” start ◮ Use DFS if graph is “wide”

  75. Compare and contrast How much memory does BFS and DFS use in the average case? Related question: how much memory do they use when we want to traverse a tree? For graphs: In practice, graphs are often large/very wide, so DFS is often a good default choice. (It’s also possible to implement DFS recursively!) 14 ◮ BFS: O ( “width” of tree ) = O ( num leaves ) ◮ DFS: O ( height ) ◮ Use BFS if graph is “narrow”, or if solution is “near” start ◮ Use DFS if graph is “wide”

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend