public override void Produce(IEngineTask task) { Guard.AssertNotNull(task, "task"); var dirtyNode = task.DirtyNode; Diagnostics.WriteLine(this, string.Format("scheduled task for node= {0}", dirtyNode.Node.Name)); if (isInitialized) { task.CalculationOrder = topsortMap[dirtyNode.Vertex.Name]; } else { // First time around we need to calculate (Update) all nodes // so here we sort the whole graph and use the visit order to // force calculation of everything. var graphSort = new TopologicalSort(engine.Graph); graphSort.Run(); task.CalculationOrder = graphSort.VisitOrder; isInitialized = true; } SendNext(task); }
public void Bind(IEngine engine) { Guard.AssertNotNull(engine, "engine"); this.engine = engine; var graph = engine.Graph; var graphVertices = graph.Vertices; topsortMap = new TopSortMap(graphVertices.Count); foreach (var vertex in graphVertices) { var host = engine[vertex.Name]; // We only produce a top sort for nodes which can be originators // of change ie IActiveNodes. All other nodes will take part // in top sorts, but they will not be first in the visit order. if (!(host.Node is IActiveNode)) { continue; } var vertexSort = new TopologicalSort(vertex); vertexSort.Run(); var topsort = new List <IVertex>(); foreach (var dependentVertex in vertexSort.VisitOrder) { var dependentHost = engine[dependentVertex.Name]; var dependentNode = dependentHost.Node; // We will only ever need to update/calculate nodes which // can change *and* are not potential originators of change. if (!(dependentNode is IActiveNode)) { // The InvariantNodeAttribute can be used to filter nodes out // of the update list here. var invAttrs = dependentNode.GetType().GetCustomAttributes( typeof(InvariantNodeAttribute), false); if (invAttrs == null || invAttrs.Length == 0) { topsort.Add(dependentVertex); } } } topsortMap[vertex.Name] = topsort; } }
public void SetNodesPosition(string graphText, string expectedPositions) { var graph = graphText.ToDirectedGraph<string, int>().ToDictionary(x => x.Key, x => x.Value); var algo = new TopologicalSort<string>(graph); algo.Run(); foreach (var node in graph.Values) { Console.WriteLine(node.Id + " " + node.Value); } foreach (var nodePosition in expectedPositions.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)) { var pair = nodePosition.Split(new[] {'-'}, StringSplitOptions.RemoveEmptyEntries); var node = graph[pair[0].Trim()]; int expectedPosition = int.Parse(pair[1]); Assert.That(node.Value, Is.EqualTo(expectedPosition), "Node '" + node.Id + "' has unexpected topological order."); } }
public void TopologicalSortTest() { for (int n = 0; n < 5; n++) { Vertex[] vertices = TopologicalSortTestClass.CreateDirectedAcyclicGraph(n); Vertex[] order = TopologicalSort.Run(vertices); for (int i = n - 1; i >= 0; i--) { foreach (Vertex v in vertices) { v.Reset(); } DepthFirstSearch.Run(order[i]); for (int j = 0; j < i; j++) { Assert.AreEqual(Color.White, order[j].Color); } } } }