public static void InsertRange <T>(this FibonacciHeap <T> heap, IEnumerable <FibonacciHeapNode <T> > enumerable) { foreach (var item in enumerable) { heap.Insert(item); } }
public static int Dijkstra(Vertex from, Vertex to, Graph graph) { HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); // Initialize labels. foreach (var vertex in graph.Vertices) { var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, n); } int currentLabel = int.MaxValue; while (!visited.Contains(to)) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; currentLabel = currentNode.Key; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); } visited.Add(current); } return currentLabel; }
public IList <ILevelTile> CalculatePath(ILevelTile from, ILevelTile to) { target = to; openNodes = new FibonacciHeap <float>(); closedNodes = new HashSet <AStarNode>(); tilesToNodes = new Dictionary <ILevelTile, AStarNode>(); AStarNode startNode = new AStarNode(from, heuristic.GetDistance(from.CenterPos, to.CenterPos)); startNode.cost = 0; tilesToNodes.Add(from, startNode); openNodes.Insert(startNode); do { AStarNode currNode = (AStarNode)openNodes.ExtractMin(); if (currNode.tile.Equals(to)) { return(GetPathToNode(currNode)); } closedNodes.Add(currNode); ExpandNode(currNode); } while (openNodes.IsEmpty() == false); // No path found return(null); }
static void TestCase4() { var random = new Random(); var myHeap = new FibonacciHeap<double>(int.MinValue, Comparer<double>.Default); var thirdPartyHeap = new FastPriorityQueue<FastPriorityQueueNode>(1000); for (var i = 0; i < 1000; i++) { if (random.Next(3) == 0 && thirdPartyHeap.Any()) { var myResult = myHeap.ExtractMin(); var otherResult = thirdPartyHeap.Dequeue(); Assert(myResult.Item1); Assert(Math.Abs(myResult.Item2 - otherResult.Priority) < double.Epsilon); } else { var value = random.NextDouble()*10; myHeap.Insert(value); thirdPartyHeap.Enqueue(new FastPriorityQueueNode(), value); } } while (thirdPartyHeap.Any()) { var myResult = myHeap.ExtractMin(); var otherResult = thirdPartyHeap.Dequeue(); Assert(myResult.Item1); Assert(Math.Abs(myResult.Item2 - otherResult.Priority) < double.Epsilon); } }
public void FibonacciHeapMergeTestMinHeaps() { // create two minheaps based on the priority value of the elements. FibonacciHeap <HeapElement> heap1 = new FibonacciHeap <HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true); FibonacciHeap <HeapElement> heap2 = new FibonacciHeap <HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true); FillHeap(heap1, 100); FillHeap(heap2, 100); Assert.AreEqual(100, heap1.Count); Assert.AreEqual(100, heap2.Count); // merge heap1 into heap2. heap2 will be empty afterwards heap1.Merge(heap2); Assert.AreEqual(200, heap1.Count); Assert.AreEqual(0, heap2.Count); // check if they are inserted correctly HeapElement previous = heap1.ExtractRoot(); HeapElement current = heap1.ExtractRoot(); while (current != null) { Assert.IsTrue(previous.Priority <= current.Priority); previous = current; current = heap1.ExtractRoot(); } // heap1 should be empty as well Assert.AreEqual(0, heap1.Count); }
public void FibonacciHeapUpdateKeyMinHeap() { FibonacciHeap <HeapElement> heap = new FibonacciHeap <HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true); FillHeap(heap, 100); Assert.AreEqual(100, heap.Count); // add new element. Give it a priority of 50 HeapElement element = new HeapElement(50, "Value: 50"); heap.Insert(element); Assert.AreEqual(101, heap.Count); // update key to 10, using an action lambda heap.UpdateKey(element, (a, b) => a.Priority = b, 10); Assert.AreEqual(10, element.Priority); // check if the heap is still correct HeapElement previous = heap.ExtractRoot(); HeapElement current = heap.ExtractRoot(); while (current != null) { Assert.IsTrue(previous.Priority <= current.Priority); previous = current; current = heap.ExtractRoot(); } // heap should be empty Assert.AreEqual(0, heap.Count); }
public static void DecreaseKey_EmptyHeap_ThrowsCorrectException() { var heap = new FibonacciHeap <int>(); var item = new FHeapNode <int>(1); Assert.Throws <ArgumentException>(() => heap.DecreaseKey(item, 0)); }
public static void DecreaseKey_TryIncreaseKey_ThrowsCorrectException() { var heap = new FibonacciHeap <int>(); var item = heap.Push(1); Assert.Throws <InvalidOperationException>(() => heap.DecreaseKey(item, 2)); }
public void DeleteKey() { var heap = new FibonacciHeap <int, string>(HeapDirection.Increasing); int count = 0; var cells = new Dictionary <int, FibonacciHeapCell <int, string> >(); for (int i = 0; i < 10; ++i) { cells.Add(i, heap.Enqueue(i, i.ToString())); ++count; } int?lastValue = null; heap.Dequeue(); FibonacciHeapCell <int, string> deletedCell = cells[8]; heap.Delete(deletedCell); count -= 2; foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator()) { if (lastValue is null) { lastValue = value.Key; } Assert.IsFalse(lastValue > value.Key, "Heap condition has been violated."); Assert.AreNotEqual(deletedCell, value, "Found item that was deleted."); lastValue = value.Key; --count; } Assert.AreEqual(0, count, "Not all elements enqueued were dequeued."); }
public static void Union_NonEmptyHeap_ReturnsSortedOrder() { var oddHeap = new FibonacciHeap <int>(); for (int i = 1; i < 10; i += 2) { oddHeap.Push(i); } var evenHeap = new FibonacciHeap <int>(); for (int i = 0; i < 10; i += 2) { evenHeap.Push(i); } oddHeap.Union(evenHeap); for (int i = 0; i < 10; i++) { Assert.AreEqual(i, oddHeap.Pop()); } Assert.Zero(oddHeap.Count); Assert.Zero(evenHeap.Count); }
public void DecreaseKeyOnIncreasing() { var heap = new FibonacciHeap <int, string>(HeapDirection.Increasing); int count = 0; var cells = new Dictionary <int, FibonacciHeapCell <int, string> >(); for (int i = 0; i < 10; ++i) { cells.Add(i, heap.Enqueue(i, i.ToString())); ++count; } int?lastValue = null; heap.ChangeKey(cells[9], -1); foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator()) { if (lastValue is null) { lastValue = value.Key; } if (lastValue > value.Key) { Assert.Fail("Heap condition has been violated."); } lastValue = value.Key; --count; } Assert.AreEqual(0, count, "Not all elements enqueued were dequeued."); }
public void SimpleEnqueueDequeDecreasing() { var heap = new FibonacciHeap <int, string>(HeapDirection.Decreasing); int count = 0; for (int i = 0; i < 10; ++i) { heap.Enqueue(i, i.ToString()); ++count; } int?lastValue = null; foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator()) { if (lastValue is null) { lastValue = value.Key; } if (lastValue < value.Key) { Assert.Fail("Heap condition has been violated."); } lastValue = value.Key; --count; } Assert.AreEqual(0, count, "Not all elements enqueued were dequeued."); }
public void Merge() { var heap = new FibonacciHeap <int, string>(HeapDirection.Increasing); var heap2 = new FibonacciHeap <int, string>(HeapDirection.Increasing); int count = 0; for (int i = 11; i > 0; --i) { heap.Enqueue(i, i.ToString()); heap2.Enqueue(i * 11, i.ToString()); count += 2; } heap2.Merge(heap); int?lastValue = null; foreach (KeyValuePair <int, string> value in heap2.GetDestructiveEnumerator()) { if (lastValue is null) { lastValue = value.Key; } if (lastValue > value.Key) { Assert.Fail("Heap condition has been violated."); } lastValue = value.Key; --count; } Assert.AreEqual(0, count, "Not all elements enqueued were dequeued."); }
static void Main(string[] args) { var heap = new FibonacciHeap<int, int>(); heap.Insert(3, 3); heap.Insert(8, 8); heap.Insert(9, 9); heap.Insert(11, 11); heap.Insert(14, 14); heap.Insert(38, 38); heap.Insert(38, 49); heap.Insert(3, 56); heap.Insert(38, 18); heap.Insert(38, 17); heap.Insert(3, 4); //heap.Insert(3, 3); //heap.Insert(8, 8); //heap.Insert(9, 9); //heap.Insert(11, 11); //heap.Insert(14, 14); //heap.Insert(38, 38); //heap.Insert(49, 49); //heap.Insert(56, 56); //heap.Insert(18, 18); //heap.Insert(17, 17); //heap.Insert(4, 4); int len = heap.Count; for (int i = 0; i < len; i++) { var min = heap.DeleteMin(); Console.WriteLine(min); } }
public void IncreasingIncreaseKeyCascadeCut() { var heap = new FibonacciHeap <int, string>(HeapDirection.Increasing); int count = 0; var cells = new Dictionary <int, FibonacciHeapCell <int, string> >(); for (int i = 0; i < 10; ++i) { cells.Add(i, heap.Enqueue(i, i.ToString())); ++count; } int lastValue = heap.Top.Priority; heap.Dequeue(); --count; heap.ChangeKey(cells[5], 10); foreach (KeyValuePair <int, string> value in heap.GetDestructiveEnumerator()) { if (lastValue > value.Key) { Assert.Fail($"Heap condition has been violated: {lastValue} > {value.Key}"); } lastValue = value.Key; --count; } Assert.AreEqual(0, count, "Not all elements enqueued were dequeued."); }
public static void Print <TNode, TKey, TValue>([NotNull] this FibonacciHeap <TNode, TKey, TValue> thisValue) where TNode : FibonacciNode <TNode, TKey, TValue> { Console.WriteLine(); Console.WriteLine("Count: " + thisValue.Count); Console.WriteLine(); thisValue.WriteTo(Console.Out); }
public void Count_1Node_1Count() { var fh = new FibonacciHeap <int>(); fh.Push(7); Assert.AreEqual(1, fh.Count); }
public void Peek_1Node_CorrectValue() { var fh = new FibonacciHeap <int>(); fh.Push(3); Assert.AreEqual(3, fh.Peek()); }
/// <summary> /// Implementation of uniform-cost search algorithm using a Fibonacci heap data structure to minimize computing times /// </summary> /// <param name="source">The node on which to start the search</param> /// <param name="destination">The node we try to find the shortest path to, starting from source</param> public List <int> LeastCostPath(int source, int destination) { var Predecessor = new Dictionary <int, int>(); var Distance = new Dictionary <int, double>(); var Frontier = new FibonacciHeap <int, double>(0); Frontier.Insert(new FibonacciHeapNode <int, double>(source, 0)); var Explored = new List <int>(); Predecessor.Add(source, -1); //value of -1 indicates this node has no predecessors while (true) { if (Frontier.IsEmpty()) { throw new Exception("LeastCostPath: Failed to find path between source (" + source + ") and destination (" + destination + ")."); } var minNode = Frontier.RemoveMin(); if (minNode.Data == destination) { List <int> LCP = new List <int> { minNode.Data }; int pred = Predecessor[minNode.Data]; while (pred != -1) { LCP.Add(pred); pred = Predecessor[pred]; } LCP.Reverse(); return(LCP); } Explored.Add(minNode.Data); foreach (int neighbor in this.GetNeighbors(minNode.Data)) { if (!Explored.Contains(neighbor)) { var neighborCost = minNode.Key + AdjacencyMatrix[minNode.Data, neighbor]; Frontier.Insert(new FibonacciHeapNode <int, double>(neighbor, neighborCost)); if (Distance.TryGetValue(neighbor, out double cost)) { if (neighborCost < cost) { Predecessor[neighbor] = minNode.Data; Distance[neighbor] = neighborCost; } } else { Predecessor.Add(neighbor, minNode.Data); Distance.Add(neighbor, neighborCost); } } } } }
/// <summary> /// Implementation of Yen's algorithm which finds the shortest path between nodes, and then the /// K-1 shortest deviations from this path. Paths returned will be simple and loopless /// </summary> /// <param name="K">The number of shortest paths to find.</param> /// <param name="source">The node on which to start the search</param> /// <param name="destination">The node we try to find the shortest path to, starting from source</param> /// <returns></returns> public List <List <int> > KShortestPaths(int K, int source, int destination) { List <List <int> > ShortestPaths = new List <List <int> >(); var PotentialPaths = new FibonacciHeap <List <int>, double>(0); ShortestPaths.Add(LeastCostPath(source, destination)); //now find next K-1 shortest paths foreach (int k in Enumerable.Range(1, K - 1)) { //The spur node ranges from the first node to the next to last node in the previous k-shortest path. int spurNodeCount = ShortestPaths[k - 1].Count - 1; foreach (int i in Enumerable.Range(0, spurNodeCount)) { int spurNode = ShortestPaths[k - 1][i]; List <int> rootPath = ShortestPaths[k - 1].GetRange(0, i + 1); PSO_WeightedGraph AlteredGraph = this.Clone(); //temporarily remove edges to avoid retracing our steps foreach (List <int> shortPath in ShortestPaths) { if (rootPath.SequenceEqual(shortPath.Take(i + 1))) { AlteredGraph.AdjacencyMatrix[shortPath[i], shortPath[i + 1]] = 0; } } //To avoid looping back over a previous path, we disconnect nodes in the root path (except the spur node) //by setting the weights of the edges that connect them to the graph to 0 foreach (int x in Enumerable.Range(0, Size).Where(a => a != spurNode & rootPath.Contains(a))) { var v = Vector <double> .Build.Sparse(Size); AlteredGraph.AdjacencyMatrix.SetColumn(x, v); AlteredGraph.AdjacencyMatrix.SetRow(x, v); } //build spur path and connect the spur path to the root List <int> spurPath = new List <int>(); //finding the least cost path may fail due to removing the edges above; just ignore and continue try { spurPath = AlteredGraph.LeastCostPath(spurNode, destination); } catch (Exception ex) { break; } List <int> totalPath = rootPath; totalPath.AddRange(spurPath.Where(node => node != spurNode).ToList()); PotentialPaths.Insert(new FibonacciHeapNode <List <int>, double>(totalPath, this.PathCost(totalPath))); } if (PotentialPaths.IsEmpty()) { break; } ShortestPaths.Add(PotentialPaths.RemoveMin().Data); } return(ShortestPaths); }
public void FibonacciHeapContainsTest() { FibonacciHeap <Int32, String> heap = new FibonacciHeap <Int32, String>(this.values); for (Int32 number = -1000; number < 1000; number++) { heap.Contains(number).ShouldBe(this.values.Contains(new KeyValuePair <Int32, String>(number, number.ToString()))); } }
public void Count_2Node_2Count() { var fh = new FibonacciHeap <int>(); fh.Push(7); fh.Push(8); Assert.AreEqual(2, fh.Count); }
public override Node Peek() { FibonacciHeap <HeapObject> .FibonacciHeapNode fNode = Heap.Minimum; if (fNode == null) { return(null); } return(fNode.Key.Node); }
public void Peek_2NodesSmallerLast_CorrectValue() { var fh = new FibonacciHeap <int>(); fh.Push(3); fh.Push(2); Assert.AreEqual(2, fh.Peek()); }
public void EmptyHeapDecreaseKey_DoesNothing() { FibonacciHeap <int> heap = new FibonacciHeap <int>(); FibonacciNode <int> node = new FibonacciNode <int>(3); heap.DecreaseKey(node, 2); NUnit.Framework.Assert.True(heap.IsEmpty()); NUnit.Framework.Assert.AreEqual(default(int), heap.GetMin()); }
public DijkstraMap(int width, int height, FibonacciHeap <DijkstraTile, double> heap, IEnumerable <Point> starts) { Heap = heap; Width = width; Height = height; foreach (var start in starts) { GenerateNode(start, 0, 0); } }
public void ExchangeTest() { var heap = new FibonacciHeap <int>((a, b) => a < b); var node1 = new FibonacciNode <int>(12); var node2 = new FibonacciNode <int>(11); heap.Exchange(ref node1, ref node2); Assert.AreEqual(node1.Key, 11); }
public void PopTest() { // Heap FibonacciHeap <float, char> heap = new FibonacciHeap <float, char>(); HashSet <float> equalPriorirtyMinimums = new HashSet <float>() { 'b', 'e', 'f', 'g' }; // Check heap starts with no nodes Assert.AreEqual(heap.Count, 0); // Add collection of nodes HeapNode <float, char> node2 = heap.Insert(7, 'b'); HeapNode <float, char> node1 = heap.Insert(3, 'a'); HeapNode <float, char> node3 = heap.Insert(14, 'c'); HeapNode <float, char> node4 = heap.Insert(35, 'd'); HeapNode <float, char> node5 = heap.Insert(7, 'e'); HeapNode <float, char> node6 = heap.Insert(7, 'f'); HeapNode <float, char> node7 = heap.Insert(7, 'g'); // Check heap has correct number of nodes Assert.AreEqual(heap.Count, 7); char minimum = heap.Pop(); // Check returned item is the correct value, and is not still in heap Assert.AreEqual(minimum, 'a'); Assert.AreNotEqual(heap.Minimum.Value, minimum); Assert.AreEqual(heap.Count, 6); // Pop a set of equal priority values, check heap outputs them all (order is undefined) for (int i = 0; i < equalPriorirtyMinimums.Count; i++) { minimum = heap.Pop(); // Check returned item is the correct value, and is not still in heap Assert.IsTrue(equalPriorirtyMinimums.Contains(minimum)); Assert.AreNotEqual(heap.Minimum.Value, minimum); Assert.AreEqual(heap.Count, 5 - i); } minimum = heap.Pop(); // Check returned item is the correct value, and is not still in heap Assert.AreEqual(minimum, 'c'); Assert.AreNotEqual(heap.Minimum.Value, minimum); Assert.AreEqual(heap.Count, 1); minimum = heap.Pop(); // Check returned item is the correct value Assert.AreEqual(minimum, 'd'); Assert.AreEqual(heap.Count, 0); }
public List <(TVertex Vertex, EdgeBase <TVertex> EdgeToParent)> FindShortestPathWithDijkstra(TVertex start, TVertex end) { var vertexInfoDict = Vertices.Select(vertex => new DijkstraVertexInfo(vertex, vertex == start ? 0 : double.PositiveInfinity)) .Select(info => new FibonacciHeapNode <DijkstraVertexInfo>(info, info.Distance)) .ToDictionary(node => node.Data.Vertex, node => node); var heap = new FibonacciHeap <DijkstraVertexInfo>(); heap.InsertRange(vertexInfoDict.Values); DijkstraVertexInfo endInfo = null; while (vertexInfoDict.Count > 0) { var curVertexInfo = heap.RemoveMin().Data; if (curVertexInfo.Vertex == end) { endInfo = curVertexInfo; break; } var neighborsWithEdges = GetNeighborsWithEdges(curVertexInfo.Vertex, ignoreSelfLoops: true); foreach (var neighborsWithEdge in neighborsWithEdges) { if (vertexInfoDict.TryGetValue(neighborsWithEdge.Vertex, out FibonacciHeapNode <DijkstraVertexInfo> neighborNode)) { var alt = curVertexInfo.Distance + neighborsWithEdge.Edge.Weight ?? 1; var neighborInfo = neighborNode.Data; if (alt < neighborInfo.Distance) { heap.DecreaseKey(neighborNode, alt); neighborInfo.Distance = alt; neighborInfo.Parent = curVertexInfo; neighborInfo.ParentEdge = neighborsWithEdge.Edge; } } } } if (endInfo != null) { var reslut = new List <(TVertex Vertex, EdgeBase <TVertex> EdgeToParent)>(); var curVertex = endInfo; while (curVertex != null) { reslut.Add((curVertex.Vertex, curVertex.ParentEdge)); curVertex = curVertex.Parent; } reslut.Reverse(); return(reslut); } return(null); }
public void ConsolidatedHeapDecreaseKey_CorrectCuts() { FibonacciHeap <int> heap = new FibonacciHeap <int>(); IList <FibonacciNode <int> > input = new List <FibonacciNode <int> >() { new FibonacciNode <int>(0), new FibonacciNode <int>(28), new FibonacciNode <int>(-13), new FibonacciNode <int>(80), new FibonacciNode <int>(3), new FibonacciNode <int>(7), new FibonacciNode <int>(-7), new FibonacciNode <int>(42), new FibonacciNode <int>(-11), new FibonacciNode <int>(12) }; IList <int> expectedElementOrder = new List <int>() { 7, -8, -11, 12, -42, 80, -1, -3, 0 }; foreach (FibonacciNode <int> value in input) { heap.Insert(value); } heap.ExtractMin(); // A decrease key with no structural changes heap.DecreaseKey(input[6], -8); // Normal cuts with parent marked heap.DecreaseKey(input[7], -42); heap.DecreaseKey(input[4], -1); // Double cascading cut heap.DecreaseKey(input[1], -3); IList <int> result = heap.GetAllValues(); for (int i = 0; i < expectedElementOrder.Count; ++i) { NUnit.Framework.Assert.IsTrue(expectedElementOrder[i] == result[i]); } NUnit.Framework.Assert.IsTrue(heap.GetMin() == -42); }
public void UnconsolidatedHeapContainsNull_false() { FibonacciHeap <int> heap = new FibonacciHeap <int>(); IList <int> input = new List <int>() { 0, 28, }; NUnit.Framework.Assert.IsFalse(heap.Contains(null)); }
public void UnconsolidatedHeapDecreaseKey_NoException() { FibonacciHeap <int> heap = new FibonacciHeap <int>(); IList <int> input = new List <int>() { 0, 28, }; heap.DecreaseKey(null, 3); }
public void UnconsolidatedHeapInsertNull_Null() { FibonacciHeap <int> heap = new FibonacciHeap <int>(); IList <int> input = new List <int>() { 0, 28, }; NUnit.Framework.Assert.IsNull(heap.Insert(null)); }
public static Path DijkstraPath(Vertex from, Vertex to, Graph graph) { HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); // Initialize labels. foreach (var vertex in graph.Vertices) { var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, n); comingFrom.Add(vertex, null); } while (!visited.Contains(to)) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) { labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); comingFrom[edge.Other(current)] = edge; } } visited.Add(current); } // Now travel back, to find the actual path List<Edge> pathEdges = new List<Edge>(); Vertex pathVertex = to; while (pathVertex != from) { pathEdges.Add(comingFrom[pathVertex]); pathVertex = comingFrom[pathVertex].Other(pathVertex); } pathEdges.Reverse(); Path path = new Path(from); path.Edges.AddRange(pathEdges); return path; }
public void FibonacciHeapUpdateKeyMinHeap() { FibonacciHeap<HeapElement> heap = new FibonacciHeap<HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true); FillHeap(heap, 100); Assert.AreEqual(100, heap.Count); // add new element. Give it a priority of 50 HeapElement element = new HeapElement(50, "Value: 50"); heap.Insert(element); Assert.AreEqual(101, heap.Count); // update key to 10, using an action lambda heap.UpdateKey(element, (a, b) => a.Priority = b, 10); Assert.AreEqual(10, element.Priority); // check if the heap is still correct HeapElement previous = heap.ExtractRoot(); HeapElement current = heap.ExtractRoot(); while(current != null) { Assert.IsTrue(previous.Priority <= current.Priority); previous = current; current = heap.ExtractRoot(); } // heap should be empty Assert.AreEqual(0, heap.Count); }
public void FibonacciHeapMergeTestMinHeaps() { // create two minheaps based on the priority value of the elements. FibonacciHeap<HeapElement> heap1 = new FibonacciHeap<HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true); FibonacciHeap<HeapElement> heap2 = new FibonacciHeap<HeapElement>((a, b) => a.Priority.CompareTo(b.Priority), true); FillHeap(heap1, 100); FillHeap(heap2, 100); Assert.AreEqual(100, heap1.Count); Assert.AreEqual(100, heap2.Count); // merge heap1 into heap2. heap2 will be empty afterwards heap1.Merge(heap2); Assert.AreEqual(200, heap1.Count); Assert.AreEqual(0, heap2.Count); // check if they are inserted correctly HeapElement previous = heap1.ExtractRoot(); HeapElement current = heap1.ExtractRoot(); while(current != null) { Assert.IsTrue(previous.Priority <= current.Priority); previous = current; current = heap1.ExtractRoot(); } // heap1 should be empty as well Assert.AreEqual(0, heap1.Count); }
public void SetLabelsFibonacciHeap(FibonacciHeap<int, Vertex> heap) { _dictLabels[_currentlyUsingVertex] = heap; }
public void AddVertexToInterleavingDijkstra(Vertex vertex, Graph graph) { if (_verticesInSearch.Contains(vertex)) throw new InvalidOperationException("Can not add the vertex, because it is already added."); _verticesInSearch.Add(vertex); var labels = new FibonacciHeap<int, Vertex>(); var nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); // Initialize labels. foreach (var v in graph.Vertices) { var node = labels.Add(v == vertex ? 0 : int.MaxValue, v); nodes.Add(v, node); } _dictLabels.Add(vertex, labels); _dictNodes.Add(vertex, nodes); _dictVisited.Add(vertex, new HashSet<Vertex>()); _dictPathsfound.Add(vertex, new Dictionary<Vertex, Path>()); _dictComingFrom.Add(vertex, new Dictionary<Vertex, Edge>()); _dictComponent.Add(vertex, ++_internalNewComponentCount); // All vertices start in a different component. }
public static FibonacciHeap<int, int> Create() { FibonacciHeap<int, int> fibonacciHeap = new FibonacciHeap<int, int>(); return fibonacciHeap; }
static void TestCase5() { var root1 = Node(7) .AddChild(Node(24) .AddChild(Node(26).Marked() .AddChild(Node(35))) .AddChild(Node(46))) .AddChild(Node(17) .AddChild(Node(30))) .AddChild(Node(23)); var root2 = Node(18).Marked() .AddChild(Node(21) .AddChild(Node(52))) .AddChild(Node(39).Marked()); var root3 = Node(38).AddChild(Node(41)); var heap = new FibonacciHeap<int>(int.MinValue, Comparer<int>.Default, new[] {root1, root2, root3}); var node1 = root1.Children.ElementAt(0).Children.ElementAt(1); var node2 = root1.Children.ElementAt(0).Children.ElementAt(0).Children.ElementAt(0); heap.DecreaseKey(node1, 15); heap.DecreaseKey(node2, 5); var expRoots = new[] { 15, 5, 26, 24, 7, 18, 38 }; var actualRoots = heap.Roots.Select(x => x.Data).ToList(); Assert(expRoots.Length == actualRoots.Count); for (var i = 0; i < expRoots.Length; i++) Assert(actualRoots.Contains(expRoots[i])); }
public static List<Path> NearestTerminals(Vertex from, Graph graph, int n) { List<Path> foundPaths = new List<Path>(); HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>(); if (graph.Terminals.Contains(from)) foundPaths.Add(new Path(from)); // Initialize labels. foreach (var vertex in graph.Vertices) { var node = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, node); comingFrom.Add(vertex, null); } while (!labels.IsEmpty() && foundPaths.Count < n) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) { labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); comingFrom[edge.Other(current)] = edge; } } visited.Add(current); if (graph.Terminals.Contains(current) && current != from) { // Now travel back, to find the actual path List<Edge> pathEdges = new List<Edge>(); Vertex pathVertex = current; while (pathVertex != from) { pathEdges.Add(comingFrom[pathVertex]); pathVertex = comingFrom[pathVertex].Other(pathVertex); } pathEdges.Reverse(); Path path = new Path(from); path.Edges.AddRange(pathEdges); foundPaths.Add(path); } } return foundPaths; }
private static FibonacciHeap<int> CreateHeap(params int[] values) { var heap = new FibonacciHeap<int>(int.MinValue, Comparer<int>.Default); foreach(var value in values) heap.Insert(value); return heap; }
public static Dictionary<Vertex, Path> DijkstraPathToAll(Vertex from, Graph graph, bool onlyTerminals) { Dictionary<Vertex, Edge> comingFrom = new Dictionary<Vertex, Edge>(); HashSet<Vertex> visited = new HashSet<Vertex>(); Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node> nodes = new Dictionary<Vertex, FibonacciHeap<int, Vertex>.Node>(); Dictionary<Vertex, Path> paths = new Dictionary<Vertex, Path>(); FibonacciHeap<int, Vertex> labels = new FibonacciHeap<int, Vertex>(); // Initialize labels. foreach (var vertex in graph.Vertices) { var n = labels.Add(vertex == from ? 0 : int.MaxValue, vertex); nodes.Add(vertex, n); } while (paths.Count < (onlyTerminals ? graph.Terminals.Count - 1 : graph.NumberOfVertices - 1)) { var currentNode = labels.ExtractMin(); var current = currentNode.Value; // Consider all edges ending in unvisited neighbours var edges = graph.GetEdgesForVertex(current).Where(x => !visited.Contains(x.Other(current))); // Update labels on the other end. foreach (var edge in edges) { if (currentNode.Key + edge.Cost < nodes[edge.Other(current)].Key) { labels.DecreaseKey(nodes[edge.Other(current)], currentNode.Key + edge.Cost); comingFrom[edge.Other(current)] = edge; } } visited.Add(current); if (current != from && (!onlyTerminals || graph.Terminals.Contains(current))) { // Travel back the path List<Edge> pathEdges = new List<Edge>(); Vertex pathVertex = current; while (pathVertex != from) { pathEdges.Add(comingFrom[pathVertex]); pathVertex = comingFrom[pathVertex].Other(pathVertex); } pathEdges.Reverse(); Path path = new Path(from); path.Edges.AddRange(pathEdges); paths[current] = path; } } return paths; }