//^ [NotDelayed] public TransposedGraph(IGraph <Node, OldEdgeInfo> /*!*/ orig, Converter <OldEdgeInfo, EdgeInfo> /*!*/ edgeinfomap) { Contract.Requires(orig != null); // Clousot Suggestion Contract.Requires(edgeinfomap != null); // Clousot Suggestion this.orig = orig; this.edgeinfomap = edgeinfomap; //^ base(); DepthFirst.Visitor <Node, OldEdgeInfo> v = new DepthFirst.Visitor <Node, OldEdgeInfo>(orig, this); // Visit all edges to compute the transpose v.VisitAll(); // debug #if false foreach (Node n in this.orig.Nodes) { DepthFirst.Info info = v.DepthFirstInfo(n); Console.WriteLine("Depthfirst info: {0}: Start:{1}, Finish:{2}", n, info.StartTime, info.FinishTime); } #endif }
public static List <List <Node> /*!*/> /*!*/ Compute <Node, EdgeInfo>(IGraph <Node, EdgeInfo> /*!*/ graph) { Contract.Requires(graph != null);// Clousot Suggestion // Step 1: Call DFS(G) to compute finishing times f[u] for each vertex u // DepthFirst.Visitor <Node, EdgeInfo> /*!*/ dfs = new DepthFirst.Visitor <Node, EdgeInfo>(graph); dfs.VisitAll(); List <Node> nodesSortedByDecreasingFinishingTime = new List <Node>(graph.Nodes); // Sort in decreasing order of finish time nodesSortedByDecreasingFinishingTime.Sort( delegate(Node lhs, Node rhs) { return(dfs.DepthFirstInfo(rhs).FinishTime - dfs.DepthFirstInfo(lhs).FinishTime); } ); // Step 2: Compute G^T // IGraph <Node, EdgeInfo> transposed = Transpose.Build <Node, EdgeInfo>(graph); // Step 3: Call DFS(G^T), but in the main loop of DFS, consider the vertices // in order of decreasing f[u] (as computed in Step 1) // bool startNewGroup = true; List <List <Node> /*!*/> /*!*/ groups = new List <List <Node> /*!*/>(); DepthFirst.Visitor <Node, EdgeInfo> transposedDFS = new DepthFirst.Visitor <Node, EdgeInfo>(transposed, delegate(Node n) { List <Node> group; if (startNewGroup) { startNewGroup = false; group = new List <Node>(); groups.Add(group); } else { group = groups[groups.Count - 1]; } group.Add(n); return(true); }); foreach (Node n in nodesSortedByDecreasingFinishingTime) { // debug #if false Console.WriteLine("Node {0}, finish time {1}", n, dfs.DepthFirstInfo(n).FinishTime); #endif transposedDFS.VisitSubGraph(n); startNewGroup = true; } return(groups); }