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)); }
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); }
/// <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<contact> 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(); }
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); }
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); }
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); }
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); }
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()); }
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); }
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--; } } }
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); }
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); } }
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); } }
internal ClosestResults(MinMaxHeap <Contact> heap, int iterations) { this.heap = heap; Iterations = iterations; }