Ejemplo n.º 1
0
        public void TreeSortTest()
        {
            // arrange
            AlgorithmBase <int> tree = new DataStructures.Tree <int>(items);

            // act
            tree.SortAndGetSpan();

            // assert
            for (int i = 0; i < items.Count; i++)
            {
                Assert.AreEqual(sorted[i], tree.Items[i]);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns a spanning tree rooted at given node to find a shortest path from any node to the root node.
        /// </summary>
        public DataStructures.Tree <Node <TNodeValue, TLinkProperty> > AnyShortestPath(Node <TNodeValue, TLinkProperty> fromNode)
        {
            if (fromNode == null || fromNode.Graph != this)
            {
                throw new Exception("Arguments are incorrect");
            }
            var treeNodes = new Dictionary <Node <TNodeValue, TLinkProperty>, bool>();
            var treeLinks = new Dictionary <Link <TNodeValue, TLinkProperty>, bool>();
            var tree      = new DataStructures.Tree <Node <TNodeValue, TLinkProperty> >(fromNode); //resulting spanning tree

            if (NodesCount == 0)
            {
                return(tree);
            }
            treeNodes.Add(fromNode, false);
            var candidateLinks = new Dictionary <Link <TNodeValue, TLinkProperty>, bool>();

            foreach (var l in fromNode.Links)
            {
                if (!l.IsLoop)
                {
                    candidateLinks.Add(l, false);                                                     // add all links of fromNode to list
                }
            }
            foreach (var n in nodes)
            {
                n.Weight = 0;                                                                   // reset weights of all nodes
            }
            while (true)
            {
                if (candidateLinks.Count == 0 || treeNodes.Count == NodesCount)
                {
                    break;                                                                 // all nodes are processed
                }
                // find a node not in the tree that has the smallest distance from starting node
                double smallestWeight = 0;
                Link <TNodeValue, TLinkProperty> closestLink = null;
                Node <TNodeValue, TLinkProperty> closestNode = null;

                foreach (var l in candidateLinks.Keys)
                {
                    if (!candidateLinks[l])
                    {
                        Node <TNodeValue, TLinkProperty> nodeInTree, nodeOutTree = null;
                        if (treeNodes.ContainsKey(l.Node1))
                        {
                            nodeInTree  = l.Node1;
                            nodeOutTree = l.Node2;
                        }
                        else
                        {
                            nodeInTree  = l.Node2;
                            nodeOutTree = l.Node1;
                        }

                        double newWeight = nodeInTree.Weight + l.Weight;
                        if (closestLink == null || newWeight < smallestWeight)
                        {
                            closestLink    = l;
                            closestNode    = nodeOutTree;
                            smallestWeight = newWeight;
                        }
                    }
                }

                // if both nodes of the link are in the tree, mark the link as added
                if (closestNode == null)
                {
                    break;
                }
                if (treeNodes.ContainsKey(closestNode))
                {
                    candidateLinks[closestLink] = true;
                }
                else
                {
                    // add found node to the spanning tree, set its weight, add node's links that lead to a node not yet in the tree, to the candidate links
                    closestNode.Weight = smallestWeight;
                    treeNodes.Add(closestNode, false);
                    foreach (var l in closestNode.Links)
                    {
                        var nodeNotInTree = l.Node1 == closestNode ? l.Node2 : l.Node1;
                        if (!treeNodes.ContainsKey(nodeNotInTree) && !l.IsLoop && !candidateLinks.ContainsKey(l))
                        {
                            candidateLinks.Add(l, false);
                        }
                    }
                    var parent = tree.Root.FindNodeByValue(closestLink.Node1 == closestNode ? closestLink.Node2 : closestLink.Node1);
                    parent.AddChild(closestNode);
                }
            }

            // check if all nodes have been added (the graph might not be connected)
            if (treeNodes.Count != this.NodesCount)
            {
                if (GraphType == GraphType.Undirected)
                {
                    throw new Exception("Graph is not connected");
                }
                else
                {
                    throw new Exception("Not possible to follow all nodes");
                }
            }

            return(tree);
        }