/// <summary> /// Compute the transitive closure and store it in the supplied graph 'tc' /// </summary> /// <param name="tc"> /// Mutable Graph instance to store the transitive closure /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="tc"/> is a <null/>. /// </exception> public void Create( IMutableVertexAndEdgeListGraph tc ) { if (tc==null) throw new ArgumentNullException("tc"); CondensationGraphAlgorithm cgalgo = new CondensationGraphAlgorithm(VisitedGraph); cgalgo.Create(cg); ArrayList topo_order = new ArrayList(cg.VerticesCount); TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(cg, topo_order); topo.Compute(); VertexIntDictionary in_a_chain= new VertexIntDictionary(); VertexIntDictionary topo_number = new VertexIntDictionary(); for( int order=0; order<topo_order.Count; order++ ) { IVertex v = (IVertex)topo_order[order]; topo_number.Add( v, order ); if(!in_a_chain.Contains(v)) // Initially no vertex is present in a chain in_a_chain.Add(v, 0); } VertexListMatrix chains = new VertexListMatrix(); int position = -1; foreach( IVertex v in topo_order ) { if(in_a_chain[v]==0) { // Start a new chain position = chains.AddRow(); IVertex next = v; for(;;) { chains[position].Add(next); in_a_chain[next] = 1; // Get adjacent vertices ordered by topological number // Extend the chain by choosing the adj vertex with lowest topo# ArrayList adj = TopoSortAdjVertices(next, cg, topo_number); if( (next = FirstNotInChain(adj, in_a_chain)) == null ) break; } } } VertexIntDictionary chain_number = new VertexIntDictionary(); VertexIntDictionary pos_in_chain = new VertexIntDictionary(); // Record chain positions of vertices SetChainPositions(chains, chain_number, pos_in_chain); VertexListMatrix successors = new VertexListMatrix(); successors.CreateObjectMatrix(cg.VerticesCount, chains.RowCount, int.MaxValue); if(topo_order.Count > 0) { for( int rtopo=topo_order.Count-1; rtopo>-1; rtopo--) { IVertex u = (IVertex) topo_order[rtopo]; foreach( IVertex v in TopoSortAdjVertices(u, cg, topo_number) ) { if(topo_number[v] < (int)successors[u.ID][chain_number[v]]) { // {succ(u)} = {succ(u)} U {succ(v)} LeftUnion(successors[u.ID], successors[v.ID]); // {succ(u)} = {succ(u)} U {v} successors[u.ID][chain_number[v]] = topo_number[v]; } } } } // Create transitive closure of condensation graph // Remove existing edges in CG & rebuild edges for TC from // successor set (to avoid duplicating parallel edges) ArrayList edges = new ArrayList(); foreach( IEdge e in cg.Edges ) edges.Add(e); foreach(IEdge e in edges) cg.RemoveEdge(e); foreach(IVertex u in cg.Vertices) { int i = u.ID; for(int j=0; j<chains.RowCount; j++) { int tnumber = (int) successors[i][j]; if(tnumber < int.MaxValue) { IVertex v = (IVertex) topo_order[tnumber]; for(int k=pos_in_chain[v]; k<chains[j].Count; k++) { cg.AddEdge( u, (IVertex)chains[j][k]); } } } } // Maps a vertex in input graph to it's transitive closure graph graphTransitiveClosures = new VertexVertexDictionary(); // Add vertices to transitive closure graph foreach(IVertex v in visitedGraph.Vertices) { if(!graphTransitiveClosures.Contains(v)) { IVertex vTransform = tc.AddVertex(); OnInitTransitiveClosureVertex( new TransitiveClosureVertexEventArgs( v, vTransform) ); // Fire the TC Vertex Event graphTransitiveClosures.Add(v, vTransform); } } //Add edges connecting vertices within SCC & adjacent // SCC (strongly connected component) IVertexCollection scc_vertices = null; foreach(IVertex s_tccg in cg.Vertices) { scc_vertices = (IVertexCollection)cgalgo.SCCVerticesMap[s_tccg.ID]; if(scc_vertices.Count > 1) { foreach(IVertex u in scc_vertices) foreach(IVertex v in scc_vertices) OnExamineEdge(tc.AddEdge(graphTransitiveClosures[u], graphTransitiveClosures[v])); } foreach(IEdge adj_edge in cg.OutEdges(s_tccg)) { IVertex t_tccg = adj_edge.Target; foreach(IVertex s in (IVertexCollection)cgalgo.SCCVerticesMap[s_tccg.ID]) { foreach(IVertex t in (IVertexCollection)cgalgo.SCCVerticesMap[t_tccg.ID]) OnExamineEdge(tc.AddEdge(graphTransitiveClosures[s], graphTransitiveClosures[t])); } } } }
public void Create(IMutableVertexAndEdgeListGraph tc) { if (tc == null) { throw new ArgumentNullException("tc"); } CondensationGraphAlgorithm algorithm = new CondensationGraphAlgorithm(this.VisitedGraph); algorithm.Create(this.cg); ArrayList vertices = new ArrayList(this.cg.get_VerticesCount()); new TopologicalSortAlgorithm(this.cg, vertices).Compute(); VertexIntDictionary dictionary = new VertexIntDictionary(); VertexIntDictionary dictionary2 = new VertexIntDictionary(); for (int i = 0; i < vertices.Count; i++) { IVertex vertex = (IVertex) vertices[i]; dictionary2.Add(vertex, i); if (!dictionary.Contains(vertex)) { dictionary.Add(vertex, 0); } } VertexListMatrix chains = new VertexListMatrix(); int num2 = -1; Label_0112: foreach (IVertex vertex2 in vertices) { if (dictionary.get_Item(vertex2) == 0) { num2 = chains.AddRow(); IVertex vertex3 = vertex2; while (true) { chains[num2].Add(vertex3); dictionary.set_Item(vertex3, 1); ArrayList list2 = this.TopoSortAdjVertices(vertex3, this.cg, dictionary2); vertex3 = this.FirstNotInChain(list2, dictionary); if (vertex3 == null) { goto Label_0112; } } } } VertexIntDictionary dictionary3 = new VertexIntDictionary(); VertexIntDictionary dictionary4 = new VertexIntDictionary(); this.SetChainPositions(chains, dictionary3, dictionary4); VertexListMatrix matrix2 = new VertexListMatrix(); matrix2.CreateObjectMatrix(this.cg.get_VerticesCount(), chains.RowCount, 0x7fffffff); if (vertices.Count > 0) { for (int j = vertices.Count - 1; j > -1; j--) { IVertex v = (IVertex) vertices[j]; foreach (IVertex vertex5 in this.TopoSortAdjVertices(v, this.cg, dictionary2)) { if (dictionary2.get_Item(vertex5) < ((int) matrix2[v.get_ID()][dictionary3.get_Item(vertex5)])) { this.LeftUnion(matrix2[v.get_ID()], matrix2[vertex5.get_ID()]); matrix2[v.get_ID()][dictionary3.get_Item(vertex5)] = dictionary2.get_Item(vertex5); } } } } ArrayList list3 = new ArrayList(); IEdgeEnumerator enumerator = this.cg.get_Edges().GetEnumerator(); while (enumerator.MoveNext()) { IEdge edge = enumerator.get_Current(); list3.Add(edge); } foreach (IEdge edge2 in list3) { this.cg.RemoveEdge(edge2); } IVertexEnumerator enumerator5 = this.cg.get_Vertices().GetEnumerator(); while (enumerator5.MoveNext()) { IVertex vertex6 = enumerator5.get_Current(); int num4 = vertex6.get_ID(); for (int k = 0; k < chains.RowCount; k++) { int num6 = (int) matrix2[num4][k]; if (num6 < 0x7fffffff) { IVertex vertex7 = (IVertex) vertices[num6]; for (int m = dictionary4.get_Item(vertex7); m < chains[k].Count; m++) { this.cg.AddEdge(vertex6, (IVertex) chains[k][m]); } } } } this.graphTransitiveClosures = new VertexVertexDictionary(); IVertexEnumerator enumerator6 = this.visitedGraph.get_Vertices().GetEnumerator(); while (enumerator6.MoveNext()) { IVertex vertex8 = enumerator6.get_Current(); if (!this.graphTransitiveClosures.Contains(vertex8)) { IVertex vertex9 = tc.AddVertex(); this.OnInitTransitiveClosureVertex(new TransitiveClosureVertexEventArgs(vertex8, vertex9)); this.graphTransitiveClosures.Add(vertex8, vertex9); } } IVertexCollection vertexs = null; IVertexEnumerator enumerator7 = this.cg.get_Vertices().GetEnumerator(); while (enumerator7.MoveNext()) { IVertex vertex10 = enumerator7.get_Current(); vertexs = (IVertexCollection) algorithm.SCCVerticesMap[vertex10.get_ID()]; if (vertexs.Count > 1) { IVertexEnumerator enumerator8 = vertexs.GetEnumerator(); while (enumerator8.MoveNext()) { IVertex vertex11 = enumerator8.get_Current(); IVertexEnumerator enumerator9 = vertexs.GetEnumerator(); while (enumerator9.MoveNext()) { IVertex vertex12 = enumerator9.get_Current(); this.OnExamineEdge(tc.AddEdge(this.graphTransitiveClosures.get_Item(vertex11), this.graphTransitiveClosures.get_Item(vertex12))); } } } IEdgeEnumerator enumerator10 = this.cg.OutEdges(vertex10).GetEnumerator(); while (enumerator10.MoveNext()) { IVertex vertex13 = enumerator10.get_Current().get_Target(); IVertexEnumerator enumerator11 = ((IVertexCollection) algorithm.SCCVerticesMap[vertex10.get_ID()]).GetEnumerator(); while (enumerator11.MoveNext()) { IVertex vertex14 = enumerator11.get_Current(); IVertexEnumerator enumerator12 = ((IVertexCollection) algorithm.SCCVerticesMap[vertex13.get_ID()]).GetEnumerator(); while (enumerator12.MoveNext()) { IVertex vertex15 = enumerator12.get_Current(); this.OnExamineEdge(tc.AddEdge(this.graphTransitiveClosures.get_Item(vertex14), this.graphTransitiveClosures.get_Item(vertex15))); } } } } }