Пример #1
0
        private BinaryTreeNode MergeNodesByWeightIntoOne(MinHeapUniversal <BinaryTreeNode> minHeap)
        {
            while (minHeap.GetHeapSize() != 1)
            {
                var firstSmallestNode  = minHeap.ExtractMinElement();
                var secondSmallestNode = minHeap.ExtractMinElement();

                var superNode = new BinaryTreeNode();
                superNode.SetKey(firstSmallestNode.GetKey() + secondSmallestNode.GetKey());
                superNode.LeftChild  = firstSmallestNode;
                superNode.RightChild = secondSmallestNode;
                minHeap.InsertElement(superNode);
            }

            return(minHeap.ExtractMinElement());
        }
Пример #2
0
        public int GetMinAllPairsShortestPaths(Dictionary <int, NodeWeighted> graph)
        {
            var vertCount = graph.Count;
            var min       = int.MaxValue;

            foreach (var startingNode in graph)
            {
                var sourceId              = startingNode.Key;
                var sourceJohnsonVal      = graph[sourceId].JohnsonsValue;
                var visitedNodesCount     = 0;
                var closestUnvisitedNodes = new MinHeapUniversal <NodeWeighted>();

                var sourceNode = graph[sourceId];

                sourceNode.Value = 0;

                foreach (var node in graph)
                {
                    closestUnvisitedNodes.InsertElement(node.Value);
                }

                while (visitedNodesCount++ != vertCount)
                {
                    var lastAddedNode = closestUnvisitedNodes.ExtractMinElement();
                    lastAddedNode.HeapIndex = 0;

                    if (lastAddedNode.Id != sourceId)
                    {
                        var adjustedPathValue = lastAddedNode.Value + lastAddedNode.JohnsonsValue - sourceJohnsonVal;
                        min = Math.Min(min, adjustedPathValue);
                    }

                    foreach (var nodeWeightTuple in lastAddedNode.Neighbours)
                    {
                        var(neighbour, edgeLength) = nodeWeightTuple;
                        if (neighbour.HeapIndex == 0)
                        {
                            continue;
                        }

                        var pathLength = edgeLength + lastAddedNode.Value;
                        closestUnvisitedNodes.TryDecreaseKey(neighbour.HeapIndex, pathLength);
                    }

                    lastAddedNode.Value = Globals.DefaultDijkstraValue;
                }
            }
            return(min);
        }
Пример #3
0
        public int[] GetShortestPaths(Dictionary <int, NodeWeighted> graph, int startingVertex)
        {
            var visitedNodesCount     = 1;
            var closestUnvisitedNodes = new MinHeapUniversal <NodeWeighted>();

            var pathLengths = new int[graph.Count + 1];
            var firstNode   = graph[startingVertex];

            firstNode.Value             = 0;
            pathLengths[startingVertex] = 0;
            var lastAddedNode = firstNode;

            lastAddedNode.Visit();
            while (visitedNodesCount++ != graph.Count - 1)
            {
                var unvisitedHeadNodes = lastAddedNode.Neighbours.FindAll(x => !x.Item1.IsVisited);

                foreach (var nodeWeightTuple in unvisitedHeadNodes)
                {
                    var(neighbour, edgeLength) = nodeWeightTuple;
                    var pathLength   = edgeLength + lastAddedNode.Value;
                    var isNodeInHeap = neighbour.HeapIndex != 0;

                    if (isNodeInHeap)
                    {
                        closestUnvisitedNodes.TryDecreaseKey(neighbour.HeapIndex, pathLength);
                    }
                    else
                    {
                        neighbour.Value = pathLength;
                        closestUnvisitedNodes.InsertElement(neighbour);
                    }
                }

                if (closestUnvisitedNodes.GetHeapSize() != 0)
                {
                    lastAddedNode = closestUnvisitedNodes.ExtractMinElement();
                    lastAddedNode.Visit();
                    lastAddedNode.HeapIndex       = 0;
                    pathLengths[lastAddedNode.Id] = lastAddedNode.Value;
                }
            }

            return(pathLengths);
        }
Пример #4
0
        // input - connected graph. Task - find collection of cheapest edges to connect all nodes

        public List <Tuple <int, int, int> > GetMinimumSpanningTree(Dictionary <int, NodeWeighted> graph)
        {
            var nodesCount        = graph.Count;
            var cheapestEdgesHeap = new MinHeapUniversal <NodeWeighted>();
            var msTree            = new List <Tuple <int, int, int> >();

            var cheapestNode = graph.Values.First();

            cheapestNode.Visit();
            nodesCount--;

            while (nodesCount != 0)
            {
                var unvisitedNeighbours = cheapestNode.Neighbours.Where(x => !x.Item1.IsVisited);

                foreach (var nodeTuple in unvisitedNeighbours)
                {
                    var currentNode = nodeTuple.Item1;
                    var edgeWeight  = nodeTuple.Item2;
                    if (currentNode.HeapIndex == 0)
                    {
                        currentNode.Parent = cheapestNode;
                        currentNode.Value  = edgeWeight;
                        cheapestEdgesHeap.InsertElement(currentNode);
                        continue;
                    }

                    if (cheapestEdgesHeap.TryDecreaseKey(currentNode.HeapIndex, edgeWeight))
                    {
                        currentNode.Parent = cheapestNode;
                    }
                }

                cheapestNode = cheapestEdgesHeap.ExtractMinElement();
                cheapestNode.Visit();

                var edge = new Tuple <int, int, int>(cheapestNode.Parent.Id, cheapestNode.Id, cheapestNode.Value);
                msTree.Add(edge);

                nodesCount--;
            }

            return(msTree);
        }