Algorithm Design and Analysis (ADA) 242-535, Semester 1 2014-2015 9. Graph Search • Objective o describe and compare depth-first and breadthfirst graph searching, and look at the creation of spanning trees 242-535 ADA: 9. Graph Search 1 Overview 1. Graph Searching 2. Depth First Search (DFS) 3. Uses of DFS o cycle detection, reachability, topological sort 4. Breadth-first Search (BFS) 5. DFS vs. BFS 6. IP Multicasting 242-535 ADA: 9. Graph Search 2 1. Graph Searching • Given: a graph G = (V, E), directed or undirected • Goal: visit every vertex • Often the end result is a tree built over the graph o called a spanning tree • it visits every vertex, but not necessarily every edge o Pick any vertex as the root o Choose certain edges to produce a tree o Note: we might build a forest if the graph is not connected 242-535 ADA: 9. Graph Search 3 Example search then build a spanning tree (or trees) 242-535 ADA: 9. Graph Search 4 2. Depth First Search (DFS) • DFS is “depth first” because it always fully explores down a path away from a vertex v before it looks at other paths leaving v. • Crucial DFS properties: • uses recursion: essential for graph structures • choice: at a vertex there may be a choice of several edges to follow to the next vertex • backtracking: "return to where you came from" • avoid cycles by grouping vertices into visited and unvisited 242-535 ADA: 9. Graph Search 5 Directed Graph Example a DFS works with directed and undirected graphs. b d e f c Graph G 242-535 ADA: 9. Graph Search 6 Data Structures • enum MARKTYPE {VISITED, UNVISITED}; struct cell { /* adj. list */ NODE nodeName; struct cell *next; }; typedef struct cell *LIST; struct graph { enum MARKTYPE mark; LIST successors; }; typedef struct graph GRAPH[NUMNODES]; 242-535 ADA: 9. Graph Search 7 The dfs() Function void dfs(NODE u, GRAPH G) // recursively search G, starting from u { LIST p; // runs down adj. list of u NODE v; // node in cell that p points at G[u].mark = VISITED; // visited u p = G[u].successors; while (p != NULL) { // visit u’s succ’s v = p->nodeName; if (G[v].mark == UNVISITED) dfs(v, G); // visit v p = p->next; } } 242-535 ADA: 9. Graph Search 8 Calling dfs(a,G) • Call d(a) d(a)-d(b) d(a)-d(b)-d(c) d(a)-d(b)-d(d) d(a)-d(b)-d(d)-d(e) 242-535 ADA: 9. Graph Search call it d(a) for short Visited {a} {a,b} {a,b,c} Skip b, return to d(b) {a,b,c,d} Skip c {a,b,c,d,e} Skip c, return to d(d) continued 9 d(a)-d(b)-d(d)-d(f) {a,b,c,d,e,f} Skip c, return to d(d) d(a)-d(b)-d(d) {a,b,c,d,e,f} Return to d(b) d(a)-d(b) {a,b,c,d,e,f} Return to d(a) d(a) {a,b,c,d,e,f} Skip d, return 242-535 ADA: 9. Graph Search 10 DFS Spanning Tree • Since nodes are marked, the graph is searched as if it were a tree: A spanning tree is a subgraph of a graph G which contains all the verticies of G. a/1 b/2 c/3 d/4 e/5 f/6 c 242-535 ADA: 9. Graph Search 11 Example 2 a a b b c d c d e f e f h g DFS h g the tree generated by DFS is drawn with thick lines 242-535 ADA: 9. Graph Search 12 dfs() Running Time • The time taken to search from a node is proportional to the no. of successors of that node. • Total search time for all nodes = O(|V|) Total search time for all successors = time to search all edges = O(|E|) • Total running time is O(V + E) 242-535 ADA: 9. Graph Search continued 13 • If the graph is dense, E >> V (E approaches V2) then the O(V) term can be ignored o in that case, the total running time = O(E) or O(V2) 242-535 ADA: 9. Graph Search 14 3. Uses of DFS • Finding cycles in a graph o e.g. for finding recursion in a call graph • Searching complex locations, such as mazes • Reachability detection o i.e. can a vertex v be reached from vertex u? o useful for e-mail routing; path finding • Strong connectivity • Topological sorting 242-535 ADA: 9. Graph Search continued 15 Maze Traversal • The DFS algorithm is similar to a classic strategy for exploring a maze o mark each intersection, corner and dead end (vertex) as visited o mark each corridor (edge ) traversed o keep track of the path back to the previous branch points Graphs 242-535 ADA: 9. Graph Search 16 16 Reachability • DFS tree rooted at v: what are the vertices reachable from v via directed paths? E D C E D C A F E A start at C D B C A F B start at B Strong Connectivity • Each vertex can reach all other vertices a g c d e f Graphs b 18 Strong Connectivity Algorithm • Pick a vertex v in G. • Perform a DFS from v in G. a G: g c o If there’s a vertex not visited, print “no”. d e • Let G’ be G with edges reversed. • Perform a DFS from v in G’. o If there’s a vertex not visited, print “no” a G’: g c • If the algorithm gets here, print “yes”. d e f • Running time: O(V+E). b f b 19 Strongly Connected Components • List all the subgraphs where each vertex can reach all the other vertices in that subgraph. • Can also be done in O(V+E) time using DFS. a g c {a,c,g} d e f b {f,d,e,b} 20 Topological Sort • Topological sort of a directed acyclic graph (DAG): o linearly order all the vertices in a graph G such that vertex u comes before vertex v if edge (u, v) G o a DAG is a directed graph with no directed cycles 242-535 ADA: 9. Graph Search 21 Example: Getting Dressed Underwear Socks Watch Trousers Shoes Shirt Belt Tie one topological sort (not unique) Jacket Socks Underwear Trousers 242-535 ADA: 9. Graph Search Shoes Watch Shirt Belt Tie Jacket 22 Topological Sort Algorithm Topological-Sort() { Run DFS; When a vertex is finished, output it; Vertices are output in reverse topological order; } • Time: O(V+E) 242-535 ADA: 9. Graph Search 23 4. Breadth-first Search (BFS) • Process all the verticies at a given level before moving to the next level. • Example graph G (again): a b c d e f h g 242-535 ADA: 9. Graph Search 24 Informal Algorithm • 1) Put the verticies into an ordering o e.g. {a, b, c, d, e, f, g, h} • 2) Select a vertex, add it to the spanning tree T: e.g. a • 3) Add to T all edges (a,X) and X verticies that do not create a cycle in T o i.e. (a,b), (a,c), (a,g) T = {a, b, c, g} a b 242-535 ADA: 9. Graph Search c continued g 25 • Repeat step 3 on the verticies just added, these are on level 1 o i.e. b: add (b,d) c: add (c,e) g: nothing T = {a,b,c,d,e} level 1 a b c d e g • Repeat step 3 on the verticies just added, these are on level 2 o i.e. d: add (d,f) e: nothing T = {a,b,c,d,e,f} a level 2 242-535 ADA: 9. Graph Search continued b c d e f g 26 • Repeat step 3 on the verticies just added, these are on level 3 o i.e. f: add (f,h) T = {a,b,c,d,e,f,h} level 3 a b c d e g f h • Repeat step 3 on the verticies just added, these are on level 4 o i.e. h: nothing, so stop 242-535 ADA: 9. Graph Search continued 27 • Resulting spanning tree: a b c d e f a different spanning tree from the earlier solution h g 242-535 ADA: 9. Graph Search 28 Example 2 242-535 ADA: 9. Graph Search 29 Algorithm Graphicallypre-built start node 242-535 ADA: 9. Graph Search adjency list 30 242-535 ADA: 9. Graph Search 31 242-535 ADA: 9. Graph Search 32 BFS Code boolean marked[]; int edgeTo[]; // visited this vertex? // vertex number going to this vertex void bfs(Graph graph, int start) { Queue q = new Queue(); marked[start] = true; q.add(start); // add to end of queue while (!q.isEmpty()) { int v = q.remove(); // get from start of queue for (int w : graph.adjacentTo(v)) // v --> w if (!marked[w]) { edgeTo[w] = v; // save last edge on a shortest path marked[w] = true; q.add(w); // add to end of queue } } } // end of bfs() 242-535 ADA: 9. Graph Search 33 5. DFS vs. BFS Applications Spanning forest, connected components, paths, cycles DFS BFS Shortest paths Biconnected components see part 11 242-535 ADA: 9. Graph Search 34 DFS and BFS as Maze Explorers • DFS is like one person exploring a maze o do down a path to the end, get to a dead-end, backtrack, and try a different path • BFS is like a group of searchers fanning out in all directions, each unrolling a ball of string. o at a branch point, the searchers split up to explore all the branches at once o if two groups meet up, they join forces (using the ball of string of the group that got there first) o the group that gets to the exit first has found the shortest path 242-535 ADA: 9. Graph Search 35 BFS Maze Graphically 242-535 ADA: 9. Graph Search Also called flood filling; used in paint software. 36 Sequential / Parallel • The BFS "fanning out" algorithm is best implemented in a parallel language, where each "group of explorers" is a separate thread of execution. o e.g. use fork and join in Java • The earlier implementation uses a queue to implement the fanning out as a sequential algorithm. • DFS is inherently a sequential algorithm. 242-535 ADA: 9. Graph Search 37 6. IP Multicasting • A network of computers and routers: source computer router 242-535 ADA: 9. Graph Search continued 38 • How can a packet (message) be sent from the source computer to every other computer? • The inefficient way is to use broadcasting o send a copy along every link, and have each router do the same o each router and computer will receive many copies of the same packet o loops may mean the packet never disappears! 242-535 ADA: 9. Graph Search continued 39 • IP multicasting is an efficient solution o send a single packet to one router o have the router send it to 1 or more routers in such a way that a computer never receives the packet more than once • This behaviour can be represented by a spanning tree. • Can use either BFS or DFS, but BFS will usually produce shorter paths o i.e. BFS is a better choice 242-535 ADA: 9. Graph Search continued 40 • One spanning tree for the network: source computer the tree is drawn with thick lines router 242-535 ADA: 9. Graph Search 41