/// <summary> /// Traverses through all the directed graph nodes in such a way as to guarantee that for /// every node in the sequence, all its predecessors have been visited first. /// </summary> /// <typeparam name="TNodeValue">The type of the labels associated with graph nodes.</typeparam> /// <typeparam name="TEdgeLabel">The type of the labels associated with graph edges.</typeparam> /// <param name="source">The source directed graph that will be traversed.</param> /// <returns> /// A sequence of <see cref="T:Bonsai.Dag.Node`2{T,U}"/> that contains the set of all /// graph nodes in topological sort order. /// </returns> public static IEnumerable <Node <TNodeValue, TEdgeLabel> > TopologicalSort <TNodeValue, TEdgeLabel>(this DirectedGraph <TNodeValue, TEdgeLabel> source) { if (source == null) { throw new ArgumentNullException("source"); } IEnumerable <Node <TNodeValue, TEdgeLabel> > topologicalOrder; if (!Bonsai.Dag.TopologicalSort.TrySort(source, out topologicalOrder)) { return(Enumerable.Empty <Node <TNodeValue, TEdgeLabel> >()); } return(topologicalOrder); }
public static DirectedGraphDescriptor <TNodeValue, TEdgeLabel> ToDescriptor <TNodeValue, TEdgeLabel>(this DirectedGraph <TNodeValue, TEdgeLabel> source) { if (source == null) { throw new ArgumentNullException("source"); } var descriptor = new DirectedGraphDescriptor <TNodeValue, TEdgeLabel>(); ToDescriptor(source, descriptor); return(descriptor); }
/// <summary> /// Traverses through all the directed graph nodes in depth-first order. /// </summary> /// <typeparam name="TNodeValue">The type of the labels associated with graph nodes.</typeparam> /// <typeparam name="TEdgeLabel">The type of the labels associated with graph edges.</typeparam> /// <param name="source">The source directed graph that will be traversed.</param> /// <returns> /// A sequence of <see cref="T:Bonsai.Dag.Node`2{T,U}"/> that contains the set of all /// graph nodes in depth-first order. /// </returns> public static IEnumerable <Node <TNodeValue, TEdgeLabel> > DepthFirstSearch <TNodeValue, TEdgeLabel>(this DirectedGraph <TNodeValue, TEdgeLabel> source) { if (source == null) { throw new ArgumentNullException("source"); } var visited = new HashSet <Node <TNodeValue, TEdgeLabel> >(); var stack = new Stack <Node <TNodeValue, TEdgeLabel> >(); return(from root in source from node in DepthFirstSearch(root, visited, stack) select node); }
/// <summary> /// Returns the sequence of predecessors to the specified node. /// </summary> /// <typeparam name="TNodeValue">The type of the labels associated with graph nodes.</typeparam> /// <typeparam name="TEdgeLabel">The type of the labels associated with graph edges.</typeparam> /// <param name="source">The source directed graph to search for predecessors.</param> /// <param name="node">The node for which to obtain the sequence of predecessors.</param> /// <returns> /// A sequence of <see cref="T:Bonsai.Dag.Node`2{T,U}"/> that contains all the predecessors /// to the specified node. /// </returns> public static IEnumerable <Node <TNodeValue, TEdgeLabel> > Predecessors <TNodeValue, TEdgeLabel>(this DirectedGraph <TNodeValue, TEdgeLabel> source, Node <TNodeValue, TEdgeLabel> node) { if (source == null) { throw new ArgumentNullException("source"); } if (!source.Contains(node)) { throw new ArgumentException("The specified node does not belong to the graph.", "node"); } foreach (var predecessor in source) { foreach (var successor in predecessor.Successors) { if (successor.Target == node) { yield return(predecessor); break; } } } }
/// <summary> /// Returns the sequence of all the nodes in the directed graph that have zero outgoing edges. /// </summary> /// <typeparam name="TNodeValue">The type of the labels associated with graph nodes.</typeparam> /// <typeparam name="TEdgeLabel">The type of the labels associated with graph edges.</typeparam> /// <param name="source">The directed graph to search for sinks.</param> /// <returns> /// A sequence of <see cref="T:Bonsai.Dag.Node`2{T,U}"/> that contains all the nodes in the /// directed graph that have zero outgoing edges. /// </returns> public static IEnumerable <Node <TNodeValue, TEdgeLabel> > Sinks <TNodeValue, TEdgeLabel>(this DirectedGraph <TNodeValue, TEdgeLabel> source) { if (source == null) { throw new ArgumentNullException("source"); } foreach (var node in source) { if (node.Successors.Count == 0) { yield return(node); } } }
/// <summary> /// Returns the sequence of all the nodes in the directed graph that have zero incoming edges. /// </summary> /// <typeparam name="TNodeValue">The type of the labels associated with graph nodes.</typeparam> /// <typeparam name="TEdgeLabel">The type of the labels associated with graph edges.</typeparam> /// <param name="source">The directed graph to search for sources.</param> /// <returns> /// A sequence of <see cref="T:Bonsai.Dag.Node`2{T,U}"/> that contains all the nodes in the /// directed graph that have zero incoming edges. /// </returns> public static IEnumerable <Node <TNodeValue, TEdgeLabel> > Sources <TNodeValue, TEdgeLabel>(this DirectedGraph <TNodeValue, TEdgeLabel> source) { if (source == null) { throw new ArgumentNullException("source"); } foreach (var node in source) { if (!source.Predecessors(node).Any()) { yield return(node); } } }
public static bool TrySort <TNodeValue, TEdgeLabel>( DirectedGraph <TNodeValue, TEdgeLabel> source, out IEnumerable <Node <TNodeValue, TEdgeLabel> > topologicalOrder) { return(TopologicalSort <TNodeValue, TEdgeLabel> .TrySort(source, out topologicalOrder)); }