예제 #1
0
        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);
        }
예제 #2
0
        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
                        );
                }
            }
        }
예제 #5
0
        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);
        }