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(); }
public void SortCyclic <TVertex, TEdge>( [PexAssumeNotNull] IVertexListGraph <TVertex, TEdge> g) where TEdge : IEdge <TVertex> { var topo = new TopologicalSortAlgorithm <TVertex, TEdge>(g); topo.Compute(); }
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(); }
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); }
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); }
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; } } } }
/// <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(); }
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])); } } } }
/// <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(); }
/// <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(); }