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 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); }
public void ConsolidatedHeapExtractMin_CorrectConsolidation() { // Create consolidated heap FibonacciHeap <int> heap = new FibonacciHeap <int>(); IList <int> input = new List <int>() { 0, 28, -13, 80, 3, 7, -7, 42, -11, 12 }; IList <int> expectedElementOrder = new List <int>() { 7, 42, 12, 28, 80, 3, 0, -7 }; foreach (int value in input) { heap.Insert(value); } heap.ExtractMin(); // Trigger second consolidation heap.ExtractMin(); 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() == -7); }
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 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 UnconsolidatedHeapExtractMin_CorrectValue() { FibonacciNode <int> node = new FibonacciNode <int>(-20); FibonacciHeap <int> heap = new FibonacciHeap <int>(); IList <int> input = new List <int>() { 0, 28, -13, 80 }; heap.Insert(node); foreach (int value in input) { heap.Insert(value); } NUnit.Framework.Assert.IsTrue(heap.ExtractMin() == node); NUnit.Framework.Assert.IsTrue(heap.GetMin() == -13); NUnit.Framework.Assert.IsTrue(heap.GetAllValues().Count == input.Count); }
public void EmptyHeapExtractMin_ReturnsNull() { FibonacciHeap <int> heap = new FibonacciHeap <int>(); NUnit.Framework.Assert.Null(heap.ExtractMin()); }
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; }
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; }