Пример #1
0
        public void TestBasicFunctionality()
        {
            var q = new PriorityQueue<int>();
            Assert.AreEqual(0, q.Count);
            Assert.AreEqual(0, q.Capacity);
            Assert.Throws<InvalidOperationException>(() => q.Peek());
            Assert.Throws<InvalidOperationException>(() => q.Dequeue());

            q.Enqueue(5);
            q.Enqueue(2);
            q.Enqueue(4);

            Assert.AreEqual(3, q.Count);
            Assert.IsTrue(q.Capacity >= 3);

            Assert.IsTrue(q.Contains(2));
            Assert.IsFalse(q.Contains(3));

            Assert.AreEqual(3, q.ToArray().Length);
            CollectionAssert.AreEqual(q.ToArray(), q);

            Assert.AreEqual(2, q.Peek());

            Assert.AreEqual(2, q.Dequeue());
            Assert.AreEqual(4, q.Dequeue());
            Assert.AreEqual(5, q.Dequeue());
        }
Пример #2
0
 public void Clear()
 {
     var pq = new PriorityQueue<int>(new int[] { 1, 2, 3 });
     int temp;
     Assert.AreEqual(3, pq.Count);
     Assert.IsTrue(pq.Peek(out temp));
     pq.Clear();
     Assert.AreEqual(0, pq.Count);
     Assert.IsFalse(pq.Peek(out temp));
 }
Пример #3
0
        public void PriorityQueuePeekQueueNoChangeInCount()
        {
            var q = new PriorityQueue<int>();

            q.Enqueue(AnyInt);
            var count = q.Count;
            q.Peek();
            Assert.Equal(count, q.Count);
        }
Пример #4
0
 public void Peek()
 {
     var pq = new PriorityQueue<int>(new int[] {1, 2, 3});
     int temp;
     Assert.IsTrue(pq.Peek(out temp));
     Assert.AreEqual(1, temp);
     Assert.AreEqual(1, pq.Dequeue());
     Assert.IsTrue(pq.Peek(out temp));
     Assert.AreEqual(2, temp);
 }
Пример #5
0
        public void PriorityQueueClearEmptiesTheQueue()
        {
            var q = new PriorityQueue<int>();
            q.Enqueue(AnyInt);
            q.Enqueue(AnyInt);
            q.Clear();

            Assert.Equal(0, q.Count);

            Assert.Throws<InvalidOperationException>(() => q.Peek());
        }
Пример #6
0
        static void DijkstraAlgorithm(Dictionary<Node, List<Connection>> graph, Node source)
        {
            PriorityQueue<Node> queue = new PriorityQueue<Node>();

            foreach (var node in graph)
            {
                if (source.ID != node.Key.ID)
                {
                    node.Key.DijkstraDistance = double.PositiveInfinity;
                    queue.Enqueue(node.Key);
                }
            }

            source.DijkstraDistance = 0.0d;
            queue.Enqueue(source);

            while (queue.Count != 0)
            {
                Node currentNode = queue.Peek();

                if (currentNode.DijkstraDistance == double.PositiveInfinity)
                {
                    break;
                }

                foreach (var neighbour in graph[currentNode])
                {
                    double potDistance = currentNode.DijkstraDistance + neighbour.Distance;

                    if (potDistance < neighbour.Node.DijkstraDistance)
                    {
                        neighbour.Node.DijkstraDistance = potDistance;
                    }
                }

                queue.Dequeue();
            }
        }
Пример #7
0
        public void TestPeek1()
        {
            var queue = new PriorityQueue<string> { "string", "anotherString" };

            var poll = queue.Peek();

            Assert.AreEqual(2, queue.Count);
            Assert.AreEqual("anotherString", poll);
            Assert.IsTrue(queue.Contains("anotherString"));
        }
Пример #8
0
        public void DequeueTestString([PexAssumeUnderTest]List<string> elementList)
        {
            PriorityQueue<string> actual = new PriorityQueue<string>(elementList);

            string dequeuedElem = actual.Dequeue();
            elementList.Sort();
            PexAssert.AreEqual(elementList[0], dequeuedElem);
            if (elementList.Count > 1)
                PexAssert.AreEqual(elementList[1], actual.Peek());
            PexAssert.AreEqual(elementList.Count - 1, actual.Count);
        }
Пример #9
0
 public void PriorityQueuePeekEmptyQueueThrowsException()
 {
     var q = new PriorityQueue<int>();
     Assert.Equal(0, q.Count);
     Assert.Throws<InvalidOperationException>(() => q.Peek());
 }
Пример #10
0
        public void TestPeek2()
        {
            var queue = new PriorityQueue<string>();

            var poll = queue.Peek();

            Assert.IsNull(poll);
        }
Пример #11
0
 public void TestPeek()
 {
     PriorityQueue<int, int> q = new PriorityQueue<int, int>();
     q.Enqueue(2, 2);
     q.Enqueue(1, 1);
     Assert.AreEqual(1, q.Peek());
     Assert.AreEqual(2, q.Count);
 }
Пример #12
0
        public void PriorityQueueAddElementsPeekReturnsHighestPriorityMessage()
        {
            var q = new PriorityQueue<int>();

            q.Enqueue(0);
            q.Enqueue(4);
            q.Enqueue(2);
            q.Enqueue(3);
            q.Enqueue(1);

            var dequeued = q.Peek();

            Assert.Equal(dequeued, 0);
        }
Пример #13
0
 protected virtual void ReInsert(Node node, Int32 level)
 {
     MinimumBoundingBox nodeBox = node.CalculateMinimumBoundingBox();
     PriorityQueue<NodeEntry, Single> distances = new PriorityQueue<NodeEntry, Single>(),
     reInsertions = new PriorityQueue<NodeEntry, Single>();
     foreach (NodeEntry entry in node.NodeEntries)
         distances.Enqueue(entry, GetCenterDistance(nodeBox, entry.MinimumBoundingBox) * -1);
     for (int i = 0; i < Constants.NODES_FOR_REINSERT; i++)
         reInsertions.Enqueue(distances.Peek().Value, distances.Dequeue().Priority * -1);
     foreach (PriorityQueueItem<NodeEntry, Single> entry in reInsertions)
         node.RemoveNodeEntry(entry.Value);
     AdjustTree(node, level);
     while(reInsertions.Count > 0)
         Insert(reInsertions.Dequeue().Value, level);
 }
Пример #14
0
            /// <summary>
            /// Returns all nodes in this quadrant that are fully contained within the given bounds.
            /// The nodes are returned in order of descending priority.
            /// </summary>
            /// <param name="bounds">The bounds that contains the nodes you want returned.</param>
            /// <returns>A lazy list of nodes along with the new potential of this quadrant.</returns>
            internal IEnumerable <Tuple <QuadNode, double> > GetNodesInside(Rect bounds)
            {
                double w = _bounds.Width / 2;
                double h = _bounds.Height / 2;

                // assumption that the Rect struct is almost as fast as doing the operations
                // manually since Rect is a value type.
                Rect topLeft     = new Rect(_bounds.Left, _bounds.Top, w, h);
                Rect topRight    = new Rect(_bounds.Left + w, _bounds.Top, w, h);
                Rect bottomLeft  = new Rect(_bounds.Left, _bounds.Top + h, w, h);
                Rect bottomRight = new Rect(_bounds.Left + w, _bounds.Top + h, w, h);

                // Create a priority queue based on the potential of our nodes and our quads.
                var queue = new PriorityQueue <IEnumerator <Tuple <QuadNode, double> >, double>(true);

                if (_nodes != null)
                {
                    queue.Enqueue(_nodes.GetNodesInside(bounds).GetEnumerator(), _nodes.Next.Priority);
                }

                if (_topLeft != null && topLeft.Intersects(bounds))
                {
                    queue.Enqueue(_topLeft.GetNodesInside(bounds).GetEnumerator(), _topLeft._potential);
                }

                if (_topRight != null && topRight.Intersects(bounds))
                {
                    queue.Enqueue(_topRight.GetNodesInside(bounds).GetEnumerator(), _topRight._potential);
                }

                if (_bottomLeft != null && bottomLeft.Intersects(bounds))
                {
                    queue.Enqueue(_bottomLeft.GetNodesInside(bounds).GetEnumerator(), _bottomLeft._potential);
                }

                if (_bottomRight != null && bottomRight.Intersects(bounds))
                {
                    queue.Enqueue(_bottomRight.GetNodesInside(bounds).GetEnumerator(), _bottomRight._potential);
                }

                // Then just loop through the queue.
                while (queue.Count > 0)
                {
                    // Grab the enumerator with the highest potential.
                    var enumerator = queue.Dequeue().Key;
                    if (enumerator.MoveNext())
                    {
                        // Get the current node and its new potential from the enumerator.
                        var current   = enumerator.Current;
                        var node      = current.Item1;
                        var potential = current.Item2;

                        // Determine our new potential.
                        var newPotential = queue.Count > 0 ? !potential.IsNaN() ? Math.Max(potential, queue.Peek().Value) : queue.Peek().Value : potential;

                        // It might be the case that the actual intersecting node has less priority than our remaining potential.
                        if (newPotential > node.Priority)
                        {
                            // Store it for later in a container containing only it with no further potential.
                            var store = Enumerable.Repeat(Tuple.Create(node, double.NaN), 1).GetEnumerator();

                            // Enqueue the container at the correct position.
                            queue.Enqueue(store, node.Priority);
                        }
                        else
                        {
                            // Return it to our parent along with our new potential.
                            yield return(Tuple.Create(node, newPotential));
                        }

                        // If this enumerator has some more potential then re-enqueue it.
                        if (!potential.IsNaN())
                        {
                            queue.Enqueue(enumerator, potential);
                        }
                    }
                }
            }
Пример #15
0
        public void MaxValuesHavePriorityTest()
        {
            PriorityQueue<int> actual = new PriorityQueue<int>(Strategy.Max) { 6, 1, 8, 9, 2, 3, 7 };

            Assert.AreEqual(9, actual.Peek());
        }
Пример #16
0
        public void PeekTest()
        {
            PriorityQueue<int> actual = new PriorityQueue<int> { 12, 6, 3, 1, 0, 8 };

            Assert.AreEqual(0, actual.Peek());
        }
Пример #17
0
 public void MaxValuesHavePriorityTest([PexAssumeUnderTest]List<int> elemList)
 {
     PexAssume.IsTrue(elemList.Count > 0);
     PriorityQueue<int> actual = new PriorityQueue<int>(elemList, Strategy.Max);
     elemList.Sort();
     Assert.AreEqual(elemList[elemList.Count - 1], actual.Peek());
 }
Пример #18
0
        /// <summary>
        /// Single-source multiple-target version of Dijkstra's shortest path algorithm that returns shortest paths to a specified number of targets.
        /// </summary>
        /// <param name="source">Source vertex to start searching from.</param>
        /// <param name="targets">Target vertices to find shortest paths to.</param>
        /// <param name="count">Number of targets to find.</param>
        /// <returns>Mapping of all shortest paths from the source to all vertices up to <paramref name="count"/> targets.</returns>
        /// <remarks>
        /// The graph attached to <paramref name="source"/> should not contain any negative cycles.
        /// </remarks>
        public static IDictionary<IVertex, Path> ShortestPaths(IVertex source, ICollection<IVertex> targets, int count)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (targets == null)
                throw new ArgumentNullException("targets");
            if (count < 1)
                throw new ArgumentOutOfRangeException("count");

            // Create a priority queue where target vertices are prioritized by shortest path weight, starting with the source.
            PriorityQueue<IVertex, int> queue = new PriorityQueue<IVertex, int>();
            IDictionary<IVertex, IEdge/*?*/> edges = new Dictionary<IVertex, IEdge/*?*/>();

            // Initialize the source with a path of 0 length.
            queue[source] = 0;
            edges[source] = null;

            // Keep track of the explored vertices with known minimal length.
            IDictionary<IVertex, Path> shortestPaths = new Dictionary<IVertex, Path>();

            // The number of explored targets.
            int targetsFound = 0;

            // Keep track of the upper bound on the distance to the closest 'count' nodes.
            // See "A Heuristic for Dijkstra's Algorithm" for details.
            PriorityQueue<IVertex, int> bounds = new PriorityQueue<IVertex, int>(true);
            foreach (IVertex target in targets)
            {
                bounds.Enqueue(target, int.MaxValue);
                if (bounds.Count == count)
                    break;
            }

            // Traverse the queue.
            while (queue.Count > 0)
            {
                // Get the next closest vertex and copy it to the list of shortest paths.
                KeyValuePair<IVertex, int> item = queue.Dequeue();
                source = item.Key;

                // We've found the shortest path to this vertex.
                IEdge/*?*/ shortest = edges[source];
                if (shortest == null)
                    shortestPaths[source] = new Path(source);
                else
                    shortestPaths[source] = shortestPaths[shortest.Source] + shortest;

                // If we've explored the requested number of targets then break early.
                if (targets.Contains(source))
                    if (++targetsFound >= count)
                        break;

                // Relax all outgoing edges from this vertex.
                foreach (IEdge edge in source.Edges)
                {
                    // If we haven't explored the target yet.
                    IVertex target = edge.Target;
                    if (!shortestPaths.ContainsKey(target))
                    {
                        // Calculate the new cost via this edge.
                        int newCost = item.Value + edge.Cost;

                        // Only relax the edge if the cost is an improvement (i.e. less than) the shortest paths seen so far.
                        // See "A Heuristic for Dijkstra's Algorithm" for details.
                        if (newCost < bounds.Peek().Value)
                        {
                            // Compare the new path with the current paths.
                            int currentCost;
                            if (!queue.TryGetValue(target, out currentCost) || newCost < currentCost)
                            {
                                // If no current path exists or the new path is shorter, then update the shortest path in the queue.
                                queue[target] = newCost;
                                edges[target] = edge;

                                // If the target is a final target then update the cost in the list of upper bounds.
                                if (targets.Contains(target))
                                {
                                    bounds[target] = newCost;

                                    // We only need to keep track of the closest 'count' targets.
                                    if (bounds.Count > count)
                                        bounds.Dequeue();
                                }
                            }
                        }
                    }
                }
            }

            return shortestPaths;
        }
Пример #19
0
        static void Main(string[] args)
        {
            string input;
            string result;
            List<Node> closed = new List<Node>();
            PriorityQueue<Node> open = new PriorityQueue<Node>();

            Console.WriteLine("enter initial string set: ");
            input = Console.ReadLine();
            Console.WriteLine("Enter desired string set: ");
            result = Console.ReadLine();

            Node start = new Node(input);
            Node goal = new Node(result);

            start.G = 0; //set G to amount of nodes traversed aka priority
            start.SetH(goal); //set the h value based on the goal node's value

            Node current = start;
            open.Enqueue(current); //add current node into open list

            while (open.Peek() != goal)
            {
                //generate children based on items in open list (current)
                List<Node> Children = getChildren(current, closed, open);

                current = open.Dequeue(); //pop current node
                closed.Add(current); //add current node into closed list

                //Console.WriteLine(current.GameString);

                foreach (Node child in Children)
                {
                    //child.SetH(goal);
                    open.Enqueue(child);
                }

                if (current.Equals(goal))
                {
                    Console.WriteLine("found path:");
                    Node last = current;
                    List<Node> list = new List<Node>();
                    while (last.Parent != null)
                    {
                        list.Add(last);
                        last = last.Parent;
                    }
                    list.Add(last);
                    list.Reverse();
                    foreach (Node n in list)
                        Console.WriteLine(n.ToString());
                    break;
                }

                if (open.isEmpty())
                {
                    Console.WriteLine("failed to find path");
                    break;
                }

                if (Children == null)
                {
                    current = open.Dequeue(); //set first element of open list to current and pop
                    continue;
                }
            }
            Console.ReadKey(true);
        }
Пример #20
0
        public void SimpleTest()
        {
            var queue = new PriorityQueue<int, int>();
            
            Assert.IsFalse(queue.HasItems);
            
            queue.Enqueue(1, 10);
            queue.Enqueue(3, 30);
            queue.Enqueue(5, 50);
            queue.Enqueue(4, 40);
            queue.Enqueue(2, 20);

            Assert.IsTrue(queue.HasItems);
            Assert.AreEqual(50, queue.Peek());
            Assert.AreEqual(50, queue.Peek());
            Assert.AreEqual(50, queue.Dequeue());

            Assert.AreEqual(40, queue.Peek());
            Assert.AreEqual(40, queue.Dequeue());

            Assert.IsTrue(queue.HasItems);
            Assert.AreEqual(30, queue.Peek());
            Assert.AreEqual(30, queue.Peek());
            Assert.AreEqual(30, queue.Peek());
            Assert.AreEqual(30, queue.Dequeue());

            Assert.IsTrue(queue.HasItems);
            Assert.AreEqual(20, queue.Peek());
            Assert.AreEqual(20, queue.Dequeue());

            Assert.AreEqual(10, queue.Peek());
            Assert.AreEqual(10, queue.Peek());
            Assert.AreEqual(10, queue.Peek());
            Assert.AreEqual(10, queue.Peek());
            Assert.AreEqual(10, queue.Peek());
            Assert.IsTrue(queue.HasItems);
            Assert.AreEqual(10, queue.Peek());
            Assert.AreEqual(10, queue.Dequeue());

            Assert.IsFalse(queue.HasItems);
        }
Пример #21
0
 public void PeekShouldThrowWhenEmpty()
 {
     var queue = new PriorityQueue<int, int>();
     queue.Peek();
 }
Пример #22
0
        public void PeekTest(int[] newElements)
        {
            try
            {
                PriorityQueue<int> actual = new PriorityQueue<int>(newElements);

                //get the minimum element
                int minVal = Int32.MaxValue;
                for (int i = 0; i < newElements.Length; i++)
                    minVal = minVal > newElements[i] ? newElements[i] : minVal;

                PexAssert.AreEqual(minVal, actual.Peek());
                PexGoal.Reached("normal");
            }
            catch (InvalidOperationException)
            {
                PexGoal.Reached("exception");
                throw;
            }
        }
Пример #23
0
        void UpdateGraphWithDistancesFromNode(Node source)
        {
            PriorityQueue<Node> unVisitedNodes = new PriorityQueue<Node>(Nodes); // Time to create a min heap - O(n)

            // Does this update the value of 'source' in Nodes ?
            source.Distance = 0;

            while (!unVisitedNodes.Empty()) // O(n)
            {
                Node current = unVisitedNodes.Peek();

                if (current.Distance == Constants.INFINITY)
                {
                    break;
                }

                foreach (Node neighbor in current.Neighbors) // O(nm)
                {
                    if (unVisitedNodes.Contains(neighbor))
                    {
                        int tentative = 0;
                        Edge edge = FindEdge(current, neighbor);  // O(nml)
                        tentative = current.Distance + edge.Cost;
                        if (tentative < neighbor.Distance)
                        {
                            neighbor.Distance = tentative;
                            neighbor.Previous = current;
                        }
                    }
                }

                unVisitedNodes.Dequeue();
            }
        }
Пример #24
0
        public void PeekNoItemsInTheQueueTest()
        {
            PriorityQueue<int> actual = new PriorityQueue<int>();

            actual.Peek();
        }
Пример #25
0
        /// <summary>
        /// Calculates a path from start to end. When no path can be found in
        /// reasonable time the search is aborted and an incomplete path is returned.
        /// When refresh is not set to true a cached path is returned where possible.
        /// </summary>
        /// <param name="start">start position in 2d map space</param>
        /// <param name="end">end position in 2d map space</param>
        /// <param name="refresh">force to recalculate the path</param>
        /// <returns></returns>
        public Path CalculatePath(Unit unit, HexPoint start, HexPoint end, bool refresh = false)
        {
            // swap points to calculate the path backwards (from end to start)
            HexPoint temp = end;
            end = start;
            start = temp;

            // Check whether the requested path is already known
            PathRequest request = new PathRequest(unit,start, end);

            if (!refresh && knownPaths.ContainsKey(request))
            {
                return knownPaths[request].Copy();
            }

            // priority queue of nodes that yet have to be explored sorted in
            // ascending order by node costs (F)
            PriorityQueue<PathNode> open = new PriorityQueue<PathNode>();

            // list of nodes that have already been explored
            LinkedList<IGridCell> closed = new LinkedList<IGridCell>();

            // start is to be explored first
            PathNode startNode = new PathNode(unit,null, map[start], end);
            open.Enqueue(startNode);

            int steps = 0;
            PathNode current;

            do
            {
                // abort if calculation is too expensive
                if (++steps > stepLimit) return null;

                // examine the cheapest node among the yet to be explored
                current = open.Dequeue();

                // Finish?
                if (current.Cell.Matches(end))
                {
                    // paths which lead to the requested goal are cached for reuse
                    Path path = new Path(current);

                    if (knownPaths.ContainsKey(request))
                    {
                        knownPaths[request] = path.Copy();
                    }
                    else
                    {
                        knownPaths.Add(request, path.Copy());
                    }

                    return path;
                }

                // Explore all neighbours of the current cell
                ICollection<IGridCell> neighbours = map.GetNeighbourCells(current.Cell);

                foreach (IGridCell cell in neighbours)
                {
                    // discard nodes that are not of interest
                    if (closed.Contains(cell) || (cell.Matches(end) == false && !cell.IsWalkable(unit)))
                    {
                        continue;
                    }

                    // successor is one of current's neighbours
                    PathNode successor = new PathNode(unit,current, cell, end);
                    PathNode contained = open.Find(successor);

                    if (contained != null && successor.F >= contained.F)
                    {
                        // This cell is already in the open list represented by
                        // another node that is cheaper
                        continue;
                    }
                    else if (contained != null && successor.F < contained.F)
                    {
                        // This cell is already in the open list but on a more expensive
                        // path -> "integrate" the node into the current path
                        contained.Predecessor = current;
                        contained.Update();
                        open.Update(contained);
                    }
                    else
                    {
                        // The cell is not in the open list and therefore still has to
                        // be explored
                        open.Enqueue(successor);
                    }
                }

                // add current to the list of the already explored nodes
                closed.AddLast(current.Cell);

            } while (open.Peek() != null);

            return null;
        }
Пример #26
0
        public void DequeueTest()
        {
            PriorityQueue<int> actual = new PriorityQueue<int> { 12, 6, 3, 1, 0, 8 };

            Assert.AreEqual(0, actual.Dequeue());
            Assert.AreEqual(1, actual.Peek());
            Assert.AreEqual(5, actual.Count);
        }
Пример #27
0
            internal IEnumerable <Tuple <QuadNode, double> > GetNodesInside(Rect bounds)
            {
                double w           = _bounds.Width / 2.0;
                double h           = _bounds.Height / 2.0;
                Rect   topLeft     = new Rect(_bounds.Left, _bounds.Top, w, h);
                Rect   topRight    = new Rect(_bounds.Left + w, _bounds.Top, w, h);
                Rect   bottomLeft  = new Rect(_bounds.Left, _bounds.Top + h, w, h);
                Rect   bottomRight = new Rect(_bounds.Left + w, _bounds.Top + h, w, h);
                PriorityQueue <IEnumerator <Tuple <QuadNode, double> >, double> queue = new PriorityQueue <IEnumerator <Tuple <QuadNode, double> >, double>(invert: true);

                if (_nodes != null)
                {
                    queue.Enqueue(_nodes.GetNodesInside(bounds).GetEnumerator(), _nodes.Next.Priority);
                }
                if (_topLeft != null && topLeft.Intersects(bounds))
                {
                    queue.Enqueue(_topLeft.GetNodesInside(bounds).GetEnumerator(), _topLeft._potential);
                }
                if (_topRight != null && topRight.Intersects(bounds))
                {
                    queue.Enqueue(_topRight.GetNodesInside(bounds).GetEnumerator(), _topRight._potential);
                }
                if (_bottomLeft != null && bottomLeft.Intersects(bounds))
                {
                    queue.Enqueue(_bottomLeft.GetNodesInside(bounds).GetEnumerator(), _bottomLeft._potential);
                }
                if (_bottomRight != null && bottomRight.Intersects(bounds))
                {
                    queue.Enqueue(_bottomRight.GetNodesInside(bounds).GetEnumerator(), _bottomRight._potential);
                }
                while (queue.Count > 0)
                {
                    IEnumerator <Tuple <QuadNode, double> > enumerator = queue.Dequeue().Key;
                    if (enumerator.MoveNext())
                    {
                        Tuple <QuadNode, double> current = enumerator.Current;
                        QuadNode node         = current.Item1;
                        double   potential    = current.Item2;
                        double   newPotential = (queue.Count <= 0) ? potential : ((!potential.IsNaN()) ? Math.Max(potential, queue.Peek().Value) : queue.Peek().Value);
                        if (newPotential > node.Priority)
                        {
                            IEnumerator <Tuple <QuadNode, double> > enumerator2 = Enumerable.Repeat(Tuple.Create(node, double.NaN), 1).GetEnumerator();
                            queue.Enqueue(enumerator2, node.Priority);
                        }
                        else
                        {
                            yield return(Tuple.Create(node, newPotential));
                        }
                        if (!potential.IsNaN())
                        {
                            queue.Enqueue(enumerator, potential);
                        }
                    }
                }
            }
Пример #28
0
 public void Peek_on_empty()
 {
     var sut = new PriorityQueue<string>();
     Assert.Throws<ArgumentOutOfRangeException>(() => sut.Peek());
 }
Пример #29
0
 public void Peek_on_non_empty()
 {
     var sut = new PriorityQueue<string>();
     sut.Enqueue("a", 1);
     Assert.AreEqual("a", sut.Peek());
 }
Пример #30
0
        private static void Dijkstra(Dictionary<Node, List<Edge>> map, Node source)
        {
            PriorityQueue<Node> queue = new PriorityQueue<Node>();

            foreach (KeyValuePair<Node, List<Edge>> pair in map)
            {
                if (pair.Key.Index != source.Index)
                {
                    queue.Enqueue(pair.Key);
                    pair.Key.DijkstraDistance = int.MaxValue;
                }
            }

            source.DijkstraDistance = 0;
            queue.Enqueue(source);

            Node currentNode;
            while (queue.Count != 0)
            {
                currentNode = queue.Peek();

                if (currentNode.DijkstraDistance == int.MaxValue)
                {
                    break;
                }

                foreach (Edge edge in map[currentNode])
                {
                    int potDistance = currentNode.DijkstraDistance + edge.Distance;

                    if (potDistance < edge.Node.DijkstraDistance)
                    {
                        edge.Node.DijkstraDistance = potDistance;
                        Node nextNode = new Node(edge.Node.Index);
                        nextNode.DijkstraDistance = potDistance;
                        queue.Enqueue(nextNode);
                    }
                }

                queue.Dequeue();
            }
        }
        /// <summary>
        /// A discrete event simulation of combat over time.
        /// </summary>
        private void SimulateCombat(PriorityQueue<Spell> queue)
        {
            int threadID = System.Threading.Thread.CurrentThread.ManagedThreadId;

            float timer = 0;
            float timelimit = Options.Duration;         //in seconds
            float latency = (Options.Latency / 1000);   //in milliseconds

            DateTime start = DateTime.Now;

            Debug.WriteLine("-------------------");
            Debug.WriteLine(String.Format("thread:[{0}] | time: {1:0.00} - simulation starts [timelimit: {2:0.00}]", threadID, timer, timelimit));
            //Trace.TraceInformation("Combat simulation started!");
            //Trace.Flush();

            while (queue.Count != 0)
            {
                //get the spell at the front of the queue
                Spell spell = queue.Dequeue();

                //this will be the next event that must occur in the combat timeline
                //so align the simulation timer to match the scheduledtime of the event
                timer = (spell.ScheduledTime);

                //events that are scheduled to occur after the simulation has ended are irrelevant
                if (timer >= timelimit)
                {
                    timer = timelimit;
                    queue.Clear();
                    continue;
                }

                #region if this is a dot spell, check that its ready
                if (spell.IsTicking)
                {
                    //perform the tick
                    Debug.WriteLine(String.Format("thread:[{0}] | time: {1:0.00} - {2} ticks for {3:0} damage", threadID, timer, spell.Name, spell.TickHitDamage()));

                    //schedule the next tick
                    spell.ScheduledTime += spell.TickTime();

                    //add it back to the queue
                    queue.Enqueue(spell);

                    //and skip to the next iteration
                    continue;
                }
                #endregion

                //get the cast time or the GCD for this ability
                float casttime = spell.ExecuteTime() > 0 ? spell.ExecuteTime() : spell.GlobalCooldown();

                //check if there is enough time left to cast this spell
                if ((timer + casttime + latency) < timelimit)
                {
                    //TODO: recalculate stats to account for all combat effects (e.g. +spell, +haste, +spi, +crit bonuses etc)
                    //spell.Stats = updatedStats;
                    //or
                    //spell.Execute(updatedStats);

                    //the spell lands on the target, so calculate damage and trigger any related effects
                    spell.Execute();

                    //prioritise - i.e. the next 'event' in the timeline 
                    //(think of this as the time when the spell can be recast [for direct damage spells] or the next tick [for dots]).
                    spell.ScheduledTime += spell.GetTimeDelay();
                    timer += latency;

                    //append to the events history
                    //Events.Add(spell);

                    if (spell.ScheduledTime < timelimit)
                    {
                        //this spell can be re-cast before the simulation ends, so add it back to the queue
                        queue.Enqueue(spell);
                    }
                    else
                    {
                        //the simulation will end before this spell can be re-cast, so we wont bother adding it to the queue
                        Debug.WriteLine(String.Format("thread:[{0}] | time: {1:0.00} - removing {2} - the simulation ends before it can be re-casted", threadID, timer, spell.Name));
                    }
                }
                else
                {
                    //There is still some simulation time left, but not enough to cast the current spell.
                    //This means that the simulation is almost finished.
                    //However, there might be enough time to cast the next spell in the queue ...
                    if (queue.Count > 0)
                    {
                        Spell next = queue.Peek();
                        Debug.WriteLine(String.Format("thread:[{0}] | time: {1:0.00} - not enough time to cast {2} [{3:0.00}s cast, {4:0.00}s lat] - trying next spell: {5}", threadID, timer, spell.Name, spell.ExecuteTime(), latency, next.Name));
                    }
                    else
                    {
                        Debug.WriteLine(String.Format("thread:[{0}] | time: {1:0.00} - not enough time to cast {2} - [this was the last spell in the queue]", threadID, timer, spell.Name));
                    }
                }
            }

            Debug.WriteLine(String.Format("thread:[{0}] | time: {1:0.00} - simulation ends [no spells left in the queue]", threadID, timer));
            DateTime stop = DateTime.Now;
            Debug.WriteLine(String.Format("thread:[{0}] | simulation time: {1} seconds", threadID, (stop - start).Seconds));

            //Trace.TraceInformation("Combat simulation finished!");
            //Trace.Flush();
        }