public void Should_dequeue_in_order() { var q = new FibonacciQueue <int, int>(i => i); q.Enqueue(3); q.Enqueue(1); q.Enqueue(0); q.Enqueue(4); q.Enqueue(9); q.Dequeue().Should().Be(0); q.Dequeue().Should().Be(1); q.Dequeue().Should().Be(3); q.Dequeue().Should().Be(4); q.Dequeue().Should().Be(9); }
public void Should_dequeue_massive_amount_in_order() { var q = new FibonacciQueue <int, int>(i => i); var r = new Random(); for (int i = 0; i < 8192; i++) { q.Enqueue(r.Next()); } var c = int.MinValue; while (q.Count > 0) { var i = q.Dequeue(); i.Should().BeGreaterOrEqualTo(c); c = i; } }
/// <inheritdoc /> protected override void InternalCompute() { TVertex root = GetAndAssertRootInGraph(); if (!TryGetTargetVertex(out TVertex target)) { throw new InvalidOperationException("Target vertex not set."); } if (!VisitedGraph.ContainsVertex(target)) { throw new VertexNotFoundException("Target vertex is not part of the graph."); } // Start by building the minimum tree starting from the target vertex. ComputeMinimumTree( target, out IDictionary <TVertex, TEdge> successors, out IDictionary <TVertex, double> distances); ThrowIfCancellationRequested(); var queue = new FibonacciQueue <DeviationPath, double>(deviationPath => deviationPath.Weight); int vertexCount = VisitedGraph.VertexCount; // First shortest path EnqueueFirstShortestPath(queue, successors, distances, root); while (queue.Count > 0 && ComputedShortestPathCount < ShortestPathCount) { ThrowIfCancellationRequested(); DeviationPath deviation = queue.Dequeue(); // Turn into path var path = new List <TEdge>(); for (int i = 0; i < deviation.DeviationIndex; ++i) { path.Add(deviation.ParentPath[i]); } path.Add(deviation.DeviationEdge); int startEdge = path.Count; AppendShortestPath(path, successors, deviation.DeviationEdge.Target); Debug.Assert(Math.Abs(deviation.Weight - path.Sum(e => _edgeWeights(e))) < float.Epsilon); Debug.Assert(path.Count > 0); // Add to list if has no cycle if (!path.HasCycles <TVertex, TEdge>()) { AddComputedShortestPath(path); } // Append new deviation paths if (path.Count < vertexCount) { EnqueueDeviationPaths( queue, root, distances, path.ToArray(), startEdge); } } }
protected override void InternalCompute() { var cancelManager = this.Services.CancelManager; TVertex root; if (!this.TryGetRootVertex(out root)) { throw new InvalidOperationException("root vertex not set"); } TVertex goal; if (!this.TryGetGoalVertex(out goal)) { throw new InvalidOperationException("goal vertex not set"); } // start by building the minimum tree starting from the goal vertex. IDictionary <TVertex, TEdge> successors; IDictionary <TVertex, double> distances; this.ComputeMinimumTree(goal, out successors, out distances); if (cancelManager.IsCancelling) { return; } var queue = new FibonacciQueue <DeviationPath, double>(dp => dp.Weight); var vertexCount = this.VisitedGraph.VertexCount; // first shortest path this.EnqueueFirstShortestPath(queue, successors, distances, root); while (queue.Count > 0 && this.ComputedShortestPathCount < this.ShortestPathCount) { if (cancelManager.IsCancelling) { return; } var deviation = queue.Dequeue(); // turn into path var path = new List <TEdge>(); for (int i = 0; i < deviation.DeviationIndex; ++i) { path.Add(deviation.ParentPath[i]); } path.Add(deviation.DeviationEdge); int startEdge = path.Count; this.AppendShortestPath(path, successors, deviation.DeviationEdge.Target); Contract.Assert(deviation.Weight == Enumerable.Sum(path, e => edgeWeights(e))); Contract.Assert(path.Count > 0); // add to list if loopless if (!EdgeExtensions.HasCycles <TVertex, TEdge>(path)) { this.AddComputedShortestPath(path); } // append new deviation paths if (path.Count < vertexCount) { this.EnqueueDeviationPaths( queue, root, successors, distances, path.ToArray(), startEdge ); } } }
public List <T> FindPath(T start, T goal) { if (start == null) { return(null); } if (goal == null) { return(null); } this.Goal = goal; gScore = new Dictionary <T, float>(); fScore = new Dictionary <T, float>(); //var openset = new HashSet<T>(); var openset = new FibonacciQueue <T, float>(d => fScore[d]); var closedset = new HashSet <T>(); cameFrom = new Dictionary <T, T>(); //came_from := the empty map // The map of navigated nodes. gScore[start] = 0; // Cost from start along best known path. // Estimated total cost from start to goal through y. fScore[start] = gScore[start] + ConnectionProvider.GetHeuristicCostEstimate(start, goal); openset.Enqueue(start); onBegin(); while (openset.Count > 0) { var current = openset.Dequeue(); onSelectNode(current); if (StopCondition(current)) { return(reconstruct_reverse_path(cameFrom, current).Reverse().ToList()); } if (current.Equals(goal)) { return(reconstruct_reverse_path(cameFrom, goal).Reverse().ToList()); } closedset.Add(current); //add current to closedset foreach (var neighbor in ConnectionProvider.GetConnectedNodes(this, current)) { if (closedset.Contains(neighbor)) { continue; } var tentative_g_score = gScore[current] + ConnectionProvider.GetCost(current, neighbor); if (openset.Contains(neighbor) && !(tentative_g_score <= gScore[neighbor])) { continue; } cameFrom[neighbor] = current; gScore[neighbor] = tentative_g_score; fScore[neighbor] = gScore[neighbor] + ConnectionProvider.GetHeuristicCostEstimate(neighbor, goal); if (openset.Contains(neighbor)) { continue; } openset.Enqueue(neighbor); onEnqueueNode(neighbor); } } return(null); }