cse 373 graph traversal
play

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

CSE 373: Graph traversal Michael Lee Friday, Feb 16, 2018 1 Warmup Warmup Given a graph, assign each node one of two colors such that no two adjacent vertices have the same color. (If its impossible to color the graph this way, your


  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 5

  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: 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 5

  3. 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 5

  4. 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 5 ◮ We visit each node once.

  5. Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, So we check each edge at most twice 5 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

  6. Breadth-fjrst search (BFS) queue E . V E , which simplifjes to V So, 5 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

  7. 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 5 ◮ 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 | ) .

  8. Breadth-fjrst search (BFS) Pseudocode: 6 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)

  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 7

  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 7

  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 7

  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 7

  13. 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 7

  14. 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 7

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

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

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

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

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

  20. 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 9

  21. 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 9

  22. 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: 9 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)

  23. Depth-fjrst search (DFS) Question: Why a queue? Can we use other data structures? The DFS algorithm: 9 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)

  24. Depth-fjrst search (DFS) example e Visited: a, Stack: a, Current node: j c i h g f d b a 10 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, Stack: Current node: a j c i h g f d b a 10 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, Stack: b, d, Current node: a j c i h g f d b a 10 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, Stack: b, Current node: d j c i h g f d b a 10 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, Stack: b, e, f, g, Current node: d j c i h g f d b a 10 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, Stack: b, e, f, Current node: g j c i h g f d b a 10 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, h, i, Current node: g j c i h g f d b a 10 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, Stack: b, e, f, h, Current node: i j c i h g f d b a 10 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, Stack: b, e, f, Current node: h j c i h g f d b a 10 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, Stack: b, e, Current node: f j c i h g f d b a 10 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, Stack: b, e, Current node: e j c i h g f d b a 10 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: b, e, c, Current node: e j c i h g f d b a 10 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: b, Current node: c j c i h g f d b a 10 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. 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 10 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)

  38. 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 10 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)

  39. 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 11

  40. 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 11 2. Runtime: also O ( | V | + | E | ) for same reasons as BFS

  41. Depth-fjrst search (DFS) Pseudocode: Depth-fjrst traversal, core idea: 11 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)

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  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 12

  58. 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 12

  59. 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 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 13

  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 13

  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 13

  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 13

  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 13

  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 13

  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 13

  67. 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 13

  68. 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 13

  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? 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. 14

  70. 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. 14 ◮ BFS: ◮ DFS:

  71. 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. 14 ◮ BFS: O ( | V | ) – what if every node is connected to the start? ◮ DFS: O ( | V | ) – what if the nodes are arranged like a linked

  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? 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!) 15

  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? 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!) 15

  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? “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!) 15 ◮ BFS: ◮ DFS:

  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: 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!) 15 ◮ BFS: O ( “width” of tree ) = O ( num leaves ) ◮ DFS: O ( height )

Recommend


More recommend