public void TestCreateDirectedGraph() { IList <CustomNode> nodes = new List <CustomNode> { new CustomNode { Name = "First", }, new CustomNode { Name = "Second" }, new CustomNode { Name = "Third" }, }; nodes[0].InputNodes = new[] { nodes[1], nodes[2] }; DirectedGraphNodeCreator <CustomNode> creator = node => new DirectedGraphNode { Id = node.Name }; NodeLinksResolver <CustomNode> resolver = node => node.InputNodes; DirectedGraph graph = nodes.ToGraph(creator, resolver, incomingLinks: true); Assert.IsNotNull(graph.ToDgml()); }
private Graph CreateGraph(IDictionary <string, ICollection <string> > inputGraph, bool incomingLinks = false) { IList <CustomNode> nodes = inputGraph.Keys.Select(node => new CustomNode { Name = node }).ToList(); NodeLinksResolver <CustomNode> resolver = node => inputGraph[node.Name] .Select( link => nodes.SingleOrDefault(n => link == n.Name) ?? new CustomNode { Name = link }); NodeCreator <CustomNode> creator = node => new Node(node.Name); return(nodes.ToGraph(creator, resolver, incomingLinks)); }
public static IEnumerable <T> TopologicalSortReverse <T>(this ICollection <T> list, NodeLinksResolver <T> linkResolver) { TopologicalSortState <T> state = new TopologicalSortState <T> { Unmarked = new HashSet <T>(list), GetLinks = linkResolver, }; while (state.Unmarked.Count > 0) { Visit(state.Unmarked.First(), state); } return(state.SortedNodes); }
/// <summary> /// Creates a graph from given list of nodes. Links to nodes outside the collection are ignored /// </summary> /// <typeparam name="T">Custom node type</typeparam> /// <param name="list">List of custom nodes</param> /// <param name="nodeCreator">Delegate for creating <see cref="Node"/></param> /// <param name="linkResolver">Delegate for finding links for given node</param> /// <param name="incomingLinks">Links are treated as incoming instead of outgoing</param> /// <returns><see cref="Graph"/> object</returns> public static DirectedGraph ToGraph <T>(this IEnumerable <T> list, DirectedGraphNodeCreator <T> nodeCreator, NodeLinksResolver <T> linkResolver, bool incomingLinks = false) { IDictionary <T, DirectedGraphNode> nodeCache = list.ToDictionary(node => node, node => nodeCreator(node)); IEnumerable <DirectedGraphLink> links = nodeCache.Keys.SelectMany(source => linkResolver(source) .Where(nodeCache.ContainsKey) .Select(target => incomingLinks ? new DirectedGraphLink { Source = nodeCache[target].Id, Target = nodeCache[source].Id } : new DirectedGraphLink { Source = nodeCache[source].Id, Target = nodeCache[target].Id })); return(new DirectedGraph { Nodes = nodeCache.Values.ToArray(), Links = links.ToArray(), }); }
public static IEnumerable <T> TopologicalSort <T>(this ICollection <T> list, NodeLinksResolver <T> linkResolver) { return(list.TopologicalSortReverse(linkResolver).Reverse()); }