Пример #1
0
        public void Test_Integration_2()
        {
            PriorityQueue <double> q = null;

            double[] items = { 82, 100, 9.3, 1.19, 10, 29, 12, 9.0006, 22, 20.9, 207, 13.56, 30, 2, 66 };
            SortedList <double, double> monitor = new SortedList <double, double>();

            q = new MinPriorityQueue <double>();

            for (int i = 0; i < items.Length; i++)
            {
                q.Enqueue(items[i]);
                monitor.Add(items[i], items[i]);

                if (i == 3)
                {
                    q.Dequeue();
                    monitor.Remove(1.19);
                }
                else if (i == 8)
                {
                    q.Dequeue();
                    monitor.Remove(9.0006);
                }
            }

            foreach (double monitorItem in monitor.Values)
            {
                Assert.AreEqual(monitorItem, q.Dequeue());
            }
        }
Пример #2
0
        public void Test_Dequeue()
        {
            PriorityQueue <double> q = null;

            q = new MinPriorityQueue <double>();
            q.Enqueue(3);
            q.Enqueue(2);
            q.Enqueue(1);

            Assert.AreEqual(1, q.Dequeue());
            Assert.AreEqual(2, q.Dequeue());
            Assert.AreEqual(3, q.Dequeue());
        }
        public void PriorityQueue_Test()
        {
            var queue = new MinPriorityQueue <int>();

            queue.Enqueue(10);
            queue.Enqueue(9);
            queue.Enqueue(1);
            queue.Enqueue(21);

            Assert.AreEqual(queue.Dequeue(), 1);
            Assert.AreEqual(queue.Dequeue(), 9);
            Assert.AreEqual(queue.Dequeue(), 10);
            Assert.AreEqual(queue.Dequeue(), 21);
        }
Пример #4
0
        public void MinPriorityQueueMovesNextLowestPriorityItemToHeadAfterRemoveItem()
        {
            var priorityQueue = new MinPriorityQueue <string, int>(50);

            List <Tuple <string, int> > items = new List <Tuple <string, int> >
            {
                new Tuple <string, int>("A_50", 50),
                new Tuple <string, int>("A_41", 41),
                new Tuple <string, int>("A_38", 38),
                new Tuple <string, int>("A_37", 37),
                new Tuple <string, int>("A_23", 23),
                new Tuple <string, int>("A_11", 11),
                new Tuple <string, int>("A_5", 5),
                new Tuple <string, int>("A_3", 3),
            }.Randomize()
            .ToList();

            priorityQueue.EnqueueRange(items);

            priorityQueue.Dequeue();

            string item = priorityQueue.Peek();

            Assert.AreEqual("A_5", item);
        }
Пример #5
0
        public void Test_Remove()
        {
            PriorityQueue <double> q = null;

            double[] items = { 5, 85, 43, 2, 28, 99, 67, 1.98, 33, 19, 17, 44 };
            SortedList <double, double> monitor = new SortedList <double, double>();

            q = new MinPriorityQueue <double>(7);

            for (int i = 0; i < items.Length; i++)
            {
                q.Enqueue(items[i]);
                monitor.Add(items[i], items[i]);
            }

            q.Remove(43);
            monitor.Remove(43);
            q.Remove(17);
            monitor.Remove(17);

            foreach (double monitorItem in monitor.Values)
            {
                Assert.AreEqual(monitorItem, q.Dequeue());
            }
        }
Пример #6
0
        public void MinPriorityQueue_FullTest_Successful()
        {
            var source      = new List <int>();
            var sourceCount = Faker.RandomNumber.Next(20, 100);

            for (int i = 0; i < sourceCount; i++)
            {
                source.Add(Faker.RandomNumber.Next());
            }

            var additionalDataCount = Faker.RandomNumber.Next(10, 50);

            // Act 1. Build priority queue with some initial data.
            var queue = new MinPriorityQueue <int>(source);

            // Act 2. Add some additional data using Enqueue
            for (int i = 0; i < additionalDataCount; i++)
            {
                queue.Enqueue(Faker.RandomNumber.Next());
            }

            // Act 3 & Assert - Check results from the queue
            var prev = -1;             // Set a negative number as previous; all data in the queue is assumed to be positive.

            while (!queue.IsEmpty())
            {
                var curr = queue.Dequeue();
                Assert.IsTrue(curr >= prev);
                prev = curr;
            }
        }
Пример #7
0
        public void Test_Dequeue_EmptyQ()
        {
            PriorityQueue <double> q = null;

            q = new MinPriorityQueue <double>();

            Assert.AreEqual(default(double), q.Dequeue());
        }
Пример #8
0
        public void Dequeue_Should_Always_Return_The_Min_Value()
        {
            var pq = new MinPriorityQueue <int>();

            pq.Enqueue(6);
            pq.Enqueue(9);
            pq.Enqueue(8);
            pq.Enqueue(3);
            pq.Enqueue(5);
            pq.Enqueue(1);
            pq.Enqueue(3);

            pq.Count.Should().Be(7);

            pq.Dequeue().Should().Be(1);
            pq.Count.Should().Be(6);
            pq.Dequeue().Should().Be(3);
            pq.Count.Should().Be(5);
            pq.Dequeue().Should().Be(3);
            pq.Count.Should().Be(4);
            pq.Dequeue().Should().Be(5);
            pq.Count.Should().Be(3);
            pq.Dequeue().Should().Be(6);
            pq.Count.Should().Be(2);
            pq.Dequeue().Should().Be(8);
            pq.Count.Should().Be(1);
            pq.Dequeue().Should().Be(9);
            pq.Count.Should().Be(0);
        }
Пример #9
0
        public IEnumerable <Node> GetPath(Node start, Node goal)
        {
            var cost    = new Dictionary <Node, int>();
            var parents = new Dictionary <Node, Node>();
            var visited = new HashSet <Node>();

            var queue = new MinPriorityQueue <Node>();

            cost[start]    = 0;
            parents[start] = null;
            queue.Enqueue(start);

            bool foundPath = false;

            while (queue.Count > 0)
            {
                var current = queue.Dequeue();
                visited.Add(current);

                if (current.Equals(goal))
                {
                    foundPath = true;
                    break;
                }

                var neighbours = this.GetNeighbours(current);
                foreach (var neighbour in neighbours)
                {
                    if (visited.Contains(neighbour) || this.IsWall(neighbour))
                    {
                        continue;
                    }

                    var newCost = cost[current] + 1;

                    if (!cost.ContainsKey(neighbour) || newCost < cost[neighbour])
                    {
                        cost[neighbour] = newCost;
                        neighbour.F     = newCost + this.GetH(neighbour, goal);
                        queue.Enqueue(neighbour);
                        parents[neighbour] = current;
                    }
                }
            }

            if (!foundPath)
            {
                throw new InvalidOperationException("No path found.");
            }

            return(this.GetPath(parents, goal));
        }
        public void Dequeue_ShouldRemoveTheSmallestItem()
        {
            var items = new List <char> {
                'T', 'Z', 'B'
            };

            var target = new MinPriorityQueue <char>();

            items.ForEach(anItem => target.Enqueue(anItem));
            items.Sort();

            Assert.That(target.Dequeue(), Is.EqualTo(items[0]));
        }
Пример #11
0
        public void ReplacingMinElementAndCheckingIfExtractedInSortedOrder()
        {
            var pq = new MinPriorityQueue <int, int>();

            int maxHeapElement = 50000;
            int minHeapElement = -50000;

            int addedElements = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minHeapElement;
                while (el <= maxHeapElement)
                {
                    pq.Enqueue(el, -el);
                    addedElements++;
                    el += i;
                }
            }

            if (pq.Count != addedElements)
            {
                Assert.Fail();
            }

            pq.ReplaceFirst(int.MaxValue, -int.MaxValue);
            pq.ReplaceFirst(int.MaxValue, -int.MaxValue);
            pq.ReplaceFirst(int.MaxValue, -int.MaxValue);

            int removedElements = 0;
            var min             = pq.Peek();

            while (!pq.IsEmpty)
            {
                var kvp = pq.Peek();
                if (min.Key > kvp.Key)
                {
                    Assert.Fail();
                }

                min = pq.Dequeue();
                removedElements++;
            }

            Assert.IsTrue(pq.IsEmpty &&
                          pq.Count == 0 &&
                          addedElements == removedElements);
        }
Пример #12
0
        public void HeapifyUnsortedCollectionAndCheckIfExtractedInSortedOrder()
        {
            var pq = new MinPriorityQueue <int, int>();

            var unsortedList = new List <KeyValuePair <int, int> >();

            int maxHeapElement = 50000;
            int minHeapElement = -50000;

            int addedElements = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minHeapElement;
                while (el <= maxHeapElement)
                {
                    unsortedList.Add(new KeyValuePair <int, int>(el, -el));
                    addedElements++;
                    el += i;
                }
            }

            pq.Heapify(unsortedList);

            if (pq.Count != addedElements)
            {
                Assert.Fail("1");
            }

            int removedElements = 0;
            var min             = pq.Peek();

            while (!pq.IsEmpty)
            {
                var kvp = pq.Peek();
                if (min.Key > kvp.Key)
                {
                    Assert.Fail("2");
                }

                min = pq.Dequeue();
                removedElements++;
            }

            Assert.IsTrue(pq.IsEmpty &&
                          pq.Count == 0 &&
                          addedElements == removedElements);
        }
Пример #13
0
        public void AddingElementsWithCustomComparerAndCheckingIfExtractedInSortedOrder()
        {
            //Creating heap with reversed comparer
            var pq = new MinPriorityQueue <int, int>(Comparer <int> .Create(
                                                         (x, y) => y.CompareTo(x)));

            int maxHeapElement = 50000;
            int minHeapElement = -50000;

            int addedElements = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minHeapElement;
                while (el <= maxHeapElement)
                {
                    pq.Enqueue(el, -el);
                    addedElements++;
                    el += i;
                }
            }

            if (pq.Count != addedElements)
            {
                Assert.Fail();
            }

            int removedElements = 0;
            // because of the reversed comparer
            var max = pq.Peek();

            while (!pq.IsEmpty)
            {
                var kvp = pq.Peek();
                if (max.Key < kvp.Key)
                {
                    Assert.Fail();
                }

                max = pq.Dequeue();
                removedElements++;
            }

            Assert.IsTrue(pq.IsEmpty &&
                          pq.Count == 0 &&
                          addedElements == removedElements);
        }
        private static int[] DequeueAll(MinPriorityQueue <int> queue)
        {
            var result = new List <int>();

            while (!queue.IsEmpty())
            {
                Console.WriteLine("Queue: {0}", queue);
                var dq = queue.Dequeue();
                Console.WriteLine(" Dequeue: {0}", dq);
                result.Add(dq);
            }

            return(result.ToArray());
        }
Пример #15
0
        public void DequeueMinValue()
        {
            var sut = new MinPriorityQueue <int, int>();

            for (var i = 0; i < 50000; i++)
            {
                sut.Enqueue(i, i);
            }

            for (var i = 0; i < 50000; i++)
            {
                Assert.AreEqual(i, sut.Dequeue());
            }
        }
Пример #16
0
        /// <summary>
        /// Nearest neighbor search method to find the single nearest neighbor at a given point.
        /// Translated from https://github.com/gvd/kdtree/blob/master/kdtree.h
        /// </summary>
        /// <param name="query">The nearest neighbor search query point.</param>
        /// <returns>The closest node to the parameter query is returned.</returns>
        //public KDNode NNSearch(Point query)
        //{
        //	MinPriorityQueue<Tuple<double, KDNode>> pq = new MinPriorityQueue<Tuple<double, KDNode>>();

        //	//Tuple<double, KDNode> best = new Tuple<double, KDNode>(1.79769e+308, root);

        //	pq.Enqueue(new Tuple<double, KDNode>(0.0, root));

        //	do
        //	{
        //		var current = pq.Dequeue();
        //              //if (current.Item1 >= best.Item1)
        //              //{
        //              //	if (EuclideanDistance(query, current.Item2.Data) > EuclideanDistance(query, best.Item2.Data))
        //              //		return best.Item2;
        //              //	else
        //              //		return current.Item2;
        //              //}
        //              List<KDNode> a = new List<KDNode>
        //              {

        //              };
        //              var currentNode = current.Item2;
        //		//double d = EuclideanDistance(query, currentNode.Data);
        //		//double dx = Subtract(query, currentNode.Data, currentNode.Depth);
        //		if ()
        //		{
        //			best = new Tuple<double, KDNode>(d, currentNode);
        //		}

        //		KDNode near, far;


        //                  near = currentNode.Left;
        //		else
        //                  near = currentNode.Right;


        //                  far = currentNode.Right;
        //		else
        //                  far = currentNode.Left;

        //		if (near != null)
        //                  pq.Enqueue(new Tuple<double, KDNode>(0, near));
        //		if (far != null)
        //                  pq.Enqueue(new Tuple<double, KDNode>(0, far));

        //	} while (pq.Count() != 0);

        //	return best.Item2;
        //}

        public List <KDNode> LocSearch(Point query)
        {
            MinPriorityQueue <Tuple <double, KDNode> > pq = new MinPriorityQueue <Tuple <double, KDNode> >();

            Point p = new Point(0, 0);

            List <KDNode> a = new List <KDNode>
            {
            };

            pq.Enqueue(new Tuple <double, KDNode>(0.0, root));

            do
            {
                var current = pq.Dequeue();
                // current.Item2.Data;
                var currentNode = current.Item2;
                if (query.x < currentNode.Data.x && currentNode.Data.x < query.x && query.y < currentNode.Data.y)
                {
                    a.Add(currentNode);
                }
                double d  = EuclideanDistance(query, currentNode.Data);
                double dx = Subtract(query, currentNode.Data, currentNode.Depth);

                KDNode near;

                if (dx <= 0)
                {
                    near = currentNode.Left;
                }
                else
                {
                    near = currentNode.Right;
                }

                //if (dx <= 0)
                //    far = currentNode.Right;
                //else
                //    far = currentNode.Left;

                if (near != null)
                {
                    pq.Enqueue(new Tuple <double, KDNode>(0, near));
                }
            } while (pq.Count() != 0);

            return(a);
        }
        public void Enqueue_ShouldEnsureTheAscendingOrder()
        {
            var items = new List <char> {
                'K', 'L', 'A', 'Z'
            };

            var target = new MinPriorityQueue <char>();

            items.ForEach(anItem => target.Enqueue(anItem));

            items.Sort();
            foreach (var item in items)
            {
                Assert.That(target.Dequeue(), Is.EqualTo(item));
            }
        }
        public void MinPriorityQueue_Enqueue()
        {
            int capacity = 5;

            var q = new MinPriorityQueue<Element>(capacity);

            for (int i = capacity; i > 0; i--)
            {
                q.Enqueue(new Element { Number = i, Data = new byte[i]});
            }

            Assert.IsTrue(q.Size == capacity);

            for (int i = 1; i <= capacity; i++)
            {
                var e = q.Dequeue();
                Assert.IsTrue(i == e.Number);
            }
        }
Пример #19
0
        public void PrioritizeInALifoManner()
        {
            var sut = new MinPriorityQueue <int, int>(Stability.Lifo);

            for (var i = 0; i < 10000; i++)
            {
                for (var j = 0; j < 5; j++)
                {
                    sut.Enqueue(i, i * 5 + j);
                }
            }

            for (var i = 0; i < 10000; i++)
            {
                for (var j = 4; j >= 0; j--)
                {
                    Assert.AreEqual(i * 5 + j, sut.Dequeue());
                }
            }
        }
        public void MaintainMinHeap()
        {
            var sut = new MinPriorityQueue <int, int>();

            var random        = new Random();
            var sortedResults = new List <int>();

            for (var i = 0; i < 50000; i++)
            {
                sortedResults.Add(random.Next(1000));
            }

            sut.AddRange(sortedResults, x => x);

            sortedResults = sortedResults.OrderBy(x => x).ToList();

            for (var i = 0; i < 50000; i++)
            {
                Assert.AreEqual(sut.Dequeue(), sortedResults[i]);
            }
        }
Пример #21
0
        public void HandleUnsortedInput()
        {
            var sut    = new MinPriorityQueue <int, int>();
            var random = new Random();

            for (var i = 0; i < 50000; i++)
            {
                var randomValue = random.Next(1000);
                sut.Enqueue(randomValue, randomValue);
            }

            var results = new List <int>();

            for (var i = 0; i < 50000; i++)
            {
                results.Add(sut.Dequeue());
            }
            var sortedResults = new List <int>(results).OrderBy(x => x).ToList();

            CollectionAssert.AreEqual(sortedResults, results);
        }
Пример #22
0
        public void MinPriorityQueueDequeueReturnsItemWithLowestPriority()
        {
            var priorityQueue = new MinPriorityQueue <string, int>(50);

            List <Tuple <string, int> > items = new List <Tuple <string, int> >
            {
                new Tuple <string, int>("A_50", 50),
                new Tuple <string, int>("A_41", 41),
                new Tuple <string, int>("A_38", 38),
                new Tuple <string, int>("A_37", 37),
                new Tuple <string, int>("A_23", 23),
                new Tuple <string, int>("A_11", 11),
                new Tuple <string, int>("A_5", 5),
                new Tuple <string, int>("A_3", 3),
            }.Randomize()
            .ToList();

            priorityQueue.EnqueueRange(items);

            string item = priorityQueue.Dequeue();

            Assert.AreEqual("A_3", item);
        }
Пример #23
0
        public void MinPriorityQueueDequeueDoesRemoveItemFromQueue()
        {
            var priorityQueue = new MinPriorityQueue <string, int>(50);

            List <Tuple <string, int> > items = new List <Tuple <string, int> >
            {
                new Tuple <string, int>("A_50", 50),
                new Tuple <string, int>("A_41", 41),
                new Tuple <string, int>("A_38", 38),
                new Tuple <string, int>("A_37", 37),
                new Tuple <string, int>("A_23", 23),
                new Tuple <string, int>("A_11", 11),
                new Tuple <string, int>("A_5", 5),
                new Tuple <string, int>("A_3", 3),
            }.Randomize()
            .ToList();

            priorityQueue.EnqueueRange(items);

            priorityQueue.Dequeue();

            Assert.AreEqual(7, priorityQueue.Count);
        }
Пример #24
0
    public Stack <State> Run(int[] nodes, HeuristicMethod heuristic)
    {
        List <State>               nextStates  = new List <State>();
        HashSet <string>           openStates  = new HashSet <string>();
        MinPriorityQueue <State>   openedQueue = new MinPriorityQueue <State>(nodes.Length);
        Dictionary <string, State> closedQueue = new Dictionary <string, State>();

        State state = new State(parent: null, nodes: nodes, heuristic: heuristic);

        openedQueue.Enqueue(state);
        openStates.Add(state.GetStateCode());


        while (!openedQueue.IsEmpty())
        {
            State currentState = openedQueue.Dequeue();
            openStates.Remove(currentState.GetStateCode());

            // Is this final state
            if (currentState.IsFinalState())
            {
                return(GetFinalPath(currentState));
            }

            // Look into next state
            currentState.GetNextStates(ref nextStates);

            if (nextStates.Count > 0)
            {
                State closedState;
                State openState;
                State nextState;

                for (int i = 0; i < nextStates.Count; i++)
                {
                    closedState = null;
                    openState   = null;
                    nextState   = nextStates[i];

                    if (openStates.Contains(nextState.GetStateCode()))
                    {
                        // We already have same state in the open queue.
                        openState = openedQueue.Find(nextState, out int openStateIndex);

                        if (openState.IsCostlierThan(nextState))
                        {
                            // We have found a better way to reach at this state. Discard the costlier one
                            openedQueue.Remove(openStateIndex);
                            openedQueue.Enqueue(nextState);
                        }
                    }
                    else
                    {
                        // Check if state is in closed queue
                        string stateCode = nextState.GetStateCode();

                        if (closedQueue.TryGetValue(stateCode, out closedState))
                        {
                            // We have found a better way to reach at this state. Discard the costlier one
                            if (closedState.IsCostlierThan(nextState))
                            {
                                closedQueue.Remove(stateCode);
                                closedQueue[stateCode] = nextState;
                            }
                        }
                    }

                    // Either this is a new state, or better than previous one.
                    if (openState == null && closedState == null)
                    {
                        openedQueue.Enqueue(nextState);
                        openStates.Add(nextState.GetStateCode());
                    }
                }

                closedQueue[currentState.GetStateCode()] = currentState;
            }
        }
        // no result
        return(null);
    }
Пример #25
0
        /// <summary>
        /// A* on the graph.
        /// </summary>
        /// <param name="pathStoreLoc">The Queue to store the path in.</param>
        /// <param name="start">The starting node.</param>
        /// <param name="end">The ending node.</param>
        public double AStar(Queue<Node> pathStoreLoc, Node start, Node end, Node toIgnore = null)
        {
            MinPriorityQueue<Node> nodeList = new MinPriorityQueue<Node>();

            initializePathfinding(true);
            if (toIgnore != null)
                toIgnore.Visited = false;

            System.Func<Node, Node, float> Heuristic;
            if (allowedPaths == Paths.quadDir)
                Heuristic = ManhattenHeuristic;
            else if (allowedPaths == Paths.octDir)
                Heuristic = DiagonalHeuristic;
            else
                Heuristic = DiagonalHeuristic;

            start.CameFrom = null;
            start.heuristicCost = Heuristic(start, end);
            start.realCost = 0;
            nodeList.Enqueue(start, start.heuristicCost);

#if DEBUG_PATHFINDER_LOGDEBUG
            StringBuilder encountered = new StringBuilder();
            StringBuilder nodes = new StringBuilder();
            nodes.Append("Start node ").Append(start.Number).AppendLine();
            encountered.Append("Start node ").Append(start.Number).AppendLine();
            nodes.Append("End node ").Append(end.Number).AppendLine();
            encountered.Append("End node ").Append(end.Number).AppendLine();
#endif

            while (nodeList.Count > 0)
            {
                //Pick the best looking node, by f-value.
                Node best = nodeList.Dequeue();
                double bestDist = best.realCost;

#if DEBUG_PATHFINDER_LOGDEBUG
                encountered.Append("Node ").Append(best.Number).Append(" ").Append(best).AppendLine();
                nodes.Append("Node ").Append(best.Number).AppendLine();
#endif

                //If this is the end, stop, show the path, and return it.
                if (best.Equals(end))
                {
                    ReconstructPath(pathStoreLoc, end);
                    ShowPath(pathStoreLoc);

#if DEBUG_PATHFINDER_LOGDEBUG
                    encountered.Append("Finished!\n\nFinal dist: ")
                               .Append(best.realCost).AppendLine();
                    Debug.Log(encountered);
                    Debug.Log(nodes);
#endif
                    return best.realCost;
                }
                best.Visited = true;

                //string updateString = "updating: ";
                foreach (Edge e in best.getEdges())
                {
                    Node other = e.getNode();

                    //We already visited this node, move along,
                    if (other.Visited)
                        continue;

                    //Tentative distance.
                    double testDist = e.getWeight() + bestDist;

                    //If the other node isn't in the priority queue, add it.
                    if (!nodeList.Contains(other))
                    {
                        other.CameFrom = best;
                        other.realCost = testDist;
                        other.heuristicCost = Heuristic(other, end);
                        nodeList.Enqueue(other, other.realCost + other.heuristicCost);

#if DEBUG_PATHFINDER_LOGDEBUG
                        encountered.Append("   added ").Append(other.Number)
                                   .Append(", total estimated cost ")
                                   .Append(other.realCost + other.heuristicCost)
                                   .AppendLine();
#endif
                        continue;
                    }
                    //If the other node was a bad path, and this one's better, replace it.
                    else if (other.realCost > testDist)
                    {
                        other.CameFrom = best;
                        other.realCost = testDist;
                        nodeList.Update(other, other.realCost + other.heuristicCost);

#if DEBUG_PATHFINDER_LOGDEBUG
                        encountered.Append("   updated ").Append(other.Number)
                                   .Append(", total new estimated cost ")
                                   .Append(other.realCost + other.heuristicCost)
                                   .AppendLine();
#endif
                    }
                }
            }

#if DEBUG_PATHFINDER_LOGDEBUG
            encountered.Append("Failed!\n");
            Debug.Log(encountered);
            Debug.Log(nodes);
#endif
            return double.PositiveInfinity;
        }
Пример #26
0
        /// <summary>
        /// Returns a sorted list of nodes within a given endurance value.
        /// Performs a Dijkstra-like algorithm.
        /// </summary>
        /// <param name="satifies">The predicate each node must follow.</param>
        /// <param name="endurance">The maximum endurance to follow out.</param>
        /// <returns>A sorted list of nodes within a given endurance value.</returns>
        public List<Node> nodesThatSatisfyPred(Node startNode, System.Predicate<Node> satifies, float endurance = 16.0f, bool stopOnFirst = false, bool isPathfinding = true)
        {
            List<Node> foundNodes = new List<Node>();
            MinPriorityQueue<Node> nodeList = new MinPriorityQueue<Node>();

            initializePathfinding(isPathfinding);

            startNode.realCost = 0;
            nodeList.Enqueue(startNode, startNode.realCost);

#if DEBUG_PATHFINDER_LOGDEBUG
            StringBuilder encountered = new StringBuilder();
            StringBuilder nodes = new StringBuilder();
            nodes.Append("Start node ").Append(startNode.Number).AppendLine();
            encountered.Append("Start node ").Append(startNode.Number).AppendLine();
            encountered.Append("endurance = ").Append(endurance).AppendLine();
#endif

            while (nodeList.Count > 0)
            {
                //Pick the best looking node, by f-value.
                Node best = nodeList.Dequeue();
                double bestDist = best.realCost;
                
#if DEBUG_PATHFINDER_LOGDEBUG
                encountered.Append("Node ").Append(best.Number).Append(" ").Append(best).AppendLine();
                nodes.Append("Node ").Append(best.Number).AppendLine();
#endif

                best.Visited = true;

                if (satifies(best))
                {
                    foundNodes.Add(best);
                    if (stopOnFirst)
                        return foundNodes;
                }

                //string updateString = "updating: ";
                foreach (Edge e in best.getEdges())
                {
                    Node other = e.getNode();

                    //We already visited this node, move along,
                    if (other.Visited)
                        continue;

                    //Tentative distance.
                    double testDist = e.getWeight() + bestDist;

                    if (testDist > endurance)
                        continue;

                    //If the other node isn't in the priority queue, add it.
                    if (!nodeList.Contains(other))
                    {
                        other.CameFrom = best;
                        other.realCost = testDist;
                        nodeList.Enqueue(other, other.realCost);

#if DEBUG_PATHFINDER_LOGDEBUG
                        encountered.Append("   added ").Append(other.Number)
                                   .Append(", total estimated cost ")
                                   .Append(other.realCost).AppendLine();
#endif
                        continue;
                    }
                    //If the other node was a bad path, and this one's better, replace it.
                    else if (other.realCost > testDist)
                    {
                        other.CameFrom = best;
                        other.realCost = testDist;
                        nodeList.Update(other, other.realCost);

#if DEBUG_PATHFINDER_LOGDEBUG
                        encountered.Append("   updated ").Append(other.Number)
                                   .Append(", total new estimated cost ")
                                   .Append(other.realCost).AppendLine();
#endif
                    }
                }
            }
#if DEBUG_PATHFINDER_LOGDEBUG
            Debug.Log(encountered);
            Debug.Log(nodes);
#endif

            return foundNodes;
        }
Пример #27
0
        /// <summary>
        /// Uses Prim's algorithm to find the minimum spanning tree of the undirected weighted graph. Returns a <see cref="WeightedALGraph{TVertex, TWeight}"/> representing the MST.
        /// </summary>
        /// <typeparam name="TVertex">The data type of the vertices. TVertex implements <see cref="IComparable{T}"/>.</typeparam>
        /// <typeparam name="TWeight">The data type of weight of the edges. TWeight implements <see cref="IComparable{T}"/>.</typeparam>
        /// <param name="graph">The graph structure that implements <see cref="IWeightedGraph{TVertex, TWeight}"/>.</param>
        /// <returns>Returns a <see cref="WeightedALGraph{TVertex, TWeight}"/> representing the MST.</returns>
        public static WeightedALGraph <TVertex, TWeight> PrimMST <TVertex, TWeight>(this IWeightedGraph <TVertex, TWeight> graph)
            where TVertex : IComparable <TVertex>
            where TWeight : IComparable <TWeight>
        {
            if (graph.IsDirected)
            {
                throw new ArgumentException("Graph is directed!");
            }

            var mst = new WeightedALGraph <TVertex, TWeight>();

            // A hash set of the added vertices to the MST
            var addedVertices = new HashSet <TVertex>();
            // Comparer for the kvp in the priority queue
            var kvpComparer = Comparer <KeyValuePair <TWeight, KeyValuePair <TVertex, TVertex> > > .Create((x, y) =>
            {
                int cmp = 0;
                // null checking because TWeight can be null
                if (x.Key == null)
                {
                    if (y.Key == null)
                    {
                        cmp = -1;                // change cmp to skip next comparisons
                    }
                    else
                    {
                        return(int.MinValue);
                    }
                }

                if (cmp == 0)// if x.Key and y.Key are not null
                {
                    if (y.Key == null)
                    {
                        return(int.MaxValue);
                    }
                    // normal check if both weights are not null
                    cmp = x.Key.CompareTo(y.Key);
                }
                else
                {
                    cmp = 0; // if x.Key and y.Key were both null, compare the kvp value
                }
                if (cmp == 0)
                {
                    cmp = x.Value.Key.CompareTo(y.Value.Key);
                }
                if (cmp == 0)
                {
                    cmp = x.Value.Value.CompareTo(y.Value.Value);
                }
                return(cmp);
            });

            // Priority queue of the edges for computing. Having the weight as key and as value - another kvp with source vertex as key and destination vertex as value.
            var priorityQueue = new MinPriorityQueue <TWeight, KeyValuePair <TVertex, TVertex> >(kvpComparer);

            var vertices = graph.Vertices.ToList();

            if (vertices.Count == 0)
            {
                return(mst);
            }
            int verticesIndex = 0;

            mst.AddVertices(vertices);

            // Add dummy edge to the priority queue
            priorityQueue.Enqueue(default(TWeight), new KeyValuePair <TVertex, TVertex>(vertices[verticesIndex], vertices[verticesIndex]));
            addedVertices.Add(vertices[verticesIndex]);

            while (priorityQueue.Count > 0)
            {
                var     curKVP               = priorityQueue.Dequeue();
                TVertex curSourceVertex      = curKVP.Value.Key;
                TVertex curDestinationVertex = curKVP.Value.Value;

                // If the destination verex of the edge is not added we add the edge
                if (!addedVertices.Contains(curDestinationVertex))
                {
                    mst.AddEdge(curSourceVertex, curDestinationVertex, curKVP.Key);
                    addedVertices.Add(curDestinationVertex);
                }

                foreach (var edge in graph.OutgoingEdgesSorted(curDestinationVertex))
                {
                    var edgeDestination = edge.Destination;
                    var edgeWeight      = edge.Weight;

                    // If the destination vertex is added to the MST we skip it
                    if (addedVertices.Contains(edgeDestination))
                    {
                        continue;
                    }

                    // Add the edge for computing
                    priorityQueue.Enqueue(edgeWeight, new KeyValuePair <TVertex, TVertex>(curDestinationVertex, edgeDestination));
                }

                // If priority queue is empty
                if (priorityQueue.Count == 0)
                {
                    // Check if all vertices of the graph were added to the MST
                    if (addedVertices.Count != vertices.Count)
                    {
                        // If not we have a forest.
                        // Add the next non added vertex
                        while (verticesIndex < vertices.Count)
                        {
                            if (!addedVertices.Contains(vertices[verticesIndex]))
                            {
                                // Add dummy edge to the priority queue
                                priorityQueue.Enqueue(default(TWeight), new KeyValuePair <TVertex, TVertex>(vertices[verticesIndex], vertices[verticesIndex]));
                                addedVertices.Add(vertices[verticesIndex]);

                                break;
                            }
                            verticesIndex++;
                        }
                    }
                }
            }

            // Return MST
            return(mst);
        }
Пример #28
0
        public void MergingTwoPriorityQueuesAndCheckingIfExtractedInSortedOrder()
        {
            var pq1 = new MinPriorityQueue <int, int>();
            var pq2 = new MinPriorityQueue <int, int>();

            int maxElementInFirstHeap    = 100000;
            int minElementInFirstHeap    = 0;
            int addedElementsInFirstHeap = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minElementInFirstHeap;
                while (el <= maxElementInFirstHeap)
                {
                    pq1.Enqueue(el, -el);
                    addedElementsInFirstHeap++;
                    el += i;
                }
            }

            int maxElementInSecondHeap    = 50000;
            int minElementInSecondHeap    = -50000;
            int addedElementsInSecondHeap = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minElementInSecondHeap;
                while (el <= maxElementInSecondHeap)
                {
                    pq2.Enqueue(el, -el);
                    addedElementsInSecondHeap++;
                    el += i;
                }
            }

            if (pq1.Count != addedElementsInFirstHeap)
            {
                Assert.Fail("first priority queue incorrect count");
            }
            if (pq2.Count != addedElementsInSecondHeap)
            {
                Assert.Fail("second priority queue incorrect count");
            }

            var oldHeap = new MinPriorityQueue <int, int>();

            oldHeap.Heapify(pq1.ToArray());

            pq1.Merge(pq2);
            pq2.Merge(oldHeap);

            int mergedHeapElements = addedElementsInFirstHeap + addedElementsInSecondHeap;

            if (pq1.Count != mergedHeapElements)
            {
                Assert.Fail("merged first with second incorect count");
            }
            if (pq2.Count != mergedHeapElements)
            {
                Assert.Fail("merged second with first incorrect count");
            }

            var min1 = pq1.Peek();
            var min2 = pq2.Peek();

            if (min1.Key != min2.Key)
            {
                Assert.Fail("merged priority queues min element is different");
            }

            int removedElements = 0;

            while (!pq1.IsEmpty && !pq2.IsEmpty)
            {
                var kvp1 = pq1.Peek();
                var kvp2 = pq2.Peek();
                if (min1.Key > kvp1.Key)
                {
                    Assert.Fail();
                }
                if (min2.Key > kvp2.Key)
                {
                    Assert.Fail();
                }

                min1 = pq1.Dequeue();
                min2 = pq2.Dequeue();
                removedElements++;

                if (min1.Key != min2.Key)
                {
                    Assert.Fail("merged priority queues min element is different");
                }
            }

            Assert.IsTrue(pq1.IsEmpty &&
                          pq2.IsEmpty &&
                          pq1.Count == 0 &&
                          pq2.Count == 0 &&
                          mergedHeapElements == removedElements);
        }
Пример #29
0
        public void AddingAfterClearingHeap()
        {
            var pq = new MinPriorityQueue <int, int>();

            int maxHeapElement = 50000;
            int minHeapElement = -50000;

            int addedElements = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minHeapElement;
                while (el <= maxHeapElement)
                {
                    pq.Enqueue(el, -el);
                    addedElements++;
                    el += i;
                }
            }

            if (pq.Count != addedElements)
            {
                Assert.Fail();
            }

            pq.Clear();

            if (pq.Count != 0)
            {
                Assert.Fail();
            }

            addedElements = 0;

            //Adding every seventh number, then every fifth number,
            //every third and at last all numbers
            //NOTE: some items are added more than once
            for (int i = 7; i > 0; i -= 2)
            {
                int el = minHeapElement;
                while (el < maxHeapElement)
                {
                    pq.Enqueue(el, -el);
                    addedElements++;
                    el += i;
                }
            }

            if (pq.Count != addedElements)
            {
                Assert.Fail();
            }

            int removedElements = 0;
            var min             = pq.Peek();

            while (!pq.IsEmpty)
            {
                var kvp = pq.Peek();
                if (min.Key > kvp.Key)
                {
                    Assert.Fail();
                }

                min = pq.Dequeue();
                removedElements++;
            }

            Assert.IsTrue(pq.IsEmpty &&
                          pq.Count == 0 &&
                          addedElements == removedElements);
        }
Пример #30
0
        public List <String> LocSearch(Point query1, Point query2)
        {
            MinPriorityQueue <Tuple <double, KDNode> > pq = new MinPriorityQueue <Tuple <double, KDNode> >();



            List <String> a = new List <String>();

            pq.Enqueue(new Tuple <double, KDNode>(0.0, root));

            do
            {
                var current = pq.Dequeue();

                var currentNode = current.Item2;
                if (query1.x > query2.x && query1.y > query2.y)
                {
                    if (query1.x >= currentNode.Data.x && query2.x <= currentNode.Data.x && query1.y >= currentNode.Data.y && query2.y <= currentNode.Data.y)
                    {
                        a.Add(currentNode.Data.x.ToString());
                        a.Add(currentNode.Data.y.ToString());
                    }
                }
                else if (query1.x < query2.x && query1.y < query2.y)
                {
                    if (query1.x <= currentNode.Data.x && query2.x >= currentNode.Data.x && query1.y <= currentNode.Data.y && query2.y >= currentNode.Data.y)
                    {
                        a.Add(currentNode.Data.x.ToString());
                        a.Add(currentNode.Data.y.ToString());
                    }
                }
                else if (query1.x < query2.x && query1.y > query2.y)
                {
                    if (query1.x <= currentNode.Data.x && query2.x >= currentNode.Data.x && query1.y >= currentNode.Data.y && query2.y <= currentNode.Data.y)
                    {
                        a.Add(currentNode.Data.x.ToString());
                        a.Add(currentNode.Data.y.ToString());
                    }
                }
                else if (query1.x > query2.x && query1.y < query2.y)
                {
                    if (query1.x >= currentNode.Data.x && query2.x <= currentNode.Data.x && query1.y <= currentNode.Data.y && query2.y >= currentNode.Data.y)
                    {
                        a.Add(currentNode.Data.x.ToString());
                        a.Add(currentNode.Data.y.ToString());
                    }
                }



                KDNode near, far;


                near = currentNode.Right;


                far = currentNode.Left;

                if (near != null)
                {
                    pq.Enqueue(new Tuple <double, KDNode>(0, near));
                }
                if (far != null)
                {
                    pq.Enqueue(new Tuple <double, KDNode>(0, far));
                }
            } while (pq.Count() != 0);

            return(a);
        }
Пример #31
0
        protected virtual Stack<PathNode> AStar(Tile source, Tile destination)
        {
            List<Tile> closed = new List<Tile>();
            List<Tile> toDetermine;
            List<Tile> toAdd = new List<Tile>();
            Stack<PathNode> finalPath = null;
            MinPriorityQueue<PathNode> open = new MinPriorityQueue<PathNode>();
            List<PathNode> openList = new List<PathNode>();
            open.Enqueue(new PathNode(source, destination));
            openList.Add(open.Peek());
            PathNode currentNode = null;
            bool endReached = false;
            do
            {
                currentNode = open.Dequeue();
                openList.Remove(currentNode);
                if (currentNode.HCost == 0)
                {
                    endReached = true;
                    finalPath = currentNode.GetPath();
                }
                else
                {
                    closed.Add(tiles[currentNode.Current.X, currentNode.Current.Y]);
                    toDetermine = getAdjacent(currentNode);
                    foreach (Tile t in toDetermine)
                    {
                        bool remove = false;
                        if (t.Collision > source.Unit.Collision)
                            remove = true;
                        if (t.HasUnit())
                            if (t.Unit.Army != source.Unit.Army) //added so that AI works
                                remove = true;
                        if (closed.Contains(t))
                            remove = true;
                        //Add this if I want to have no duplicate pathnodes (currently,
                        //multiple exist with different source nodes
                        /*
                        PathNode temp = new PathNode(t.GridwiseLocation, currentNode, destination.GridwiseLocation);
                        foreach (PathNode p in openList)
                        {
                            if (p.Current == temp.Current)
                            {
                                if (p.GCost > temp.GCost)
                                {
                                    p.Source = temp.Source;

                                    remove = true;
                                }
                            }

                        }'*/

                        if (!remove)
                            toAdd.Add(t);
                    }

                    foreach (Tile t in toAdd)
                    {
                        PathNode temp = new PathNode(t.GridwiseLocation, currentNode, destination.GridwiseLocation);
                        open.Enqueue(temp);
                    }
                    toAdd.Clear();
                }
            } while (!endReached);

            return finalPath;
        }
Пример #32
0
        /// <summary>
        /// Uses Dijkstra's algorithm to compute the shortest paths in an unweighted graph. Shortest paths are computed with the distance between the vertices. Returns an <see cref="UnweightedGraphShortestPaths{TVertex}"/> object containg the shortest paths.
        /// </summary>
        /// <typeparam name="TVertex">The data type of the vertices. TVertex implements <see cref="IComparable{T}"/>.</typeparam>
        /// <param name="graph">The graph structure that implements <see cref="IGraph{TVertex}"/>.</param>
        /// <param name="source">The source vertex for which the shortest paths are computed.</param>
        /// <returns>Returns a <see cref="UnweightedGraphShortestPaths{TVertex}"/> containing the shortest paths for the given source vertex.</returns>
        public static UnweightedGraphShortestPaths <TVertex> DijkstraShortestPaths <TVertex>(this IGraph <TVertex> graph, TVertex source)
            where TVertex : IComparable <TVertex>
        {
            if (!graph.ContainsVertex(source))
            {
                throw new ArgumentException("Vertex does not belong to the graph!");
            }

            // A dictionary holding a vertex as key and its previous vertex in the path as value.
            var previousVertices = new Dictionary <TVertex, TVertex>();
            // A dictionary holding a vertex as key and the distance from the source vertex as value.
            var pathDistance = new Dictionary <TVertex, int>();
            // Comparer for the key-value pair in the sorted set
            var kvpComparer = Comparer <KeyValuePair <int, TVertex> > .Create((x, y) =>
            {
                var cmp = x.Key.CompareTo(y.Key);
                if (cmp == 0)
                {
                    cmp = x.Value.CompareTo(y.Value);
                }
                return(cmp);
            });

            // Sorted set containing the vertices for computing. Having a kvp with the distance from the source vertex as a key and the vertex as a value
            var priorityQueue = new MinPriorityQueue <int, TVertex>(kvpComparer);

            // Add the source vertex
            priorityQueue.Enqueue(0, source);

            while (priorityQueue.Count > 0)
            {
                var     curKVP      = priorityQueue.Dequeue();
                TVertex curVertex   = curKVP.Value;
                int     curDistance = curKVP.Key;

                foreach (var edge in graph.OutgoingEdgesSorted(curVertex))
                {
                    var edgeDestination = edge.Destination;

                    // If the edge destination is the source we continue with the next edge
                    if (object.Equals(source, edgeDestination))
                    {
                        continue;
                    }

                    int newDistance = curDistance + 1;

                    // If this distance is bigger or equal than an already computed distance we continue with the next edge
                    if (pathDistance.ContainsKey(edgeDestination))
                    {
                        if (newDistance.CompareTo(pathDistance[edgeDestination]) >= 0)
                        {
                            continue;
                        }
                    }

                    // Else we save the path
                    previousVertices[edgeDestination] = curVertex;
                    pathDistance[edgeDestination]     = newDistance;

                    // Add the destination vertex for computing
                    priorityQueue.Enqueue(newDistance, edgeDestination);
                }
            }

            var shortestPaths = new UnweightedGraphShortestPaths <TVertex>(source, previousVertices, pathDistance);

            return(shortestPaths);
        }
Пример #33
0
        public static IEnumerable <Point> FindShortestPath(
            Map map, Point source, Point dest, Action <Point, Color> UpdateColor = null)
        {
            // For each point we keep their distance to the destination.
            int[,] dist = new int[map.Height, map.Width];
            // For each point we keep the predecessor from source.
            Point[,] prev = new Point[map.Height, map.Width];

            // Initialize all distance to infinity.
            for (int i = 0; i < map.Height; i++)
            {
                for (int j = 0; j < map.Width; j++)
                {
                    dist[i, j] = int.MaxValue;
                }
            }

            // Set distance of source to 0.
            dist[source.Y, source.X] = 0;

            // .Net does not provide a priority queue, we emulate
            // with a sorted set.
            var q = new MinPriorityQueue <Point>();

            q.Enqueue(source, 0);

            while (prev[dest.Y, dest.X] == null && q.Count != 0)
            {
                // Get the next element in the queue.
                var current = q.Dequeue();
                UpdateColor(current, VisitedColor);
                // Get all the neighbors of the element.
                var neighbors = GetNeighbors(
                    map.Points, current, map.Height, map.Width);
                var currentDist = dist[current.Y, current.X];
                var cost        = GetCost(current);

                foreach (var point in neighbors)
                {
                    // If the distance to the current element + distance to the
                    // neighbor is less than the distance recorded for neighbor,
                    // the shortest pass to the neighbor is through the current
                    // element. We add the neighbor to the queue.
                    int newDist = currentDist + cost;
                    if (dist[point.Y, point.X] > newDist)
                    {
                        dist[point.Y, point.X] = newDist;
                        prev[point.Y, point.X] = current;
                        q.Enqueue(point, newDist);
                        UpdateColor(point, AddedColor);
                    }
                }
            }

            // Get the path from dest to source.
            if (prev[dest.Y, dest.X] != null)
            {
                var prevList = new List <Point>();
                var current  = dest;
                do
                {
                    prevList.Add(current);
                    current = prev[current.Y, current.X];
                } while (current != null);
                return(prevList);
            }

            return(Array.Empty <Point>());
        }
Пример #34
0
    // run away to the node that's farthest away from all enemies.
    private KeyValuePair<Result, UnitAction> RunAway()
    {
        MinPriorityQueue<UnitAction> farthestActions = new MinPriorityQueue<UnitAction>();
        foreach (Node n in pathManager.getAccessibleNodes(subjectRef))
        {
            int curCount = 0;
            foreach (Unit en in subjectsEnemiesRef)
                curCount += Node.range(n, en.getNode());

            // min priority queue: negate results.
            UnitAction runAwayTo = new UnitAction(subjectRef, null, n);
            farthestActions.Enqueue(runAwayTo, -curCount);
        }

        if (farthestActions.Count == 0)
            return new KeyValuePair<Result, UnitAction>(Result.NothingFound, UnitAction.DoNothing(subjectRef));
        else
            return new KeyValuePair<Result, UnitAction>(Result.Success, farthestActions.Dequeue());
    }
Пример #35
0
        public int GetLengthOfShortestPath(char source, char destination)
        {
            CheckIfPathCanExist(source, destination);

            var allNodes    = GetAllNodes();
            var pathIsALoop = source == destination;

            var minPathLengthFromSource = new Dictionary <char, int>(MAX_NUMBER_OF_NODES);
            var previousNodeOnShortestPathFromSource = new Dictionary <char, char>(MAX_NUMBER_OF_NODES);
            var remainingPaths = new MinPriorityQueue <PathFromSource>(MAX_NUMBER_OF_NODES);
            var unknownNode    = '-';

            if (pathIsALoop)
            {
                destination = DUMMY_NODE_NAME;
                allNodes.Add(destination);
            }

            foreach (var node in allNodes)
            {
                var initialPathLength = INFINITY;
                if (node == source)
                {
                    initialPathLength = 0;
                    remainingPaths.Enqueue(new PathFromSource(node, initialPathLength));
                }
                minPathLengthFromSource.Add(node, initialPathLength);
                previousNodeOnShortestPathFromSource.Add(node, unknownNode);
            }

            while (remainingPaths.Count != 0)
            {
                var currentPath = remainingPaths.Dequeue();
                var currentNode = currentPath.Stop;
                if (currentPath.Length > minPathLengthFromSource[currentNode] ||
                    (pathIsALoop && currentNode == destination))
                {
                    continue;
                }

                var neighbors = GetNeighborsOf(currentNode);
                foreach (var neighbor in neighbors)
                {
                    var currentNeighbor      = neighbor;
                    var additionalPathLength = GetLengthOf(currentNode, currentNeighbor);

                    if (pathIsALoop && currentNeighbor == source)
                    {
                        currentNeighbor = destination;
                    }

                    if (minPathLengthFromSource[currentNode] + additionalPathLength >= minPathLengthFromSource[currentNeighbor])
                    {
                        continue;
                    }

                    minPathLengthFromSource[currentNeighbor] = minPathLengthFromSource[currentNode] + additionalPathLength;
                    previousNodeOnShortestPathFromSource[currentNeighbor] = currentNode;
                    remainingPaths.Enqueue(new PathFromSource(currentNeighbor, minPathLengthFromSource[currentNeighbor]));
                }
            }

            var lengthOfShortestPath = minPathLengthFromSource[destination];

            CheckIfPathLengthIsValid(lengthOfShortestPath);
            return(lengthOfShortestPath);
        }