/// <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);
                }
            }
        }
Example #7
0
 public static bool TrySort <TNodeValue, TEdgeLabel>(
     DirectedGraph <TNodeValue, TEdgeLabel> source,
     out IEnumerable <Node <TNodeValue, TEdgeLabel> > topologicalOrder)
 {
     return(TopologicalSort <TNodeValue, TEdgeLabel> .TrySort(source, out topologicalOrder));
 }