Exemplo n.º 1
0
        /// <summary>
        /// Topologically sorts the nodes of this graph. Throws an exception if this graph is acyclic.
        /// </summary>
        /// <returns>The sorted nodes collection.</returns>
        public IEnumerable <EdgeListNode <T> > TopologicalSort()
        {
            List <EdgeListNode <T> >         ordered         = new List <EdgeListNode <T> >();
            List <EdgeListNode <T> >         noIncomingEdges = NodesWithoutIncomingEdges.ToList();
            List <Edge <EdgeListNode <T> > > allEdges        = AllEdges.ToList();

            while (noIncomingEdges.Count() > 0)
            {
                EdgeListNode <T> node = noIncomingEdges[0];
                noIncomingEdges.RemoveAt(0);
                ordered.Add(node);
                IEnumerable <Edge <EdgeListNode <T> > > outgoingEdges = allEdges.Where((Edge <EdgeListNode <T> > e) => e.From.Equals(node)).ToList();
                foreach (Edge <EdgeListNode <T> > edge in outgoingEdges)
                {
                    allEdges.Remove(edge);
                    int index = allEdges.FindIndex((Edge <EdgeListNode <T> > e) => e.To.Equals(edge.To));
                    if (index == -1)
                    {
                        noIncomingEdges.Add(edge.To);
                    }
                }
            }

            if (allEdges.Count > 0)
            {
                throw new Exception("This graph has at least one cycle, so it can't be topologically sorted.");
            }
            else
            {
                return(ordered);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates an edge to the specified node and stores it in this node edges, if it does not already exist.
        /// </summary>
        /// <param name="node">The node on the 'to' end of the edge.</param>
        /// <returns>The edge between this node and the specified node.</returns>
        public Edge <EdgeListNode <T> > AddEdgeTo(EdgeListNode <T> node)
        {
            Edge <EdgeListNode <T> > newEdge    = new Edge <EdgeListNode <T> >(this, node);
            Edge <EdgeListNode <T> > oldEdge    = this.FindEdgeTo(node);
            Edge <EdgeListNode <T> > actualEdge = oldEdge;

            if (oldEdge == null)
            {
                _edges.Add(newEdge);
                actualEdge = newEdge;
            }
            return(actualEdge);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Adds a new node to this graph, if it does not already exist.
        /// </summary>
        /// <param name="node">The node to add.</param>
        public EdgeListNode <T> AddNode(EdgeListNode <T> node)
        {
            EdgeListNode <T> target = FindNode(node.Value);

            if (target == null)
            {
                _nodes.Add(node);
                return(node);
            }
            else
            {
                return(target);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Adds a directed edge between the nodes identified by the specified values.
        /// </summary>
        /// <param name="from">Value identifying the node that will spawn the edge.</param>
        /// <param name="to">Value identifying the node on the 'to' end of the edge.</param>
        /// <returns>The edge between the targeted nodes.</returns>
        public Edge <EdgeListNode <T> > AddDirectedEdge(T from, T to)
        {
            EdgeListNode <T> fromTarget = FindNode(from);
            EdgeListNode <T> toTarget   = FindNode(to);

            if (fromTarget == null)
            {
                throw new ArgumentException("The 'from' node is not part of this graph.");
            }
            if (toTarget == null)
            {
                throw new ArgumentException("The 'to' node is not part of this graph.");
            }
            return(fromTarget.AddEdgeTo(to));
        }
Exemplo n.º 5
0
 /// <summary>
 /// Adds a directed edge between the specified nodes.
 /// </summary>
 /// <param name="from">The node spawning the edge.</param>
 /// <param name="to">The destination of the edge.</param>
 /// <returns>The edge between the nodes equivalent to the specified nodes.</returns>
 public Edge <EdgeListNode <T> > AddDirectedEdge(EdgeListNode <T> from, EdgeListNode <T> to)
 {
     return(this.AddDirectedEdge(from.Value, to.Value));
 }
Exemplo n.º 6
0
 /// <summary>
 /// Gets whether this graph contains a node equivalent to the specified node.
 /// </summary>
 /// <param name="node">The equivalent node to search for.</param>
 /// <returns>True if a node is found, false otherwise.</returns>
 public bool ContainsNode(EdgeListNode <T> node)
 {
     return(this.ContainsNode(node.Value));
 }
Exemplo n.º 7
0
 /// <summary>
 /// Finds a node equivalent to the specified node.
 /// </summary>
 /// <param name="node">The node to search for.</param>
 /// <returns>The node if it is found, null otherwise.</returns>
 public EdgeListNode <T> FindNode(EdgeListNode <T> node)
 {
     return(this.FindNode(node.Value));
 }
Exemplo n.º 8
0
        /// <summary>
        /// Adds a new node having the specified value as value, if it does not already exist.
        /// </summary>
        /// <param name="value"></param>
        public EdgeListNode <T> AddNode(T value)
        {
            EdgeListNode <T> target = new EdgeListNode <T>(value);

            return(AddNode(target));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Creates an edge to a node having the specified value and stores it in this node edges, if it does not already exist.
        /// </summary>
        /// <param name="value">The value of the node on the 'to' end of the edge.</param>
        /// /// <returns>The edge between this node and the one having value as the specified value.</returns>
        public Edge <EdgeListNode <T> > AddEdgeTo(T value)
        {
            EdgeListNode <T> newNode = new EdgeListNode <T>(value);

            return(this.AddEdgeTo(newNode));
        }
Exemplo n.º 10
0
 /// <summary>
 /// Gets whether this node has an edge going to a node equivalent to the specified node.
 /// </summary>
 /// <param name="node">The node on the 'to' end.</param>
 /// <returns>True if the condition is met, false otherwise.</returns>
 public bool HasEdgeTo(EdgeListNode <T> node)
 {
     return(this.FindEdgeTo(node) != null);
 }
Exemplo n.º 11
0
 /// <summary>
 /// Searches for an edge spawning from this node and ending in a node equivalent to the specified node.
 /// </summary>
 /// <param name="node"></param>
 /// <returns></returns>
 public Edge <EdgeListNode <T> > FindEdgeTo(EdgeListNode <T> node)
 {
     return(this.FindEdgeTo(node.Value));
 }