コード例 #1
0
        public void BMinHeap_Test()
        {
            var rnd     = new Random();
            var initial = Enumerable.Range(0, 51).OrderBy(x => rnd.Next()).ToList();

            //insert test
            var tree = new BMinHeap <int>(initial);

            for (int i = 51; i <= 99; i++)
            {
                tree.Insert(i);
            }

            for (int i = 0; i <= 99; i++)
            {
                var min = tree.ExtractMin();
                Assert.AreEqual(min, i);
            }


            var testSeries = Enumerable.Range(1, 49).OrderBy(x => rnd.Next()).ToList();

            foreach (var item in testSeries)
            {
                tree.Insert(item);
            }

            for (int i = 1; i <= 49; i++)
            {
                var min = tree.ExtractMin();
                Assert.AreEqual(min, i);
            }
        }
コード例 #2
0
        /// <summary>
        /// Returns a dictionary of chosen encoding bytes for each distinct T
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public Dictionary <T, byte[]> Compress(T[] input)
        {
            var frequencies = computeFrequency(input);

            var minHeap = new BMinHeap <FrequencyWrap>();

            foreach (var frequency in frequencies)
            {
                minHeap.Insert(new FrequencyWrap(
                                   frequency.Key, frequency.Value));
            }

            while (minHeap.Count > 1)
            {
                var a = minHeap.ExtractMin();
                var b = minHeap.ExtractMin();

                var newNode = new FrequencyWrap(
                    default(T), a.Frequency + b.Frequency);

                newNode.Left  = a;
                newNode.Right = b;

                minHeap.Insert(newNode);
            }

            var root = minHeap.ExtractMin();

            var result = new Dictionary <T, byte[]>();

            DFS(root, new List <byte>(), result);

            return(result);
        }
コード例 #3
0
        /// <summary>
        /// Sort the given input
        /// where elements are misplaced almost by a distance k
        /// </summary>
        /// <param name="input"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static int[] Sort(int[] input, int k)
        {
            if (k > input.Length)
            {
                throw new Exception("K cannot exceed array length.");
            }

            var firstKElements = new int[k];

            Array.Copy(input, firstKElements, k);

            var minHeap = new BMinHeap <int>(firstKElements);

            var result = new List <int>();

            for (int i = k; i < input.Length; i++)
            {
                result.Add(minHeap.ExtractMin());
                minHeap.Insert(input[i]);
            }

            while (minHeap.Count > 0)
            {
                result.Add(minHeap.ExtractMin());
            }

            return(result.ToArray());
        }
コード例 #4
0
        /// <summary>
        /// Do DFS to pick smallest weight neighbour edges
        /// of current spanning tree one by one
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="currentVertex"></param>
        /// <param name="spanTreeVertices"></param>
        /// <param name="spanTreeNeighbours"> Use Fibornacci Min Heap to pick smallest edge neighbour </param>
        /// <param name="spanTreeEdges">result MST edges</param>
        private void DFS(WeightedGraph <T, W> graph,
                         WeightedGraphVertex <T, W> currentVertex,
                         BMinHeap <MSTEdge <T, W> > spanTreeNeighbours,
                         HashSet <T> spanTreeVertices,
                         List <MSTEdge <T, W> > spanTreeEdges)
        {
            //add all edges to Fibornacci Heap
            //So that we can pick the min edge in next step
            foreach (var edge in currentVertex.Edges)
            {
                spanTreeNeighbours.Insert(new MSTEdge <T, W>(
                                              currentVertex.Value,
                                              edge.Key.Value, edge.Value));
            }

            //pick min edge
            var minNeighbourEdge = spanTreeNeighbours.ExtractMin();

            //skip edges already in MST
            while (spanTreeVertices.Contains(minNeighbourEdge.Source) &&
                   spanTreeVertices.Contains(minNeighbourEdge.Destination))
            {
                minNeighbourEdge = spanTreeNeighbours.ExtractMin();

                //if no more neighbours to explore
                //time to end exploring
                if (spanTreeNeighbours.Count == 0)
                {
                    return;
                }
            }

            //keep track of visited vertices
            //do not duplicate vertex
            if (!spanTreeVertices.Contains(minNeighbourEdge.Source))
            {
                spanTreeVertices.Add(minNeighbourEdge.Source);
            }

            //Destination vertex will never be a duplicate
            //since this is an unexplored Vertex
            spanTreeVertices.Add(minNeighbourEdge.Destination);

            //add edge to result
            spanTreeEdges.Add(minNeighbourEdge);

            //now explore the destination vertex
            DFS(graph, graph.Vertices[minNeighbourEdge.Destination],
                spanTreeNeighbours, spanTreeVertices, spanTreeEdges);
        }
コード例 #5
0
        /// <summary>
        /// Find smallest by first constructing a BMinHeap in O(n) time
        /// & then extracting out k -1 times
        /// Finally do one more extract to return the kth smallest
        /// Total O(n+k) complexity
        /// Better algorithms do exist with O(n) time
        /// </summary>
        /// <param name="input"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public T FindKthSmallest(T[] input, int k)
        {
            if (k > input.Length)
            {
                throw new Exception("K exceeds input length.");
            }

            var minHeap = new BMinHeap <T>(input);

            //0,1,2...(k-1) min extraction
            for (int i = 0; i < k - 1; i++)
            {
                minHeap.ExtractMin();
            }

            //kth extraction
            return(minHeap.ExtractMin());
        }
コード例 #6
0
        /// <summary>
        /// Add a new item to stream
        /// </summary>
        /// <param name="newValue"></param>
        public void Add(int newValue)
        {
            var median = GetMedian();

            //our goal is to keep the balance factor atmost to be <=1
            if (leftHeap.Count == rightHeap.Count)
            {
                if (newValue < median)
                {
                    leftHeap.Insert(newValue);
                }
                else
                {
                    rightHeap.Insert(newValue);
                }

                return;
            }
            //left has more elements
            else if (leftHeap.Count > rightHeap.Count)
            {
                //we can't increase left count > 1
                //So borrow top to right first
                if (newValue < median)
                {
                    rightHeap.Insert(leftHeap.ExtractMax());
                    leftHeap.Insert(newValue);
                }
                else
                {
                    rightHeap.Insert(newValue);
                }

            }
            //right has more elements
            else if(rightHeap.Count > leftHeap.Count)
            {
                //we can't increase right count > 1
                //So borrow top to left first
                if (newValue > median)
                {
                    leftHeap.Insert(rightHeap.ExtractMin());
                    rightHeap.Insert(newValue);
                }
                else
                {
                    leftHeap.Insert(newValue);
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Time complexity: O(nlog(n)).
        /// </summary>
        public static T[] Sort(T[] array)
        {
            //heapify
            var heap = new BMinHeap <T>(array);

            //now extract min until empty and return them as sorted array
            var sortedArray = new T[array.Length];
            var j           = 0;

            while (heap.Count > 0)
            {
                sortedArray[j] = heap.ExtractMin();
                j++;
            }

            return(sortedArray);
        }
コード例 #8
0
        //O(nlog(n))
        public static T[] Sort(T[] array)
        {
            //heapify
            var heap = new BMinHeap <T>();

            for (int i = 0; i < array.Length; i++)
            {
                heap.Insert(array[i]);
            }

            //now extract min until empty and return them as sorted array
            var sortedArray = new T[array.Length];
            int j           = 0;

            while (heap.Count > 0)
            {
                sortedArray[j] = heap.ExtractMin();
                j++;
            }

            return(sortedArray);
        }
コード例 #9
0
        public Dictionary <Point, List <Line> > FindIntersections(IEnumerable <Line> lineSegments)
        {
            initialize(lineSegments);

            while (eventQueue.Count > 0)
            {
                var currentEvent = eventQueue.ExtractMin();
                eventQueueLookUp.Remove(currentEvent);
                sweepTo(currentEvent);

                switch (currentEvent.Type)
                {
                case EventType.Start:

                    if (verticalHorizontalLines.Count > 0)
                    {
                        foreach (var line in verticalHorizontalLines)
                        {
                            var intersection = findIntersection(currentEvent, line);
                            recordIntersection(currentEvent, line, intersection);
                        }
                    }

                    if (currentEvent.Segment.IsVertical || currentEvent.Segment.IsHorizontal)
                    {
                        verticalHorizontalLines.Add(currentEvent);

                        foreach (var line in normalLines)
                        {
                            var intersection = findIntersection(currentEvent, line);
                            recordIntersection(currentEvent, line, intersection);
                        }

                        break;
                    }

                    normalLines.Add(currentEvent);

                    currentlyTrackedLines.Insert(currentEvent);

                    var lower = currentlyTrackedLines.NextLower(currentEvent);
                    var upper = currentlyTrackedLines.NextHigher(currentEvent);

                    var lowerIntersection = findIntersection(currentEvent, lower);
                    recordIntersection(currentEvent, lower, lowerIntersection);
                    enqueueIntersectionEvent(currentEvent, lowerIntersection);

                    var upperIntersection = findIntersection(currentEvent, upper);
                    recordIntersection(currentEvent, upper, upperIntersection);
                    enqueueIntersectionEvent(currentEvent, upperIntersection);

                    break;

                case EventType.End:

                    currentEvent = rightLeftEventLookUp[currentEvent];

                    if (currentEvent.Segment.IsVertical || currentEvent.Segment.IsHorizontal)
                    {
                        verticalHorizontalLines.Remove(currentEvent);
                        break;
                    }

                    normalLines.Remove(currentEvent);

                    lower = currentlyTrackedLines.NextLower(currentEvent);
                    upper = currentlyTrackedLines.NextHigher(currentEvent);

                    currentlyTrackedLines.Delete(currentEvent);

                    var upperLowerIntersection = findIntersection(lower, upper);
                    recordIntersection(lower, upper, upperLowerIntersection);
                    enqueueIntersectionEvent(currentEvent, upperLowerIntersection);

                    break;

                case EventType.Intersection:

                    var intersectionLines = intersectionEvents[currentEvent as Point];

                    foreach (var item in intersectionLines)
                    {
                        currentlyTrackedLines.Swap(item.Item1, item.Item2);

                        var upperLine  = item.Item1;
                        var upperUpper = currentlyTrackedLines.NextHigher(upperLine);

                        var newUpperIntersection = findIntersection(upperLine, upperUpper);
                        recordIntersection(upperLine, upperUpper, newUpperIntersection);
                        enqueueIntersectionEvent(currentEvent, newUpperIntersection);

                        var lowerLine  = item.Item2;
                        var lowerLower = currentlyTrackedLines.NextLower(lowerLine);

                        var newLowerIntersection = findIntersection(lowerLine, lowerLower);
                        recordIntersection(lowerLine, lowerLower, newLowerIntersection);
                        enqueueIntersectionEvent(currentEvent, newLowerIntersection);
                    }

                    break;
                }
            }

            return(intersectionEvents.ToDictionary(x => x.Key,
                                                   x => x.Value.SelectMany(y => new[] { y.Item1.Segment, y.Item2.Segment })
                                                   .Distinct().ToList()));
        }
コード例 #10
0
 public T Dequeue()
 {
     return(minHeap.ExtractMin());
 }