public static void DoTest () { BinaryMinHeap<long> minHeap = new BinaryMinHeap<long> (Comparer<long>.Default); minHeap.Add (23); minHeap.Add (42); minHeap.Add (4); minHeap.Add (16); minHeap.Add (8); minHeap.Add (15); minHeap.Add (9); minHeap.Add (55); minHeap.Add (0); minHeap.Add (34); minHeap.Add (12); minHeap.Add (2); minHeap.Add (93); minHeap.Add (14); minHeap.Add (27); var array = minHeap.ToArray (); Debug.Assert (array.Length == minHeap.Count, "Wrong size."); var list = minHeap.ToList (); Debug.Assert (list.Count == minHeap.Count, "Wrong size."); array.HeapSortDescending(); var maxHeap = minHeap.ToMaxHeap (); Debug.Assert (maxHeap.Peek() == array[0], "Wrong maximum."); }
public void TestBinaryMinHeap(BinaryMinHeap <char> sut) { var expected = new[] { 'a', 'b', 'd', 'e', 'c', 'f', 'g' }; var actual = expected.Select(_ => sut.ExtractMinimum()); Assert.True(expected.SequenceEqual(actual.Select(_ => _.Id))); }
public static void DoTest() { BinaryMinHeap <long> minHeap = new BinaryMinHeap <long>(Comparer <long> .Default); minHeap.Add(23); minHeap.Add(42); minHeap.Add(4); minHeap.Add(16); minHeap.Add(8); minHeap.Add(15); minHeap.Add(9); minHeap.Add(55); minHeap.Add(0); minHeap.Add(34); minHeap.Add(12); minHeap.Add(2); minHeap.Add(93); minHeap.Add(14); minHeap.Add(27); var array = minHeap.ToArray(); Assert.True(array.Length == minHeap.Count, "Wrong size."); var list = minHeap.ToList(); Assert.True(list.Count == minHeap.Count, "Wrong size."); array.HeapSortDescending(); var maxHeap = minHeap.ToMaxHeap(); Assert.True(maxHeap.Peek() == array[0], "Wrong maximum."); }
private IEnumerable <Edge> GetMinimumSpanningTreeEdgesBad(Dictionary <char, List <Edge> > g) { var h = new BinaryMinHeap <char>(); var vte = new Dictionary <char, Edge>(); // Fill Heap var isFirst = true; foreach (char key in g.Keys) { if (isFirst) { h.Add(new BinaryMinHeap <char> .Node { Id = key, Weight = 0 }); isFirst = false; } else { h.Add(new BinaryMinHeap <char> .Node { Id = key, Weight = int.MaxValue }); } } var result = new List <Edge>(); while (h.HasItem()) { var v = h.ExtractMinimum(); vte.TryGetValue(v.Id, out Edge ste); if (ste != null) { result.Add(ste); } foreach (Edge e in g[v.Id]) { char adj = e.V2; if (!h.Contains(adj)) { continue; } var node = h.GetNode(adj); if (node.Weight > e.Weight) { node.Weight = e.Weight; h.Decrease(node); if (!vte.ContainsKey(node.Id)) { vte.Add(node.Id, e); } vte[node.Id] = e; } } } return(result); }
private static void TestBinaryMinHeap() { BinaryMinHeap <String> heap = new BinaryMinHeap <String>(); heap.AddNode(3, "Tushar"); heap.AddNode(4, "Ani"); heap.AddNode(8, "Vijay"); heap.AddNode(10, "Pramila"); heap.AddNode(5, "Roy"); heap.AddNode(6, "NTF"); heap.PrintHeap(); heap.Decrease("Pramila", 1); heap.Decrease("Vijay", 1); heap.Decrease("Ani", 11); heap.Decrease("NTF", 4); heap.PrintHeap(); var node = heap.extractMin(); while (node != null) { Console.WriteLine("Min Node extracted is :" + node.Data + " " + node.Weight); heap.PrintHeap(); node = heap.extractMin(); } }
public static IEnumerable <object[]> GetSampleBinaryHeap() { var sut = new BinaryMinHeap <char>(); var a = new BinaryMinHeap <char> .Node { Id = 'a', Weight = -1 }; var b = new BinaryMinHeap <char> .Node { Id = 'b', Weight = 2 }; var c = new BinaryMinHeap <char> .Node { Id = 'c', Weight = 6 }; var d = new BinaryMinHeap <char> .Node { Id = 'd', Weight = 4 }; var e = new BinaryMinHeap <char> .Node { Id = 'e', Weight = 5 }; var f = new BinaryMinHeap <char> .Node { Id = 'f', Weight = 7 }; var g = new BinaryMinHeap <char> .Node { Id = 'g', Weight = 8 }; sut.Add(a); sut.Add(b); sut.Add(c); sut.Add(d); sut.Add(e); sut.Add(f); sut.Add(g); yield return(new object[] { sut }); }
/** * <summary> * Search for the paths between the start node and the goal node * </summary> * * <param name="start"></param> * <param name="goal"></param> * * <returns> * List<NavigationNode> * </returns> */ public List <NavigationNode> Search(NavigationNode start, NavigationNode goal) { this.PriorityQueue = new BinaryMinHeap(); this.Explored = new List <NavigationNode>(); this.Paths = new List <NavigationNode>(); this.PriorityQueue.Insert(start); start.CameFrom = null; start.GScore = 0; start.FScore = this.Heuristic(start, goal); while (this.PriorityQueue.NotEmpty()) { NavigationNode current = this.PriorityQueue.Extract(); if (current.ID == goal.ID) { return(this.Paths = this.ReconstructPath(current)); } for (int i = 0; i < current.Neighbours.Count; i++) { NavigationNode neighbour = current.Neighbours[i]; if ( neighbour == null || neighbour.OccupiedBy != null ) { continue; } var tentativeGScore = current.GScore + this.MovementCost(current, neighbour); if (tentativeGScore < neighbour.GScore) { neighbour.CameFrom = current; neighbour.GScore = tentativeGScore; neighbour.FScore = neighbour.GScore + this.Heuristic(neighbour, goal); if (!neighbour.Explored) { neighbour.Explored = true; this.Explored.Add(neighbour); this.PriorityQueue.Insert(neighbour); } } } // Set the explored flag current.Explored = true; this.Explored.Add(current); } this.ResetFlags(); return(this.Paths); }
public static List <Edge <T> > GetMSTUsingPrims <T>(this Graph <T> g) { BinaryMinHeap <Vertex <T> > minHeap = new BinaryMinHeap <Vertex <T> >(); //Set all nodes in hash map to infinity Dictionary <Vertex <T>, Edge <T> > vertexToEdgeMap = new Dictionary <Vertex <T>, Edge <T> >(); //Final result var result = new List <Edge <T> >(); //insert all vertices with infinite value initially. foreach (var v in g.AllVertex.Values) { minHeap.AddNode(Int32.MaxValue, v); } //Start from Random Vertex and decrease min heap to 0 Vertex <T> startVertex = g.AllVertex.FirstOrDefault().Value; minHeap.Decrease(startVertex, 0); //iterate till heap + map has elements in it while (!minHeap.IsEmpty()) { //Extract the min vertex from heap var minVertex = minHeap.extractMin().Data; //get the corresponding edge for this vertex if present and add it to final result. //This edge wont be present for first vertex. Edge <T> spanningTreeEdge = vertexToEdgeMap.ContainsKey(minVertex) ? vertexToEdgeMap[minVertex] : null; if (spanningTreeEdge != null) { result.Add(spanningTreeEdge); } //Iterate through all the edges for the current minVertex foreach (var edge in minVertex.GetAdjEdges()) { Vertex <T> otherVertex = GetVertexForEdge(minVertex, edge); //Check if the other vertex already exists in the map and weight attached is greater than weight of the edge. If yes, replace if (minHeap.ContainsData(otherVertex) && minHeap.GetWeight(otherVertex) > edge.Weight) { minHeap.Decrease(otherVertex, edge.Weight); if (vertexToEdgeMap.ContainsKey(otherVertex)) { vertexToEdgeMap[otherVertex] = edge; } else { vertexToEdgeMap.Add(otherVertex, edge); } } } } return(result); }
public void GivenKeepMin2Items_AddInReverseOrder_ShouldHold3Not4() { _intHeap = BinaryMinHeap <int> .CreateWithSizeLimit(new IntComparer(), 2); Assert.AreEqual(0, _intHeap.Add(4)); Assert.AreEqual(0, _intHeap.Add(3)); Assert.AreEqual(0, _intHeap.Add(2)); // level 2 is now full, should discard on next add Assert.AreEqual(4, _intHeap.Add(1)); }
public void MinHeapWithNumbers() { var heap = new BinaryMinHeap <int>(); foreach (var number in Enumerable.Range(1, 10).Reverse()) { heap.Push(number); } var minimumNumber = heap.Pop(); Assert.That(minimumNumber, Is.EqualTo(1)); }
public void HeapifyUnsortedCollectionAndCheckIfExtractedInSortedOrder() { var heap = new BinaryMinHeap <int>(); var unsortedList = new List <int>(); int maxHeapElement = 50000; int minHeapElement = -50000; int addedElements = 0; //Adding every seventh number, then every fifth number, //every third and at last all numbers //NOTE: some items are added more than once for (int i = 7; i > 0; i -= 2) { int el = minHeapElement; while (el <= maxHeapElement) { unsortedList.Add(el); addedElements++; el += i; } } heap.Heapify(unsortedList); if (heap.Count != addedElements) { Assert.Fail("1"); } int removedElements = 0; var min = heap.PeekMin(); while (!heap.IsEmpty) { if (min > heap.PeekMin()) { Assert.Fail("2"); } min = heap.PopMin(); removedElements++; } Assert.IsTrue(heap.IsEmpty && heap.Count == 0 && addedElements == removedElements); }
public void ReplacingMinElementAndCheckingIfExtractedInSortedOrder() { var heap = new BinaryMinHeap <int>(); int maxHeapElement = 50000; int minHeapElement = -50000; int addedElements = 0; //Adding every seventh number, then every fifth number, //every third and at last all numbers //NOTE: some items are added more than once for (int i = 7; i > 0; i -= 2) { int el = minHeapElement; while (el <= maxHeapElement) { heap.Add(el); addedElements++; el += i; } } if (heap.Count != addedElements) { Assert.Fail(); } heap.ReplaceMin(int.MaxValue); heap.ReplaceMin(int.MaxValue); heap.ReplaceMin(int.MaxValue); int removedElements = 0; var min = heap.PeekMin(); while (!heap.IsEmpty) { if (min > heap.PeekMin()) { Assert.Fail(); } min = heap.PopMin(); removedElements++; } Assert.IsTrue(heap.IsEmpty && heap.Count == 0 && addedElements == removedElements); }
public void TestBinaryMinHeapDecrease() { var sut = new BinaryMinHeap <char>(); var a = new BinaryMinHeap <char> .Node { Id = 'a', Weight = -1 }; var b = new BinaryMinHeap <char> .Node { Id = 'b', Weight = 2 }; var c = new BinaryMinHeap <char> .Node { Id = 'c', Weight = 6 }; var d = new BinaryMinHeap <char> .Node { Id = 'd', Weight = 4 }; var e = new BinaryMinHeap <char> .Node { Id = 'e', Weight = 5 }; var f = new BinaryMinHeap <char> .Node { Id = 'f', Weight = 7 }; var g = new BinaryMinHeap <char> .Node { Id = 'g', Weight = 8 }; sut.Add(a); sut.Add(b); sut.Add(c); sut.Add(d); sut.Add(e); sut.Add(f); sut.Add(g); f.Weight = -2; sut.Decrease(f); g.Weight = -3; sut.Decrease(g); var expected = new[] { 'g', 'f', 'a', 'b', 'd', 'e', 'c' }; var actual = expected.Select(_ => sut.ExtractMinimum()); //foreach (BinaryMinHeap<char>.Node node in actual) //{ // _output.WriteLine(node.ToString()); //} Assert.True(expected.SequenceEqual(actual.Select(_ => _.Id))); }
public void AddingElementsWithCustomComparerAndCheckingIfExtractedInSortedOrder() { //Creating heap with reversed comparer var heap = new BinaryMinHeap <int>(Comparer <int> .Create( (x, y) => y.CompareTo(x))); int maxHeapElement = 50000; int minHeapElement = -50000; int addedElements = 0; //Adding every seventh number, then every fifth number, //every third and at last all numbers //NOTE: some items are added more than once for (int i = 7; i > 0; i -= 2) { int el = minHeapElement; while (el <= maxHeapElement) { heap.Add(el); addedElements++; el += i; } } if (heap.Count != addedElements) { Assert.Fail(); } int removedElements = 0; // because of the reversed comparer var max = heap.PeekMin(); while (!heap.IsEmpty) { if (max < heap.PeekMin()) { Assert.Fail(); } max = heap.PopMin(); removedElements++; } Assert.IsTrue(heap.IsEmpty && heap.Count == 0 && addedElements == removedElements); }
public void MinHeapWithNodes() { var heap = new BinaryMinHeap <Node>(new NodeComparer()); foreach (var number in Enumerable.Range(1, 10).Reverse()) { heap.Push(new Node { PredictedTotalCost = number }); } var minimumNumber = heap.Pop().PredictedTotalCost; Assert.That(minimumNumber, Is.EqualTo(1)); }
void Start() { BinaryMinHeap <TestClass> minHeap = new BinaryMinHeap <TestClass>(); TestClass nodeToChangeKey = new TestClass(); minHeap.Insert(new HeapNode <TestClass>(6, nodeToChangeKey)); minHeap.Insert(new HeapNode <TestClass>(3, new TestClass())); minHeap.Insert(new HeapNode <TestClass>(5, new TestClass())); minHeap.Insert(new HeapNode <TestClass>(1, new TestClass())); minHeap.Insert(new HeapNode <TestClass>(7, new TestClass())); minHeap.Insert(new HeapNode <TestClass>(8, new TestClass())); string debugString = "After insertion: "; for (int i = 0; i < minHeap.nodes.Count; i++) { debugString += minHeap.nodes[i].key + ", "; } Debug.Log(debugString); Debug.Log("Extracted value: " + minHeap.ExtractRoot().key); debugString = "After extraction: "; for (int i = 0; i < minHeap.nodes.Count; i++) { debugString += minHeap.nodes[i].key + ", "; } Debug.Log(debugString); minHeap.ChangeKey(nodeToChangeKey, 2); debugString = "After changing 6 to 2: "; for (int i = 0; i < minHeap.nodes.Count; i++) { debugString += minHeap.nodes[i].key + ", "; } Debug.Log(debugString); minHeap.ChangeKey(nodeToChangeKey, 11); debugString = "After changing 2 to 11: "; for (int i = 0; i < minHeap.nodes.Count; i++) { debugString += minHeap.nodes[i].key + ", "; } Debug.Log(debugString); }
public void TestBinaryMinHeapContains(BinaryMinHeap <char> sut) { Assert.True(sut.Contains('a')); Assert.True(sut.Contains('b')); Assert.True(sut.Contains('c')); Assert.True(sut.Contains('d')); Assert.True(sut.Contains('e')); Assert.True(sut.Contains('f')); Assert.True(sut.Contains('g')); Assert.False(sut.Contains('1')); Assert.False(sut.Contains('x')); Assert.False(sut.Contains('3')); Assert.False(sut.Contains('y')); Assert.False(sut.Contains('z')); }
public void AddAndRemoveElements() { var r = new Random(); const int totalElements = 10000; var elements = Enumerable.Range(1, totalElements).Select(x => r.Next(totalElements)).ToList(); var target = new BinaryMinHeap<int>(); foreach (var i in elements) { target.Add(i); } Assert.AreEqual(totalElements, target.Count); elements.Sort(); for (var i = 0; i < totalElements; i++) { Assert.AreEqual(elements[i], target.RemoveMin()); } }
public void PerformanceComparism() { var simpleHeap = new BinaryMinHeap <Node>(new NodeComparer()); var indexedHeap = new IndexedLinkedList <Node>(new NodeComparer(), new NodeIndexer()); var count = 1000; this.PushNodes(simpleHeap, count); this.PushNodes(indexedHeap, count); var pushSimple = this.PushNodes(simpleHeap, count); var pushIndexed = this.PushNodes(indexedHeap, count); this.PopNodes(simpleHeap, count); this.PopNodes(indexedHeap, count); var popSimple = this.PopNodes(simpleHeap, count); var popIndexed = this.PopNodes(indexedHeap, count); Assert.Pass($"(PUSH) BinaryMinHeap: {pushSimple.Elapsed}, IndexedLinkedList: {pushIndexed.Elapsed}\r\n(POP) BinaryMinHeap: {popSimple.Elapsed}, IndexedLinkedList: {popIndexed.Elapsed}"); }
public void CheckOrderInHeap_RandomOrder_ReturnsTrue() { BinaryMinHeap <long> minHeap = new BinaryMinHeap <long>(Comparer <long> .Default); minHeap.Add(23); minHeap.Add(42); minHeap.Add(4); minHeap.Add(16); minHeap.Add(8); minHeap.Add(1); minHeap.Add(3); minHeap.Add(100); minHeap.Add(5); minHeap.Add(7); var isRightOrder = IsRightOrderInHeap <long>(minHeap); Assert.IsTrue(isRightOrder); }
public static void CheckOrderInHeap_DecreasingOrder_ReturnsTrue() { BinaryMinHeap <long> minHeap = new BinaryMinHeap <long>(Comparer <long> .Default); minHeap.Add(10); minHeap.Add(9); minHeap.Add(8); minHeap.Add(7); minHeap.Add(6); minHeap.Add(5); minHeap.Add(4); minHeap.Add(3); minHeap.Add(2); minHeap.Add(1); var isRightOrder = IsRightOrderInHeap <long>(minHeap); Assert.True(isRightOrder); }
public Dictionary <Node, int> shortestPath(Graph graph, Node soruceNode) { BinaryMinHeap <Node> minHeap = new BinaryMinHeap <Node>(); Dictionary <Node, int> distance = new Dictionary <Node, int>(); Dictionary <Node, Node> parent = new Dictionary <Node, Node>(); foreach (Node node in graph.nodes) { minHeap.add(int.MaxValue, node); } minHeap.decrease(soruceNode, 0); distance.Add(soruceNode, 0); parent.Add(soruceNode, null); while (!minHeap.isEmpty()) { BinaryMinHeap <Node> .NestedNode heapNode = minHeap.extractMinNode(); Node current = heapNode.key; distance[current] = heapNode.weight; foreach (Edge edge in current.edges) { Node adjacent = getNodeForEdge(current, edge); if (!minHeap.containsData(adjacent)) { continue; } int newDistance = distance[current] + edge.weight; if (minHeap.getWeight(adjacent) > newDistance) { minHeap.decrease(adjacent, newDistance); parent[adjacent] = current; } } } return(distance); }
public static Dictionary <Vertex <T>, Int32> DjkstrasAlgo <T>(this Graph <T> g, Vertex <T> source, Dictionary <Vertex <T>, Vertex <T> > pathMap) { BinaryMinHeap <Vertex <T> > minHeap = new BinaryMinHeap <Vertex <T> >(); Dictionary <Vertex <T>, Int32> distanceMap = new Dictionary <Vertex <T>, int>(); //Dictionary<Vertex<T>, Vertex<T>> pathMap = new Dictionary<Vertex<T>, Vertex<T>>(); //Set all weights to infinity in minHeap foreach (var v in g.AllVertex.Values) { minHeap.AddNode(Int32.MaxValue, v); } //Decrease the weight of source to 0 minHeap.Decrease(source, 0); pathMap.Add(source, null); while (!minHeap.IsEmpty()) { //Extract the min int weight = minHeap.MinNode().Weight; var currentVertex = minHeap.extractMin().Data; distanceMap.AddOrUpdateDictionary(currentVertex, weight); foreach (var edge in currentVertex.GetAdjEdges()) { var otherVertex = GetVertexForEdge(currentVertex, edge); if (minHeap.ContainsData(otherVertex) && minHeap.GetWeight(otherVertex) > (edge.Weight + weight)) { minHeap.Decrease(otherVertex, (edge.Weight + weight)); pathMap.AddOrUpdateDictionary(otherVertex, currentVertex); } } } return(distanceMap); }
public static bool IsRightOrderInHeap <T>(BinaryMinHeap <T> binaryMinHeap) where T : IComparable <T> { var array = binaryMinHeap.ToArray(); for (int i = 0; i * 2 + 1 < array.Length; ++i) { int leftChildIndex = i * 2 + 1; int rightChildIndex = leftChildIndex + 1; if (array[i].CompareTo(array[leftChildIndex]) > 0) { return(false); } if (rightChildIndex < array.Length && array[i].CompareTo(array[rightChildIndex]) > 0) { return(true); } } return(true); }
/** * <summary> * Search the nodes from start to the goal * and get the paths * </summary> * * <param name="start">Node start</param> * <param name="goal">Node goal</param> * * <returns> * List<Node> paths * </returns> */ public List <Node> Search(Node start, Node goal) { // Paths List <Node> paths = new List <Node>(); // Priority queue BinaryMinHeap queue = new BinaryMinHeap(); queue.Insert(start); //start.SetCameFrom(null); start.SetGScore(0); start.SetFScore(this.Hueristic(start, goal)); // Filter out empty nodes List <Node> filtered = queue.GetNodes().FindAll((node) => { return(node != null); }); while (filtered.Count > 0) { Node current = queue.Extract(); // If the goal is found, get and return reconstructed paths if (current.GetID() == goal.GetID()) { return(paths = this.ReconstructPath(current)); } for (int i = 0; i < current.GetNeighbours().Count; i++) { Node neighbour = current.GetNeighbours()[i]; // The cost of moving to the next neighbour float tentativeGScore = current.GetGScore() + this.MovementCost(current, neighbour); // if the new gScore is less than the neighbour gScore if (tentativeGScore < neighbour.GetGScore()) { // Set neighbour cameFrom to the current neighbour.SetCameFrom(current); // Set the neighbour gScore to the lower gScore neighbour.SetGScore(tentativeGScore); // Set the new FScore neighbour.SetFScore(neighbour.GetGScore() + this.Hueristic(neighbour, goal)); bool exist = false; // Is the neighbour in the open set or priority queue for (int n = 0; n < queue.GetNodes().Count; n++) { Node node = queue.GetNodes()[n]; if (node != null && node.GetID() == neighbour.GetID()) { exist = true; break; } } if (!exist) { queue.Insert(neighbour); } } } } return(paths); }
public void CapacityConstructorThrowArgumentOutOfRangeException() { BinaryMinHeap <int> heap = new BinaryMinHeap <int>(-1); }
public void CapacityConstructor() { BinaryMinHeap <int> heap = new BinaryMinHeap <int>(5); Assert.IsNotNull(heap); }
private List <RiverNode> GenerateDownslopes(MapArray <int> bitmask) { var simplex = new Simplex2D(52562); MapArray <float> weights = new MapArray <float>(1000.0f); var rivernet = new List <RiverNode>(); var node_lookup = new Dictionary <GBTCorner, RiverNode>(); var queue = new BinaryMinHeap <QueueElement <RiverNode> >(); // Assign weights to each land vertex and add coast vertices to the queue. foreach (KeyValuePair <GBTCorner, int> kvp in bitmask.GetCornerEnumerator()) { if ((kvp.Value & 1) > 0) { weights[kvp.Key] = simplex.GetFractalNoise(4.0f * kvp.Key.position / Radius); if ((kvp.Value & 2) > 0) { RiverNode node = new RiverNode(kvp.Key); queue.Push(new QueueElement <RiverNode>(weights[kvp.Key], node)); rivernet.Add(node); node_lookup[kvp.Key] = node; } } } while (queue.Count > 0) { RiverNode node = queue.Pop().value; GBTCorner lowest = new GBTCorner(-1); float lowest_weight = 999.0f; // Find the neighboring land node with the lowest weight which has not already // been added to the network. foreach (GBTCorner adjacent in node.Vertex.GetAdjacent()) { if (CheckValidAdjacent(node, adjacent, bitmask, node_lookup) && weights[adjacent] < lowest_weight) { lowest_weight = weights[adjacent]; lowest = adjacent; } } // Add the lowest node to the network, and push it and the into the queue. if (lowest.isValid()) { var new_node = new RiverNode(lowest); new_node.Downslope = node; if (node.Left == null) { node.Left = new_node; // If the node hasn't been filled, add it to the queue again, but with a lower weight. weights[node.Vertex] += 0.05f; queue.Push(new QueueElement <RiverNode>(weights[node.Vertex], node)); } else if (node.Right == null) { node.Right = new_node; } node_lookup[lowest] = new_node; queue.Push(new QueueElement <RiverNode>(weights[lowest], new_node)); } } return(rivernet); }
public void ConvertingToBinaryMaxHeap() { var minHeap = new BinaryMinHeap <int>(); int maxHeapElement = 50000; int minHeapElement = -50000; int addedElements = 0; //Adding every seventh number, then every fifth number, //every third and at last all numbers //NOTE: some items are added more than once for (int i = 7; i > 0; i -= 2) { int el = minHeapElement; while (el <= maxHeapElement) { minHeap.Add(el); addedElements++; el += i; } } if (minHeap.Count != addedElements) { Assert.Fail(); } // Binary min heap with reversed comparer. Have to be the same as the max heap var reversedMinHeap = new BinaryMinHeap <int>(Comparer <int> .Create( (x, y) => y.CompareTo(x))); reversedMinHeap.Heapify(minHeap.ToArray()); var maxHeap = minHeap.ToMaxHeap(); if (maxHeap.Count != reversedMinHeap.Count) { Assert.Fail(); } var max1 = reversedMinHeap.PeekMin(); var max2 = maxHeap.PeekMax(); int removedElements = 0; while (!reversedMinHeap.IsEmpty && !maxHeap.IsEmpty) { if (max1 < reversedMinHeap.PeekMin()) { Assert.Fail(); } if (max2 < maxHeap.PeekMax()) { Assert.Fail(); } max1 = reversedMinHeap.PopMin(); max2 = maxHeap.PopMax(); removedElements++; if (max1 != max2) { Assert.Fail(); } } Assert.IsTrue(reversedMinHeap.IsEmpty && maxHeap.IsEmpty && reversedMinHeap.Count == 0 && maxHeap.Count == 0 && addedElements == removedElements); }
//finds the shortest path through the grid from the given start index to the given end index //If there is no path at all, then null is returned List <Index> dijkstra(Index start, Index end) { BinaryMinHeap <Node> unvisited = new BinaryMinHeap <Node>(dimensions.x * dimensions.y + 50); Dictionary <Index, Node> graph = new Dictionary <Index, Node>(); for (int i = 0; i < dimensions.x; i++) { for (int j = 0; j < dimensions.y; j++) { if (i == start.x && j == start.y) { Node n = createNode(start, end); n.visited = true; n.dist = 0; graph.Add(start, n); unvisited.addWithPriority(0, n); } else { Node n = createNode(new Index(i, j), end); unvisited.addWithPriority(Double.PositiveInfinity, n); graph.Add(n.pos, n); } } } Node current; while (unvisited.Size > 0) { current = unvisited.extractMin(); current.visited = true; foreach (Index p in validNeighbors(current.pos)) { Node n = graph[p]; if (!n.visited) { double newDist = current.dist + distance(current.pos, n.pos); if (newDist < n.dist) { n.dist = newDist; n.prev = current; unvisited.updatePriority(newDist, n); } } } } //check to make sure we actually found a path if (graph[end].prev == null) { return(null); } //reconstruct the path List <Index> path = new List <Index>(Math.Max(dimensions.x, dimensions.y)); current = graph[end]; path.Add(current.pos); while (current.prev != null) { path.Add(current.prev.pos); current = current.prev; } //flip the path path.Reverse(); return(path); }
private void Play(Difficulty difficulty, out int leastMana) { CombatState victoryState = null; Comparer <CombatState> stateComparer = Comparer <CombatState> .Create((a, b) => a.manaSpent.CompareTo(b.manaSpent)); BinaryMinHeap <CombatState> activeStates = new BinaryMinHeap <CombatState>(stateComparer); activeStates.Insert(new CombatState(difficulty)); while (activeStates.Count > 0) { CombatState prevState = activeStates.Extract(); if (victoryState != null && victoryState.manaSpent <= prevState.manaSpent) { break; } foreach (Spell spell in Spells) { if (victoryState != null && victoryState.manaSpent <= prevState.manaSpent + spell.manaCost) { continue; } CombatState nextState = prevState.DeepClone(); nextState.CastSpell(spell); switch (nextState.result) { case CombatState.Result.InProgress: activeStates.Insert(nextState); break; case CombatState.Result.Victory: if (victoryState == null || victoryState.manaSpent > nextState.manaSpent) { victoryState = nextState; } break; } } } Debug.Assert(victoryState != null, "Failed to find any sequence of spells to defeat the boss!"); Console.WriteLine($" -- Difficulty {difficulty} -- "); CombatState state = new CombatState(difficulty); foreach (Spell spell in victoryState.spellsCast) { state.CastSpell(spell); Console.Write($"{spell.name,-15}"); Console.Write($"Boss: {state.boss.hitPoints,2} "); Console.Write($"Player: {state.player.hitPoints,2} "); Console.Write($"Mana: {state.player.mana,3}"); Console.WriteLine(); } leastMana = victoryState.spellsCast.Sum(s => s.manaCost); }
public void ThrowExceptionWhenExtractingAnEmptyBinaryMinHeap() { var sut = new BinaryMinHeap <char>(); Assert.Throws <ArgumentOutOfRangeException>(() => sut.ExtractMinimum()); }