
DFS in a digraph (adjacency lists) COS 226 Lecture 18: Digraphs and DAGs void dfsR(Graph G, Edge e, int pre[], int post[]) DIGRAPH: directed graph { link t; int i, v, w = e.w; Edge x; edge s-t from s to t pre[w] = cnt0++; edge t-s from t to s for (t = G->adj[w]; t != NULL; t = t->next) if (pre[t->v] == -1) 4-2 11-12 dfsR(G, EDGE(w, t->v), pre, post); post[w] = cnt1++; 4-11 5-4 } 2-3 12-9 0 void GRAPHsearch(Graph G, int pre[], int post[]) 4-3 0-5 6 7 8 { int v; 3-2 9-10 1 2 cnt0 = 0; cnt1 = 0; depth = 0; 3-5 6-4 for (v = 0; v < G->V; v++) 0-6 9-11 3 9 10 { pre[v] = -1; post[v] = -1; } 7-8 6-9 4 for (v = 0; v < G->V; v++) if (pre[v] == -1) 0-1 8-9 5 11 12 search(G, EDGE(v, v), pre, post); 8-7 7-6 } 2-0 10-12 Need both PREORDER and POSTORDER numbering Can you get there from here? 18.1 18.3 Basic definitions DFS forests Structure determined by digraph AND search dynamics CONNECTIVITY use pre- and post- numbering to distinguish edge types path from s to t in undirected graph 0 7 Edge types 5 1 6 6 8 REACHABILITY TREE 4 9 4 7 9 directed path from s to t in digraph BACK 3 11 2 5 2 12 DOWN 0 3 9 STRONG CONNECTIVITY CROSS 11 10 directed paths from s to t AND from t to s 12 9 0 7 Connectivity ADT implementation (last lecture) 11 10 5 1 6 6 8 query: O(1) 12 12 4 9 4 7 9 9 3 11 2 preprocessing: O(E) 5 2 space: O(V) 0 3 Can we do as well for reachability and strong connectivity? ONLY the FIRST tree 18.2 has the set of nodes reachable from its root 18.4 Transitive closure Warshall’s algorithm Digraph G Method of choice for transitive closure of a dense graph Transitive closure G* has edge from s to running time proportional to V^3 iff there is a directed path from s to t in G 0 1 2 3 4 5 for (k = 0; k < G->V; k++) 1 2 0 1 0 1 0 0 1 for (s = 0; s < G->V; s++) 1 1 1 0 0 0 0 if (G->tc[s][k] == 1) 0 3 2 0 1 1 0 0 0 3 0 0 1 1 1 0 for (t = 0; t < G->V; t++) 4 0 0 0 0 1 1 if (G->tc[k][t] == 1) G->tc[s][t] = 1; 5 4 5 0 0 0 0 1 1 0 1 2 3 4 5 Proof of correctness (induction on k) 1 2 0 1 1 1 0 1 1 there is a path from s to t (with no nodes > k) if 1 1 1 1 0 1 1 0 3 2 1 1 1 0 1 1 EITHER 3 1 1 1 1 1 1 there is path from s to k (with no nodes > k-1) 4 0 0 0 0 1 1 5 4 5 0 0 0 0 1 1 AND a path from k to t (with no nodes > k-1) OR there is a path from s to t (with no nodes > k-1) NOT symmetric supports O(1) reachability queries with O(V^2) space 18.5 18.7 Boolean matrices and paths in graphs Warshall’s algorithm (example) Adjacency matrix A A[s][t] is 1 iff path from s to t 0 1 2 3 4 5 Square A*A = A^2 1 2 0 1 0 1 0 0 1 1 1 1 0 0 0 0 A[s][t] is 1 iff path from s to t of length 2 in A [s-k-t] 0 3 2 0 1 1 0 0 0 3 0 0 1 1 1 0 Reflexive square A + A^2 4 0 0 0 0 1 1 5 4 A[s][t] is 1 iff path from s to t of length < 2 in A 5 0 0 0 0 1 1 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 1 2 1 2 0 0 0 1 0 0 1 0 0 1 0 0 1 0 1 2 0 1 0 1 0 0 1 1 2 0 1 1 1 0 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0 1 0 3 2 0 1 0 0 0 0 2 1 0 0 0 0 0 0 3 0 3 2 0 1 1 0 0 0 0 3 2 1 1 1 0 0 1 3 0 0 1 0 1 0 3 0 1 0 0 0 1 3 0 0 1 1 1 0 3 1 1 1 1 1 1 4 0 0 0 0 0 1 4 0 0 0 0 1 0 4 0 0 0 0 1 1 4 0 0 0 0 1 1 5 4 5 0 0 0 0 1 0 5 0 0 0 0 0 1 5 4 5 4 5 0 0 0 0 1 1 5 4 5 0 0 0 0 1 1 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 1 2 0 1 0 1 0 1 1 0 1 1 1 0 1 1 1 2 1 2 0 1 0 1 0 0 1 1 2 0 1 1 1 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0 1 1 1 1 1 0 0 1 0 3 2 0 1 1 0 0 0 2 1 1 1 0 0 0 0 3 0 3 2 1 1 1 0 0 1 0 3 2 1 1 1 0 0 1 3 0 0 1 1 1 1 3 0 1 1 1 1 1 3 0 0 1 1 1 0 3 1 1 1 1 1 1 4 0 0 0 0 1 1 4 0 0 0 0 1 1 4 0 0 0 0 1 1 4 0 0 0 0 1 1 5 4 5 4 5 4 5 0 0 0 0 1 1 5 0 0 0 0 1 1 5 4 5 0 0 0 0 1 1 5 0 0 0 0 1 1 0 1 2 3 4 5 0 1 2 3 4 5 Transitive closure: A + A^2 + A^3 + A^4 + A^5 + ... 1 2 0 1 1 1 0 0 1 1 2 0 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 same as lg V reflexive squares 0 3 2 1 1 1 0 0 1 0 3 2 1 1 1 0 1 1 3 1 1 1 1 1 1 3 1 1 1 1 1 1 [ A + (A + A^2)^2 = A + A^2 + A^3 + A^4 ] 4 0 0 0 0 1 1 4 0 0 0 0 1 1 5 4 5 4 leads to easy V^3 lg V transitive closure algorithm 18.6 5 0 0 0 0 1 1 5 0 0 0 0 1 1 18.8 Transitive closure lower bound Abstract transitive closure Consider Boolean (0-1) matrices ADT function for reachability in digraphs Premise: Matrix multiplication is not easy THM: DFS-based transtive closure provides grade-school algorithm: V^3 VE preprocessing time best known: V^c, c>2 [practical?] V^2 space constant query time THM: Transitive closure is no easier than matrix multiplication GOAL: Proof: V^2 (or VE) preprocessing time Given a matrix multiplication problem V space can solve it with a TC algorithm constant query time I A 0 I A AB V^2 preprocessing guarantee not likely by TC lower bound 0 I B = 0 I B 0 0 I 0 0 I Next attempt: O(V^2) TC would yield O(V^2) matrix multiply (not likely) is the problem easier if there are no cycles (DAG)?? 18.9 18.11 DFS-based transitive closure Topological sort (DAG) Package DFS to implement reachability ADT run new DFS for each vertex DAG: directed acyclic graph 0 6 7 8 void TCdfsR(Graph G, int v, int w) 1 2 { link t; 3 9 10 G->tc[v][w] = 1; 4 for (t = G->adj[w]; t != NULL; t = t->next) 5 11 12 if (G->tc[v][t->v] == 0) TCdfsR(G, v, t->v); Topological sort: all edges point left to right } void GRAPHtc(Graph G, Edge e) { int v, w; G->tc = malloc2d(G->V, G->V); 0 1 2 3 8 7 6 4 5 9 10 11 12 for (v = 0; v < G->V; v++) for (w = 0; w < G->V; w++) 0123456789101112 G->tc[v][w] = 0; ts 0 1 2 3 8 7 6 4 5 9 10 11 12 tsI 0 1 2 3 7 8 6 5 4 9 10 11 12 for (v = 0; v < G->V; v++) TCdfsR(G, v, v); } Reverse TS: all edges point right to left int GRAPHreach(Graph G, int s, int t) { return G->tc[s][t]; } Running time? less than VE (V^2 for sparse graphs) 18.10 18.12 Violates lower bound? NO (worst case still V^3) 5 12 11 10 9 4 6 3 2 1 0 7 8 DFS topological sort DAG transitive closure (code) Easy alg for reverse TS: DFS! 0 7 8 void TCdfsR(Dag D, int w, int v) (postorder visit is reverse TS) 5 6 2 3 1 6 7 { int u, i; 9 4 3 pre[v] = cnt0++; 11 10 12 9 5 4 for (u = 0; u < D->V; u++) if (D->adj[v][u]) 12 { 0123456789101112 post 5121110946321078 D->tc[v][u] = 1; void TSdfsR(Graph G, int v, int ts[]) if (pre[u] > pre[v]) continue; { int w; if (pre[u] == -1) TCdfsR(D, v, u); pre[v] = 0; for (i = 0; i < D->V; i++) for (w = 0; w < G->V; w++) if (D->tc[u][i] == 1) if (G->adj[w][v] != 0) D->tc[v][i] = 1; if (pre[w] == -1) TSdfsR(G, w, ts); } ts[cnt0++] = v; } } worst-case cost bound: VE (no help!) Quick hack for arrays: 18.13 actual cost is V(V+ no.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages6 Page
-
File Size-