Beispiel #1
0
        public void SortCyclic(
            [PexAssumeNotNull] IVertexListGraph <string, Edge <string> > g)
        {
            TopologicalSortAlgorithm <string, Edge <string> > topo = new TopologicalSortAlgorithm <string, Edge <string> >(g);

            topo.Compute();
        }
        public void Sort()
        {
            AdjacencyGraph g = new AdjacencyGraph(new VertexAndEdgeProvider(), true);
            Hashtable iv = new Hashtable();

            int i = 0;
            IVertex a = g.AddVertex();
            iv[i++]=a;
            IVertex b = g.AddVertex();
            iv[i++]=b;
            IVertex c = g.AddVertex();
            iv[i++]=c;
            IVertex d = g.AddVertex();
            iv[i++]=d;
            IVertex e = g.AddVertex();
            iv[i++]=e;

            g.AddEdge(a,b);
            g.AddEdge(a,c);
            g.AddEdge(b,c);
            g.AddEdge(c,d);
            g.AddEdge(a,e);

            TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(g);
            topo.Compute();

            for(int j=0;j<topo.SortedVertices.Count;++j)
            {
                Assert.AreEqual( (IVertex)iv[j], topo.SortedVertices[j]);
            }
        }
		public void Sort()
		{
			AdjacencyGraph g = new AdjacencyGraph(true);
			Hashtable iv = new Hashtable();
			
			int i = 0;
			IVertex a = g.AddVertex();
			iv[i++]=a;
			IVertex b = g.AddVertex();
			iv[i++]=b;
			IVertex c = g.AddVertex();
			iv[i++]=c;
			IVertex d = g.AddVertex();
			iv[i++]=d;
			IVertex e = g.AddVertex();
			iv[i++]=e;

			g.AddEdge(a,b);
			g.AddEdge(a,c);
			g.AddEdge(b,c);
			g.AddEdge(c,d);				
			g.AddEdge(a,e);				

			TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(g);
			topo.Compute();
		}
        private void SortCyclic <TVertex, TEdge>(
            IVertexListGraph <TVertex, TEdge> g)
            where TEdge : IEdge <TVertex>
        {
            var topo = new TopologicalSortAlgorithm <TVertex, TEdge>(g);

            topo.Compute();
        }
Beispiel #5
0
        public void SortCyclic <TVertex, TEdge>(
            [PexAssumeNotNull] IVertexListGraph <TVertex, TEdge> g)
            where TEdge : IEdge <TVertex>
        {
            var topo = new TopologicalSortAlgorithm <TVertex, TEdge>(g);

            topo.Compute();
        }
Beispiel #6
0
        public void SortDCT8()
        {
            var g    = TestGraphFactory.LoadGraph("GraphML/DCT8.graphml");
            var topo = new TopologicalSortAlgorithm <string, Edge <string> >(g);

            Assert.IsFalse(topo.AllowCyclicGraph);
            topo.Compute();
        }
 public void OneTwo()
 {
     var graph = new AdjacencyGraph<int, Edge<int>>();
     graph.AddVertex(1);
     graph.AddVertex(2);
     graph.AddEdge(new Edge<int>(1, 2));
     var t = new TopologicalSortAlgorithm<int, Edge<int>>(graph);
     t.Compute();
 }
        /// <summary>
        /// Creates a topological sort of a directed
        /// acyclic graph.
        /// </summary>
        /// <typeparam name="TVertex">type of the vertices</typeparam>
        /// <typeparam name="TEdge">type of the edges</typeparam>
        /// <param name="visitedGraph"></param>
        /// <param name="vertices"></param>
        /// <returns></returns>
        /// <exception cref="NonAcyclicGraphException">the input graph
        /// has a cycle</exception>
        public static void TopologicalSort <TVertex, TEdge>
            (this IVertexListGraph <TVertex, TEdge> visitedGraph, IList <TVertex> vertices)
            where TEdge : IEdge <TVertex>
        {
            Contract.Requires(visitedGraph != null);
            Contract.Requires(vertices != null);

            var topo = new TopologicalSortAlgorithm <TVertex, TEdge>(visitedGraph);

            topo.Compute(vertices);
        }
        public void OneTwo()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddEdge(new Edge <int>(1, 2));
            var t = new TopologicalSortAlgorithm <int, Edge <int> >(graph);

            t.Compute();
        }
Beispiel #10
0
        public static void TopologicalSort <TVertex, TEdge>(
            IVertexListGraph <TVertex, TEdge> visitedGraph,
            IList <TVertex> vertices)
            where TEdge : IEdge <TVertex>
        {
            GraphContracts.AssumeNotNull(visitedGraph, "visitedGraph");
            GraphContracts.AssumeNotNull(vertices, "vertices");

            var topo = new TopologicalSortAlgorithm <TVertex, TEdge>(visitedGraph);

            topo.Compute(vertices);
        }
Beispiel #11
0
        public void OneTwo()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddEdge(new Edge <int>(1, 2));
            var t        = new TopologicalSortAlgorithm <int, Edge <int> >(graph);
            var vertices = new List <int>(graph.VertexCount);

            t.Compute(vertices);
            Assert.AreEqual(2, vertices.Count);
        }
Beispiel #12
0
        public void TwoOne()
        {
            var graph = new AdjacencyGraph <int, Edge <int> >();

            // Deliberately adding 1 and then 2, before adding edge (2, 1).
            graph.AddVertex(1);
            graph.AddVertex(2);
            graph.AddEdge(new Edge <int>(2, 1));
            var t        = new TopologicalSortAlgorithm <int, Edge <int> >(graph);
            var vertices = new List <int>(graph.VertexCount);

            t.Compute(vertices);
            Assert.AreEqual(2, vertices.Count);
        }
        protected override void RunFixtures()
        {
            // setup result
            foreach (FixtureVertex v in this.FixtureGraph.Graph.Vertices)
                v.Result = ReportRunResult.NotRun;

            // topological sort
            TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(this.FixtureGraph.Graph);
            ArrayList list = new ArrayList();
            topo.Compute(list);

            // execute pipes
            foreach (FixtureVertex v in list)
            {
                // result failed
                if (v.Result != ReportRunResult.NotRun)
                {
                    ReportMonitor monitor = new ReportMonitor();
                    ParentFixtureFailedException ex = new ParentFixtureFailedException();
                    foreach (Fixture fixture in v.Fixtures)
                    {
                        if (!this.FilterFixture(fixture))
                            continue;
                        this.SkipStarters(fixture, ex);
                    }
                }
                else
                {
                    // run fixtures
                    v.Result = ReportRunResult.Success;
                    foreach (Fixture fixture in v.Fixtures)
                    {
                        if (!this.FilterFixture(fixture))
                            continue;
                        ReportRunResult result = RunFixture(fixture);
                        if (result != ReportRunResult.Success && v.Result != ReportRunResult.Failure)
                            v.Result = result;
                    }
                }

                // update children if failed
                if (v.Result != ReportRunResult.Success)
                {
                    foreach (FixtureVertex target in this.FixtureGraph.Graph.AdjacentVertices(v))
                    {
                        target.Result = v.Result;
                    }
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Applies a topological sort to the graph
        /// </summary>
        /// <param name="g">graph to sort</param>
        /// <param name="vertices">sorted vertices</param>
        public static void TopologicalSort(IVertexListGraph g, IList vertices)
        {
            if (g == null)
            {
                throw new ArgumentNullException("g");
            }
            if (vertices == null)
            {
                throw new ArgumentNullException("vertices");
            }

            vertices.Clear();

            TopologicalSortAlgorithm topo =
                new TopologicalSortAlgorithm(g, vertices);

            topo.Compute();
        }
Beispiel #15
0
        public void FacebookSeattleWordPuzzle()
        {
            /* A puzzle from Facebook Seattle opening party:
             * http://www.facebook.com/note.php?note_id=146727365346299
             * You are given a list of relationships between the letters in a single word, all of which are in the form:
             * "The first occurrence of A comes before N occurrences of B."
             * You can safely assume that you have all such relationships except for any in which N would be 0.
             * Determine the original word, then go to http://www.facebook.com/seattle/[insert-word-here] to find the second part of the puzzle.
             *
             * The first occurrence of 'e' comes before 1 occurrence of 's'.
             * The first occurrence of 'i' comes before 1 occurrence of 'n'.
             * The first occurrence of 'i' comes before 1 occurrence of 'i'.
             * The first occurrence of 'n' comes before 2 occurrences of 'e'.
             * The first occurrence of 'e' comes before 1 occurrence of 'e'.
             * The first occurrence of 'i' comes before 1 occurrence of 'v'.
             * The first occurrence of 'n' comes before 1 occurrence of 'i'.
             * The first occurrence of 'n' comes before 1 occurrence of 'v'.
             * The first occurrence of 'i' comes before 1 occurrence of 's'.
             * The first occurrence of 't' comes before 1 occurrence of 's'.
             * The first occurrence of 'v' comes before 1 occurrence of 's'.
             * The first occurrence of 'v' comes before 2 occurrences of 'e'.
             * The first occurrence of 't' comes before 2 occurrences of 'e'.
             * The first occurrence of 'i' comes before 2 occurrences of 'e'.
             * The first occurrence of 'v' comes before 1 occurrence of 't'.
             * The first occurrence of 'n' comes before 1 occurrence of 't'.
             * The first occurrence of 'v' comes before 1 occurrence of 'i'.
             * The first occurrence of 'i' comes before 1 occurrence of 't'.
             * The first occurrence of 'n' comes before 1 occurrence of 's'.
             */
            var graph = new AdjacencyGraph <Letter, Edge <Letter> >();

            //A more generalized algorithm would handle duplicate letters automatically.
            //This is the quick and dirty solution.
            var i1 = new Letter('i');
            var i2 = new Letter('i');
            var e1 = new Letter('e');
            var e2 = new Letter('e');

            var s = new Letter('s');
            var n = new Letter('n');
            var t = new Letter('t');
            var v = new Letter('v');

            graph.AddVertexRange(new List <Letter> {
                e1, e2, s, i1, i2, n, t, v
            });

            graph.AddEdge(new Edge <Letter>(e1, s));
            graph.AddEdge(new Edge <Letter>(i1, n));
            graph.AddEdge(new Edge <Letter>(i1, i2));
            graph.AddEdge(new Edge <Letter>(n, e1));
            graph.AddEdge(new Edge <Letter>(n, e2));
            graph.AddEdge(new Edge <Letter>(e1, e2));
            graph.AddEdge(new Edge <Letter>(i1, v));
            graph.AddEdge(new Edge <Letter>(n, e1));
            graph.AddEdge(new Edge <Letter>(n, v));
            graph.AddEdge(new Edge <Letter>(i1, s));
            graph.AddEdge(new Edge <Letter>(t, s));
            graph.AddEdge(new Edge <Letter>(v, s));
            graph.AddEdge(new Edge <Letter>(v, e1));
            graph.AddEdge(new Edge <Letter>(v, e2));
            graph.AddEdge(new Edge <Letter>(t, e1));
            graph.AddEdge(new Edge <Letter>(t, e2));
            graph.AddEdge(new Edge <Letter>(i1, e1));
            graph.AddEdge(new Edge <Letter>(i1, e2));
            graph.AddEdge(new Edge <Letter>(v, t));
            graph.AddEdge(new Edge <Letter>(n, t));
            graph.AddEdge(new Edge <Letter>(v, i2));
            graph.AddEdge(new Edge <Letter>(i1, t));
            graph.AddEdge(new Edge <Letter>(n, s));


            var sort = new TopologicalSortAlgorithm <Letter, Edge <Letter> >(graph);

            sort.Compute();

            StringBuilder builder = new StringBuilder();

            foreach (var item in sort.SortedVertices)
            {
                builder.Append(item.ToString());
            }
            var word = builder.ToString();

            Assert.AreEqual("invitees", word);
        }
        public ReportResult RunTests()
        {
            ReportResult result = new ReportResult();
            if (graph.VerticesCount == 0)
            {
                this.OnLog("No assembly to execute");
                result.UpdateCounts();
                return result;
            }

            this.OnLog("Sorting assemblies by dependencies");
            // create topological sort
            ArrayList sortedVertices = new ArrayList();
            TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(graph);
            topo.Compute(sortedVertices);
            if (sortedVertices.Count == 0)
                throw new InvalidOperationException("Cannot be zero");

            // set vertices colors
            this.OnLog("etting up fixture colors");
            VertexColorDictionary colors = new VertexColorDictionary();
            foreach (TestDomainVertex v in graph.Vertices)
                colors.Add(v, GraphColor.White);

            // execute each domain
            foreach (TestDomainVertex v in sortedVertices)
            {
                // if vertex color is not white, skip it
                GraphColor color = colors[v];
                if (color != GraphColor.White)
                {
                    this.OnLog("Skipping assembly {0} because dependent assembly failed", v.Domain.TestEngine.Explorer.AssemblyName);
                    // mark children
                    foreach (TestDomainVertex child in graph.AdjacentVertices(v))
                        colors[child] = GraphColor.Black;
                    continue;
                }

                this.OnLog("Loading {0}", v.Domain.TestEngine.Explorer.AssemblyName);

                ReportCounter counter = v.Domain.TestEngine.GetTestCount();
                this.OnLog("Found  {0} tests", counter.RunCount);
                this.OnLog("Running fixtures.");
                v.Domain.TestEngine.RunPipes();
                counter = v.Domain.TestEngine.GetTestCount();
                this.OnLog("Tests finished: {0} tests, {1} success, {2} failures, {3} ignored"
                    , counter.RunCount
                    , counter.SuccessCount
                    , counter.FailureCount
                    , counter.IgnoreCount
                    );

                result.Merge(v.Domain.TestEngine.Report.Result);

                if (counter.FailureCount != 0)
                {
                    // mark children as failed
                    colors[v] = GraphColor.Black;
                    foreach (TestDomainVertex child in graph.AdjacentVertices(v))
                        colors[child] = GraphColor.Black;
                }
                else
                {
                    // mark vertex as succesfull
                    colors[v] = GraphColor.Gray;
                }
            }

            result.UpdateCounts();
            MbUnit.Framework.Assert.IsNotNull(result);
            MbUnit.Framework.Assert.IsNotNull(result.Counter);

            this.OnLog("All Tests finished: {0} tests, {1} success, {2} failures, {3} ignored in {4} seconds"
                , result.Counter.RunCount
                , result.Counter.SuccessCount
                , result.Counter.FailureCount
                , result.Counter.IgnoreCount
                , result.Counter.Duration
                );

            return result;
        }
        public void SortPUT_NEW(bool allowParallelEdges_b, int numberOfVertices, bool toNull, bool makeNull)
        {
            TopologicalSortAlgorithm topo = null;
            AdjacencyGraph g = null;
            if(!makeNull)
                g = AdjacencyGraphFactory.CreateAcyclicGraph1(allowParallelEdges_b, numberOfVertices, toNull);
            else
                topo = new TopologicalSortAlgorithm(g);
            Hashtable iv = new Hashtable();

            int i = 0;
            IVertex a = g.AddVertex();
            iv[i++] = a;
            IVertex b = g.AddVertex();
            iv[i++] = b;
            IVertex c = g.AddVertex();
            iv[i++] = c;
            IVertex d = g.AddVertex();
            iv[i++] = d;
            IVertex e = g.AddVertex();
            iv[i++] = e;

            g.AddEdge(a, b);
            g.AddEdge(a, c);
            g.AddEdge(b, c);
            g.AddEdge(c, d);
            g.AddEdge(a, e);

            topo = new TopologicalSortAlgorithm(g);
            topo.Compute();

               for (int j = 0; j < topo.SortedVertices.Count; ++j)
            {
                //PexAssert.AreEqual((IVertex)iv[j], topo.SortedVertices[j]);
                PexObserve.ValueForViewing<IVertex>("Sorted Vertex", (IVertex)topo.SortedVertices[j]);
            }
        }
 public void SortCyclic(
     [PexAssumeNotNull]IVertexListGraph<string,Edge<string>> g)
 {
     TopologicalSortAlgorithm<string, Edge<string>> topo = new TopologicalSortAlgorithm<string, Edge<string>>(g);
     topo.Compute();
 }
        /// <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]));
                    }
                }
            }
        }
Beispiel #20
0
		/// <summary>
		/// Applies a topological sort to the graph
		/// </summary>
		/// <param name="g">graph to sort</param>
		/// <param name="vertices">sorted vertices</param>
		public static void TopologicalSort(IVertexListGraph g, IList vertices)
		{
			if (g==null)
				throw new ArgumentNullException("g");
			if (vertices==null)
				throw new ArgumentNullException("vertices");
	
			vertices.Clear();	
	
			TopologicalSortAlgorithm topo = 
				new TopologicalSortAlgorithm(g,vertices);
			topo.Compute();
		}
Beispiel #21
0
        /// <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 SortCyclic()
        {
            AdjacencyGraph g = new AdjacencyGraph(new VertexAndEdgeProvider(), true);

            IVertex a = g.AddVertex();
            IVertex b = g.AddVertex();
            IVertex c = g.AddVertex();
            IVertex d = g.AddVertex();
            IVertex e = g.AddVertex();

            g.AddEdge(a,b);
            g.AddEdge(a,c);
            g.AddEdge(b,c);
            g.AddEdge(c,d);
            g.AddEdge(a,e);
            g.AddEdge(c,a);

            TopologicalSortAlgorithm topo = new TopologicalSortAlgorithm(g);
            topo.Compute();
        }