public static void HeapSortUsingGet <T>(
            [ValueSource("CollectionsSource")] IEnumerable <T> collection,
            [Values] bool ascending)
        {
            var ordered   = ascending ? collection.OrderBy(x => x) : collection.OrderByDescending(x => x);
            var mmh       = new MinMaxHeap <T>(collection);
            var extracted = new List <T>();

            while (mmh.Count > 0)
            {
                T value;
                if (ascending)
                {
                    value = mmh.GetMin();
                    _     = mmh.ExtractMin();
                }
                else
                {
                    value = mmh.GetMax();
                    _     = mmh.ExtractMax();
                }

                extracted.Add(value);
            }

            Assert.IsTrue(ordered.SequenceEqual(extracted));
        }
Esempio n. 2
0
        public void EmptyHeapOperations()
        {
            var heap = new MinMaxHeap <double>(1, Comparer <double> .Default);

            Assert.True(heap.Count == 0);

            Assert.ThrowsAny <Exception>(() =>
            {
                var x = heap.Minimum;
            });

            Assert.ThrowsAny <Exception>(() =>
            {
                var x = heap.Maximum;
            });

            Assert.ThrowsAny <Exception>(() =>
            {
                var x = heap.PopMinimum();
            });

            Assert.ThrowsAny <Exception>(() =>
            {
                var x = heap.PopMaximum();
            });

            Assert.True(heap.Count == 0);
        }
Esempio n. 3
0
        /// <summary>
        /// Finds the closest contact in the network. Does several round trips to the network
        /// </summary>
        /// <param name="target">The target.</param>
        /// <returns>an IEnumerable&lt;contact&gt; in order of distance from the target. Can be cast into a GetClosestNodes.ClosestResults</contact></returns>
        public IEnumerable <Contact> GetClosestContacts(Identifier512 target, Func <Contact, bool> terminate = null)
        {
            MinMaxHeap <Contact> heap = new MinMaxHeap <Contact>(new ContactComparer(target), contacts.ClosestNodes(target).Take(RoutingTable.Configuration.LookupConcurrency));

            HashSet <Identifier512> contacted = new HashSet <Identifier512>();

            contacted.Add(RoutingTable.LocalIdentifier);

            int iterations = 0;
            HashSet <Contact> uniqueDiscoveries;

            do
            {
                iterations++;

                uniqueDiscoveries = new HashSet <Contact>(                                                      //hashet means we only get each result once
                    heap                                                                                        //from the set of results we know about
                    .Where(c => !contacted.Contains(c.Identifier))                                              //which we have not already contacted
                    .SelectMany(c =>
                {
                    try { return(RemoteGetClosest(RoutingTable.LocalContact, c, target, RoutingTable.Configuration.LookupConcurrency, RoutingTable.Configuration.LookupTimeout)); }
                    catch (TimeoutException) { return(null); }
                })                                                                                          //select the closest ones they know about
                    .Where(n => n != null)
                    .Where(r => !heap.Contains(r)));                                                        //remove the results we already know about

                //Make the system aware of these potentially new nodes
                foreach (var c in uniqueDiscoveries)
                {
                    contacts.Update(c);
                }

                //make sure we never contact these nodes again
                contacted.UnionWith(heap.Select(a => a.Identifier));

                //add the new results
                heap.AddMany(uniqueDiscoveries);

                while (heap.Count > RoutingTable.Configuration.LookupConcurrency)
                {
                    heap.RemoveMax();
                }

                if (terminate != null)
                {
                    if (uniqueDiscoveries.Where(a => terminate(a)).FirstOrDefault() != null)
                    {
                        break;
                    }
                }
            }while (uniqueDiscoveries.Count != 0 && heap.Minimum.Identifier != target);

            return(new ClosestResults(heap, iterations));
            //while (heap.Count > 0)
            //    yield return heap.RemoveMin();
        }
Esempio n. 4
0
        public static void GetMaxTest <T>(IEnumerable <T> collection)
        {
            var emptyHeap = new MinMaxHeap <int>();
            var mmh       = new MinMaxHeap <T>(collection);

            var maxValue = mmh.GetMax();

            Assert.Throws <InvalidOperationException>(() => emptyHeap.GetMax());
            Assert.AreEqual(collection.Max(), maxValue);
        }
Esempio n. 5
0
        public static void ExtractMinTest <T>(IEnumerable <T> collection)
        {
            var ordered   = collection.OrderBy(x => x);
            var mmh       = new MinMaxHeap <T>(collection);
            var emptyHeap = new MinMaxHeap <T>();

            var first  = mmh.ExtractMin();
            var second = mmh.GetMin();

            Assert.Throws <InvalidOperationException>(() => emptyHeap.ExtractMin());
            Assert.AreEqual(ordered.ElementAt(0), first);
            Assert.AreEqual(ordered.ElementAt(1), second);
            Assert.AreEqual(collection.Count() - 1, mmh.Count);
        }
Esempio n. 6
0
        public void ClearHeap()
        {
            var heap = new MinMaxHeap <double>(2, Comparer <double> .Default);

            Assert.Equal(heap.Count, 0);

            heap.Push(Math.E);
            Assert.Equal(heap.Count, 1);

            heap.Clear();
            Assert.Equal(heap.Count, 0);

            heap.Push(Math.PI);
            Assert.Equal(heap.Minimum, Math.PI);
        }
Esempio n. 7
0
        public static void AddTest <T>(IEnumerable <T> collection)
        {
            var mmh = new MinMaxHeap <T>();

            foreach (var item in collection)
            {
                mmh.Add(item);
            }
            var minValue = mmh.GetMin();
            var maxValue = mmh.GetMax();

            Assert.AreEqual(collection.Min(), minValue);
            Assert.AreEqual(collection.Max(), maxValue);
            Assert.AreEqual(collection.Count(), mmh.Count);
        }
Esempio n. 8
0
        public static void CustomComparerTest()
        {
            var arr      = new [] { "aaaa", "c", "dd", "bbb" };
            var comparer = Comparer <string> .Create((a, b) => Comparer <int> .Default.Compare(a.Length, b.Length));

            var mmh = new MinMaxHeap <string>(comparer: comparer);

            foreach (var s in arr)
            {
                mmh.Add(s);
            }

            Assert.AreEqual(comparer, mmh.Comparer);
            Assert.AreEqual("c", mmh.GetMin());
            Assert.AreEqual("aaaa", mmh.GetMax());
        }
Esempio n. 9
0
        public void HeapCapacity()
        {
            var heap = new MinMaxHeap <double>(1, Comparer <double> .Default);

            Assert.True(heap.Capacity == 1);
            Assert.True(heap.Count == 0);

            heap.Push(Math.PI);
            Assert.True(heap.Capacity == 1);
            Assert.True(heap.Count == 1);
            Assert.ThrowsAny <Exception>(() =>
            {
                heap.Push(Math.E);
            });
            Assert.True(heap.Capacity == 1);
            Assert.True(heap.Count == 1);
        }
Esempio n. 10
0
        public void PopCorrectness()
        {
            // Generate random values
            var rng    = new Random(1);
            var values = new double[20];

            for (var i = 0; i < values.Length; i++)
            {
                values[i] = -Math.Log(rng.NextDouble());
            }

            // Push them on the heap
            var heap = new MinMaxHeap <double>(values.Length, Comparer <double> .Default);

            foreach (var value in values)
            {
                heap.Push(value);
            }

            // Sort them, so we know what order they should come out in
            Array.Sort(values);

            // Pop elements and make sure they come out in that order
            var minIndex = 0;
            var maxIndex = values.Length - 1;

            for (var i = 0; i < values.Length; i++)
            {
                Assert.Equal(heap.Count, values.Length - i);
                Assert.Equal(heap.Minimum, values[minIndex]);
                Assert.Equal(heap.Maximum, values[maxIndex]);

                // Randomly pop either minimum or maximum
                if (rng.NextDouble() < 0.5)
                {
                    Assert.Equal(heap.PopMinimum(), values[minIndex]);
                    minIndex++;
                }
                else
                {
                    Assert.Equal(heap.PopMaximum(), values[maxIndex]);
                    maxIndex--;
                }
            }
        }
Esempio n. 11
0
        public void SingleItemHeapOperations()
        {
            var heap = new MinMaxHeap <double>(1, Comparer <double> .Default);

            Assert.Equal(heap.Count, 0);

            heap.Push(Math.PI);
            Assert.Equal(heap.Count, 1);
            Assert.Equal(heap.Minimum, Math.PI);
            Assert.Equal(heap.Maximum, Math.PI);
            Assert.Equal(heap.PopMinimum(), Math.PI);
            Assert.Equal(heap.Count, 0);

            heap.Push(Math.E);
            Assert.Equal(heap.Count, 1);
            Assert.Equal(heap.PopMaximum(), Math.E);
            Assert.Equal(heap.Count, 0);
        }
Esempio n. 12
0
        public void PushOrderIrrelevant()
        {
            double[] values = { 1.0, 2.0, 3.0, 4.0, 5.0 };

            // Insert values in different orders, make sure
            // resuts are same

            var rng = new Random(1);

            for (var i = 0; i < 10; i++)
            {
                // Shuffle values
                for (var j = 0; j < values.Length; j++)
                {
                    var k = rng.Next(j, values.Length);
                    var t = values[j];
                    values[j] = values[k];
                    values[k] = t;
                }

                // Push in shuffled order
                var heap = new MinMaxHeap <double>(values.Length, Comparer <double> .Default);
                foreach (var value in values)
                {
                    heap.Push(value);
                }

                // Pop order should always be same
                Assert.Equal(heap.Count, 5);
                Assert.Equal(heap.PopMinimum(), 1.0);
                Assert.Equal(heap.PopMaximum(), 5.0);
                Assert.Equal(heap.PopMaximum(), 4.0);
                Assert.Equal(heap.PopMinimum(), 2.0);
                Assert.Equal(heap.PopMinimum(), 3.0);
                Assert.Equal(heap.Count, 0);
            }
        }
Esempio n. 13
0
        static void HeapTest()
        { 
            MinMaxHeap<int> heapRemoveMin = new MinMaxHeap<int>();
            heapRemoveMin.DebugCheckHeapProperty = true;
            MinMaxHeap<int> heapRemoveMax = new MinMaxHeap<int>();
            heapRemoveMax.DebugCheckHeapProperty = true;
            List<int> doubleCheckMin = new List<int>();
            List<int> doubleCheckMax = new List<int>();
            Random r = new Random();

            // Generate the list of numbers to populate the heaps and to check against
            if (true)
            {
                for (int i = 0; i < 700; i++)
                {
                    int randInt = r.Next(-10000, 10000);
                    doubleCheckMin.Add(randInt);
                }
            }
            else
            {
                // Manually test degenerate cases
                doubleCheckMin.Add(-55);
                doubleCheckMin.Add(31);
                doubleCheckMin.Add(-93);
                //doubleCheckMin.Add(64);
            }

            for (int i = 0; i < doubleCheckMin.Count; i++)
            {
                int randInt = doubleCheckMin[i];
                // heap.Add("" + i, i);
                heapRemoveMin.Add(randInt, randInt);
                heapRemoveMax.Add(randInt, randInt);
                doubleCheckMax.Add(randInt);
            }
            doubleCheckMin.Sort(); // Default. Ascending
            doubleCheckMax.Sort(delegate (int x, int y)
            {
                if (x == y) return 0;
                if (x > y) return -1;
                if (x < y) return 1;
                return 0;
            });
            Console.WriteLine(" -- NOW REMOVE MIN --");
            int checkCount = 0;
            while (heapRemoveMin.Count > 0)
            {
                int min = heapRemoveMin.FindMin();
                if (doubleCheckMin[checkCount] != min)
                {
                    throw new Exception("WRONG!");
                }
                heapRemoveMin.RemoveMin();
                checkCount++;
                Console.WriteLine(min);
            }
            Console.WriteLine(" -- NOW REMOVE MAX --");
            checkCount = 0;
            while (heapRemoveMax.Count > 0)
            {
                //Console.WriteLine("iteration " + checkCount);
                //Console.WriteLine(heapRemoveMax.PrintTree());
                int max = heapRemoveMax.RemoveMax();
                if (doubleCheckMax[checkCount] != max)
                {
                    throw new Exception("WRONG!");
                }
                checkCount++;
                Console.WriteLine(max);
            }
        }
Esempio n. 14
0
 internal ClosestResults(MinMaxHeap <Contact> heap, int iterations)
 {
     this.heap  = heap;
     Iterations = iterations;
 }