Graph Traversal Discrete Mathematics and Its Applications Baojian
Graph Traversal Discrete Mathematics and Its Applications Baojian Hua bjhua@ustc. edu. cn
BFS and DFS n BFS: breath first searching n n start from one vertex, near to far generates BFS forest n n flat DFS: depth first searching n n recursion and back-tracking generates DFS forest n narrow
“graph” ADT in C: Interface // in file “graph. h” #ifndef GRAPH_H #define GRAPH_H typedef struct graph *graph; typedef void (*ty. Visit)(poly); graph new. Graph (); void insert. Vertex (graph g, poly data); void insert. Edge (graph g, poly from, poly to); void dfs (graph g, poly start, ty. Visit visit); void bfs (graph g, poly start, ty. Visit visit); // we’d see more later … #endif
Sample Graph For BFS, associate each vertex with a “distance” property. a b c distance(v): the number of edges from the vertex “start” to vertex “v”, with distance(start)=0 d e f
Sample Graph BFS bfs (g, “a”, str. Output); a b c d e f
Sample Graph BFS bfs (g, “a”, str. Output); print a; a 0 b c d e f
Sample Graph BFS bfs (g, “a”, str. Output); print a; a 0 b 1 c d e f // a choice print b;
Sample Graph BFS bfs (g, “a”, str. Output); print a; a 0 b 1 c d 1 e f // a choice print b; print d;
Sample Graph BFS bfs (g, “a”, str. Output); print a; a 0 b 1 c d 1 e 2 f // a choice print b; print d; print e;
Sample Graph BFS bfs (g, “a”, str. Output); print a; a 0 b 1 c 0 d 1 e 2 f // a choice print b; print d; print e; // a choice print c;
Sample Graph BFS bfs (g, “a”, str. Output); print a; a 0 b 1 c 0 d 1 e 2 f 1 // a choice print b; print d; print e; // a choice print c; print f;
BFS Algorithm bfs (vertex start, ty. Visit visit){ queue q = new. Queue (); set. Distance (start, 0); //Invariant: all vertices in q have distance property en. Queue (q, start); while (q not empty) { vertex current = de. Queue (q); int dist = get. Distance (current); visit (current); for (each adjacent vertex u of “current”){ if (not visited u){ set. Distance (u, dist+1); en. Queue (q, u); } }}}
BFS Algorithm void bfs. Main (graph g, poly start, ty. Visit visit) { vertex start. V = search. Vertex (g, start); bfs (start. V, visit); for (each vertex u in graph g) if (not visited u) bfs (q, u); }
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 d Queue: a e f
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 1 print a; d 1 e Queue: a Queue: b, d f
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 1 print a; // a choice print b; d 1 e 2 Queue: a Queue: b, d Queue: d, e f
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 1 print a; // a choice print b; print d; d 1 e 2 Queue: a Queue: b, d d, e e f
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 1 print a; 0 // a choice print b; print d; print e; d 1 e 2 f Queue: a Queue: b, d d, e e Queue: c
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 1 print a; 0 // a choice print b; print d; d 1 print e; Queue: a // a choice Queue: print c; Queue: e 2 b, d d, e e f 1 Queue: c Queue: f
Sample Graph BFS // color convention: not visited, in. Queue, de. Queued bfs (g, “a”, str. Output); a b c 0 1 print a; 0 // a choice print b; print d; d 1 print e; Queue: a // a choice Queue: print c; Queue: print f; Queue: e 2 b, d d, e e f 1 Queue: c Queue: f
Sample Graph DFS Associate a “discover time” and a “finish time” with each vertex v a b c d e f with: discover (start) = 0
Sample Graph DFS dfs (g, “a”, str. Output); a b c d e f
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b c d e f
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b (1, ) c d e f // a choice print b;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b (1, ) c d e (2, ) f // a choice print b; print e;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b (1, ) c d (3, ) e (2, ) f // a choice print b; print e; print d;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b (1, ) c d (3, 4) e (2, ) f // a choice print b; print e; print d;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b (1, ) c d (3, 4) e (2, 5) f // a choice print b; print e; print d;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, ) b (1, 6) c d (3, 4) e (2, 5) f // a choice print b; print e; print d;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, 7) b (1, 6) c d (3, 4) e (2, 5) f // a choice print b; print e; print d;
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, 7) b (1, 6) c (8, ) d (3, 4) e (2, 5) f // a choice print b; print e; print d; // a choice print c
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, 7) b (1, 6) c (8, ) d (3, 4) e (2, 5) f (9, ) // a choice print b; print e; print d; // a choice print c print f
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, 7) b (1, 6) c (8, ) d (3, 4) e (2, 5) f (9, 10) // a choice print b; print e; print d; // a choice print c
Sample Graph DFS dfs (g, “a”, str. Output); print a; a (0, 7) b (1, 6) c (8, 11) d (3, 4) e (2, 5) f (9, 10) // a choice print b; print e; print d; // a choice print c
DFS Algorithm dfs (vertex start, ty. Visit visit, time) { visit (start); set. Discover (start, time++); for (each adjacent vertex u of “start”) if (not visited u) dfs (u, visit, time); set. Finish (start, time++); }
DFS Algorithm void dfs. Main (graph g, poly start, ty. Visit visit) { vertex start. V = search. Vertex (g, start); time = new. Time (); dfs (start. V, visit, time); for (each vertex u in graph g) if (not visited u) dfs (u, visit, time); }
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) print a; d dfs(a) e c f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, ) print a; c // a choice print b; d dfs(a) => dfs(b) e f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, ) print a; c // a choice print b; print e; d e (2, ) dfs(a) => dfs(b) => dfs(e) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, ) print a; c // a choice print b; print e; d (3, ) e (2, ) print d; dfs(a) => dfs(b) => dfs(e) => dfs(d) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, nat. Output); a b (0, ) (1, ) print a; c // a choice print b; print e; d (3, ) e (2, ) print d; dfs(a) => dfs(b) => dfs(e) => dfs(d) => dfs(b)? ? ? f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, ) print a; c // a choice print b; print e; d (3, 4) e (2, ) print d; dfs(a) => dfs(b) => dfs(e) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, ) print a; c // a choice print b; print e; d (3, 4) print d; dfs(a) => dfs(b) e (2, 5) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, 6) print a; c // a choice print b; print e; d (3, 4) print d; dfs(a) e (2, 5) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, 6) print a; c // a choice print b; print e; d (3, 4) e (2, 5) print d; dfs(a) =>dfs(d)? ? ? f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, ) (1, 6) print a; c // a choice print b; print e; d (3, 4) print d; dfs(a) e (2, 5) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c // a choice print b; print e; d (3, 4) print d; empty! e (2, 5) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c (8, ) // a choice print b; print e; d (3, 4) print d; // a choice print c; dfs(c) e (2, 5) f
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c (8, ) // a choice print b; print e; d (3, 4) print d; // a choice print c; print f; dfs(c)=>dfs(f) e (2, 5) f (9, )
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c (8, ) // a choice print b; print e; d (3, 4) e (2, 5) print d; // a choice print c; print f; dfs(c)=>dfs(f)? ? ? f (9, )
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c (8, ) // a choice print b; print e; d (3, 4) e (2, 5) print d; // a choice print c; print f; dfs(c)=>dfs(f)? ? ? f (9, )
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c (8, ) // a choice print b; print e; d (3, 4) print d; // a choice print c; print f; dfs(c) e (2, 5) f (9, 10)
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b (0, 7) (1, 6) print a; c (8, ) // a choice print b; print e; d (3, 4) e (2, 5) print d; // a choice print c; print f; dfs(c)=>dfs(e)? ? ? f (9, 10)
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b c (0, 7) (1, 6) print a; (8, 11) // a choice print b; print e; d (3, 4) print d; // a choice print c; print f; dfs(c) e (2, 5) f (9, 10)
Sample Graph DFS // color convention: not visited, discover, finish dfs (g, “a”, str. Output); a b c (0, 7) (1, 6) print a; (8, 11) // a choice print b; print e; d (3, 4) print d; // a choice print c; print f; empty! e (2, 5) f (9, 10)
Edge Classification n Once we obtain the DFS (or BFS) spanning trees (forests), the graph edges could be classified according to the trees: n n tree edges: edges in the trees forward edges: ancestors to descants back edges: descants to ancestors cross edges: others
Edge Classification Example • tree edges: a->b, b->e, e->d, c->f a b c d e f • forward edges: a->d • back edges: d->b, f->f • cross edges: c->e
Edge Classification Algorithm n Based on discover and finish time, for each edge e=(u, v): n n n if v not visited, e is tree edge if v not finished, e is back edge if v finished n n if discover(u)<discover(v), e is forward edge if discover(u)>discover(v), e is cross edge
Edge Classification Algorithm dfs (vertex start, ty. Visit visit, time) { visit (start); set. Discover (start, time++); for (each edge e=(start, v)) { if (not visited v) { dfs (v, visit, time); classify. Edge (e, “Tree. Edge”); } else { if (not set. Finish v) classify. Edge (e, “Back. Edge”); else { // leave to you } } set. Finish (start, time++); }
DFS Algorithm void dfs. Main (graph g, poly start, ty. Visit visit) { vertex start. V = search. Vertex (g, start); time = new. Time (); dfs (start. V, visit, time); for (each vertex u in graph g) if (not visited u) dfs (u, visit, time); }
BFS and DFS Application #1: Topological Sorting
An Example: Hasse Diagram 12 20 4 2 5 1 From Rosen’s book
An Example: Hasse Diagram 12 20 4 2 5 1 Sorted Sequence: 1
An Example: Hasse Diagram 12 20 4 2 5 1 Sorted Sequence: 1, 2
An Example: Hasse Diagram 12 20 4 2 5 1 Sorted Sequence: 1, 2, 4
An Example: Hasse Diagram 12 20 4 2 5 1 Sorted Sequence: 1, 2, 4, 12
An Example: Hasse Diagram 12 20 4 2 5 1 Sorted Sequence: 1, 2, 4, 12, 5
An Example: Hasse Diagram 12 20 4 2 5 1 Sorted Sequence: 1, 2, 4, 12, 5, 20
Source-queue Topological Sorting Algorithm topo. Sort. Bfs (graph g) { for (each vertex v) calculate in-degree for v; // vertices in queue q are candidates for // deletion queue q = new. Queue (); for (each vertex v) if (in-degree of v ==0) en. Queue (q, v);
Source-queue Topological Sorting Algorithm (cont’) while (q not empty) { vertex current = de. Queue (q); for (each edge e=(current, v)) if (not visited v) { in-degree of v --; if (in-degree of v ==0) en. Queue (q, v); } } } // BFS-based algorithm
An Example: Hasse Diagram 12 20 4 2 Source queue: 1 5 1 // color convention: not visited, en. Queue, de. Queue
An Example: Hasse Diagram 12 20 4 2 Source queue: 2, 5 Sorted Sequence: 1 5 1
An Example: Hasse Diagram 12 20 4 2 Source queue: 5, 4 Sorted Sequence: 1, 2 5 1
An Example: Hasse Diagram 12 20 4 // Note that we don’t // en. Queue 20!! Source queue: 4 Sorted Sequence: 1, 2, 5 2 5 1
An Example: Hasse Diagram 12 20 4 2 Source queue: 12, 20 // a chance Sorted Sequence: 1, 2, 5, 4 5 1
An Example: Hasse Diagram 12 20 4 2 Source queue: 20 Sorted Sequence: 1, 2, 5, 4, 12 5 1
An Example: Hasse Diagram 12 20 4 2 Source queue: empty! Sorted Sequence: 1, 2, 5, 4, 12, 20 5 1
DFS-based Algorithm 12 20 4 2 DFS from 4: 5 1
DFS-based Algorithm 12 (1, 2) 20 (3, 4) 4 (0, 5) 2 (7, 8) DFS from 4: 5 (9, 10) 1 (6, 11) When each vertex v finishes, insert v onto head of a linked list
Topological Sorting Algorithm dfs (vertex start, ty. Visit visit, linked. List list) { visit (start); for (each edge e=(start, v)) // as before … linked. List. Insert. Head (list, start) }
DFS Algorithm linked. List topo. Sort. Dfs (graph g, poly start, ty. Visit visit) { vertex start. V = search. Vertex (g, start); linked. List list = new. Linked. List (); dfs (start. V, visit, list); for (each vertex u in graph g) if (not visited u) dfs (u, visit, list); return list; }
Some Extra Programming Assignments n Simple path: is there a simple path from vertex u to v? n n Is an undirected g connected? n n n Or, are vertices u and v connected? Or, how many connected components are there in g? Cycle detection: is there a cycle in a digraph g? Two colorability: is it possible to color all the vertices in a digraph g using two colors, such that no adjacent vertices are of the same color?
- Slides: 82