Exemple #1
0
        public void TestDebugUpdatePriorityThrowsOnNodeNotInQueue()
        {
            Node node = new Node(1);
            HeapPriorityQueue <Node> queue = new HeapPriorityQueue <Node>(3);

            Assert.Throws <InvalidOperationException>(() => queue.UpdatePriority(node, 2));
        }
Exemple #2
0
    void SetVals(HeapPriorityQueue <MapNode> openQ, int x, int y, int g, int g_inc, int count, coord prev, int end_x, int end_y)
    {
        if (!m_Map[x, y].closed && m_Map[x, y].g > g + g_inc)
        {
            m_Map[x, y].g        = g + g_inc;
            m_Map[x, y].h        = Heuristic(x, y, end_x, end_y);
            m_Map[x, y].f        = m_Map[x, y].g + m_Map[x, y].h;
            m_Map[x, y].count    = count + 1;
            m_Map[x, y].previous = prev;

            /*if(Heuristic(prev.x, prev.y, x, y) > 1)
             * {
             *      Debug.Log("Err: H: " + Heuristic(prev.x, prev.y, x, y).ToString() + ": prev (" + prev.x.ToString() +", " + prev.y.ToString() + ") to current (" + x.ToString() + ", " + y.ToString() + ")");
             * }*/

            if (openQ.Contains(m_Map[x, y]))
            {
                openQ.UpdatePriority(m_Map[x, y], m_Map[x, y].f);
            }
            else
            {
                openQ.Enqueue(m_Map[x, y], m_Map[x, y].f);
            }
        }
    }
        private void Update(UInt32 pIndex, List <PointRelation> neighbors, double coreDistance)
        {
            for (int i = 0; i < neighbors.Count; i++)//遍历邻域点集
            {
                UInt32 p2Index = neighbors[i].To;

                if (_points[p2Index].WasProcessed)
                {
                    continue;
                }

                //计算该邻域点到中心点pIndex的可达距离
                double newReachabilityDistance = Math.Max(coreDistance, neighbors[i].Distance);

                //如果该邻域点的可达距离不存在
                if (double.IsNaN(_points[p2Index].ReachabilityDistance))
                {
                    _points[p2Index].ReachabilityDistance = newReachabilityDistance;
                    //将该点加入有序队列
                    _seeds.Enqueue(_points[p2Index], newReachabilityDistance);
                }
                //该点的可达距离存在,则更新可达距离
                else if (newReachabilityDistance < _points[p2Index].ReachabilityDistance)
                {
                    _points[p2Index].ReachabilityDistance = newReachabilityDistance;
                    _seeds.UpdatePriority(_points[p2Index], newReachabilityDistance);
                }
            }
        }
Exemple #4
0
        private void Update(UInt32 pIndex, List <PointRelation> neighbors, double coreDistance)
        {
            for (int i = 0; i < neighbors.Count; i++)
            {
                UInt32 p2Index = neighbors[i].To;

                if (_points[p2Index].WasProcessed)
                {
                    continue;
                }

                double newReachabilityDistance = Math.Max(coreDistance, neighbors[i].Distance);

                if (double.IsNaN(_points[p2Index].ReachabilityDistance))
                {
                    _points[p2Index].ReachabilityDistance = newReachabilityDistance;
                    _seeds.Enqueue(_points[p2Index], newReachabilityDistance);
                }
                else if (newReachabilityDistance < _points[p2Index].ReachabilityDistance)
                {
                    _points[p2Index].ReachabilityDistance = newReachabilityDistance;
                    _seeds.UpdatePriority(_points[p2Index], newReachabilityDistance);
                }
            }
        }
Exemple #5
0
        public List <SearchNode> getPath(SearchNode start, SearchNode end, scoringFunction func)
        {
            List <SearchNode> optimalPath = new List <SearchNode>();
            HashSet <int>     closeSet    = new HashSet <int>();
            HeapPriorityQueue <SearchNode>      openSet  = new HeapPriorityQueue <SearchNode>(80000);
            Dictionary <int, double>            gScore   = new Dictionary <int, double>();
            Dictionary <int, double>            fScore   = new Dictionary <int, double>();
            Dictionary <int, SearchNode>        nodes    = new Dictionary <int, SearchNode>();
            Dictionary <SearchNode, SearchNode> cameFrom = new Dictionary <SearchNode, SearchNode>();

            gScore[start.GetHashCode()] = 0;
            fScore[start.GetHashCode()] = start.dist(end);
            openSet.Enqueue(start, 0);
            while (openSet.Count > 0)
            {
                SearchNode current = openSet.Dequeue();
                if (current == end)
                {
                    optimalPath.Add(current);
                    while (cameFrom.ContainsKey(current))
                    {
                        current = cameFrom[current];
                        optimalPath.Add(current);
                    }
                    return(optimalPath);
                }
                closeSet.Add(current.GetHashCode());
                foreach (var neighbor in GetNeighbors(current))
                {
                    if (!closeSet.Contains(neighbor.GetHashCode()))
                    {
                        double tentativeGScore = gScore[current.GetHashCode()] + func(current, neighbor);
                        if (!gScore.ContainsKey(neighbor.GetHashCode()))
                        {
                            cameFrom[neighbor]             = current;
                            gScore[neighbor.GetHashCode()] = tentativeGScore;
                            fScore[neighbor.GetHashCode()] = tentativeGScore + neighbor.dist(end);

                            openSet.Enqueue(neighbor, fScore[neighbor.GetHashCode()]);
                        }
                        else if (gScore[neighbor.GetHashCode()] > tentativeGScore)
                        {
                            cameFrom[neighbor]             = current;
                            gScore[neighbor.GetHashCode()] = tentativeGScore;
                            fScore[neighbor.GetHashCode()] = tentativeGScore + neighbor.dist(end);

                            openSet.UpdatePriority(neighbor, fScore[neighbor.GetHashCode()]);
                        }
                    }
                }
            }

            return(optimalPath);
        }
Exemple #6
0
        public List <Field> FindPath(Field start, Field end)
        {
            HeapPriorityQueue <Field> openList = new HeapPriorityQueue <Field>((gameBoard.SizeX + 1) * (gameBoard.SizeY + 1));

            ResetAGwiazdka();
            start.G        = 0;
            start.H        = 0;
            start.Priority = 0;
            openList.Enqueue(start, 0);
            start.Opened = true;
            while (openList.Count != 0)
            {
                var unit = openList.Dequeue();
                unit.Closed = true;
                if (unit == end)
                {
                    var list = new List <Field>();
                    var node = unit;
                    list.Add(node);
                    while (node.Parent != null)
                    {
                        node = node.Parent;
                        list.Add(node);
                    }
                    list.RemoveAt(list.Count - 1);
                    return(list);
                }
                var positions = gameBoard.GetAdjacentPositionsForAStar(unit).ToList();
                foreach (var position in positions)
                {
                    if (!position.Closed)
                    {
                        var distance = unit.G + 1;
                        if (!position.Opened || distance < position.G)
                        {
                            position.G        = distance;
                            position.H        = DistanceFields(position, end);
                            position.Priority = position.G + position.H;
                            position.Parent   = unit;
                            if (!position.Opened)
                            {
                                openList.Enqueue(position, position.Priority);
                                position.Opened = true;
                            }
                            else
                            {
                                openList.UpdatePriority(position, position.Priority);
                            }
                        }
                    }
                }
            }
            return(null);
        }
Exemple #7
0
        public List <Coordinate> GetShortestPath(Coordinate start, Coordinate goal)
        {
            HashSet <Coordinate> visited = new HashSet <Coordinate>();
            Dictionary <Coordinate, Coordinate> parents     = new Dictionary <Coordinate, Coordinate>();
            Dictionary <Coordinate, double>     gScore      = new Dictionary <Coordinate, double>();
            HeapPriorityQueue <Coordinate>      fScoreQueue = new HeapPriorityQueue <Coordinate>(rows * cols);

            parents[start] = start;
            gScore.Add(start, 0);
            fScoreQueue.Enqueue(start, gScore[start] + Heuristic(start, goal));
            while (fScoreQueue.Count() != 0)
            {
                Coordinate current = fScoreQueue.Dequeue();
                Console.Out.WriteLine("");
                Console.Out.WriteLine("Current = " + current.ToString());
                Console.Out.WriteLine("Visited = " + visited.ToString());
                Console.Out.WriteLine("Parents = " + parents.ToString());
                Console.Out.WriteLine("gScore = " + gScore.ToString());
                Console.Out.WriteLine("fScoreQueue = " + fScoreQueue.ToString());
                if (current == goal)
                {
                    return(ReconstructPath(parents, goal));
                }

                visited.Add(start);
                foreach (Coordinate neighbor in board[current.row, current.col].GetNeighborCoordinates())
                {
                    if (visited.Contains(neighbor))
                    {
                        continue;
                    }
                    double newGScore = gScore[current] + Distance(current, neighbor);
                    if (!fScoreQueue.Contains(neighbor))
                    {
                        parents[neighbor] = current;
                        gScore[neighbor]  = newGScore;
                        fScoreQueue.Enqueue(neighbor, newGScore + Heuristic(neighbor, goal));
                    }
                    else if (newGScore < gScore[neighbor])
                    {
                        parents[neighbor] = current;
                        gScore[neighbor]  = newGScore;
                        fScoreQueue.UpdatePriority(neighbor, newGScore + Heuristic(neighbor, goal));
                    }
                }
            }

            return(null);
        }
        public static List<Coordinate> GetShortestPath(Board board, Coordinate start, Coordinate goal)
        {
            HashSet<Coordinate> visited = new HashSet<Coordinate>();
            Dictionary<Coordinate, Coordinate> parents = new Dictionary<Coordinate, Coordinate>();
            Dictionary<Coordinate, double> gScore = new Dictionary<Coordinate, double>();
            HeapPriorityQueue<Coordinate> fScoreQueue = new HeapPriorityQueue<Coordinate>(board.MaxSize());
            parents[start] = start;
            gScore.Add(start, 0);
            fScoreQueue.Enqueue(start, gScore[start] + Heuristic(start, goal));
            while (fScoreQueue.Count() != 0)
            {
                Coordinate current = fScoreQueue.Dequeue();
                //Console.WriteLine("Current = " + current.ToString());
                if (current.Equals(goal))
                {
                    Console.WriteLine("FOUND GOAL!!!");
                    return ReconstructPath(parents, goal);
                }

                visited.Add(current);
                List<Coordinate> neighbors = board.GetNeighbors(current);
                foreach (Coordinate neighbor in neighbors)
                {
                    if (visited.Contains(neighbor)) continue;
                    if (!board.GetSquare(neighbor).IsTraversable()) continue;
                    double newGScore = gScore[current] + Distance(current, neighbor);
                    if (!fScoreQueue.Contains(neighbor))
                    {
                        parents[neighbor] = current;
                        gScore[neighbor] = newGScore;
                        fScoreQueue.Enqueue(neighbor, newGScore + Heuristic(neighbor, goal));
                    }
                    else if (newGScore < gScore[neighbor])
                    {
                        parents[neighbor] = current;
                        gScore[neighbor] = newGScore;
                        fScoreQueue.UpdatePriority(neighbor, newGScore + Heuristic(neighbor, goal));
                    }

                }
            }

            return null;
        }
        static void Main(string[] args)
        {
            //First, we create the priority queue.  We'll specify a max of 10 users in the queue
            HeapPriorityQueue<User> priorityQueue = new HeapPriorityQueue<User>(MAX_USERS_IN_QUEUE);

            //Next, we'll create 5 users to enqueue
            User user1 = new User("1 - Jason");
            User user2 = new User("2 - Tyler");
            User user3 = new User("3 - Valerie");
            User user4 = new User("4 - Joseph");
            User user42 = new User("4 - Ryan");

            //Now, let's add them all to the queue (in some arbitrary order)!
            priorityQueue.Enqueue(user4, 4);
            priorityQueue.Enqueue(user2, 0); //Note: Priority = 0 right now!
            priorityQueue.Enqueue(user1, 1);
            priorityQueue.Enqueue(user42, 4);
            priorityQueue.Enqueue(user3, 3);

            //Change user2's priority to 2.  Since user2 is already in the priority queue, we call UpdatePriority() to do this
            priorityQueue.UpdatePriority(user2, 2);

            //Finally, we'll dequeue all the users and print out their names
            while(priorityQueue.Count != 0)
            {
                User nextUser = priorityQueue.Dequeue();
                Console.WriteLine(nextUser.Name);
            }
            Console.ReadKey();

            //Output:
            //1 - Jason
            //2 - Tyler
            //3 - Valerie
            //4 - Joseph
            //4 - Ryan

            //Notice that when two users with the same priority were enqueued, they were dequeued in the same order that they were enqueued.
        }
        static void Main(string[] args)
        {
            //First, we create the priority queue.  We'll specify a max of 10 users in the queue
            HeapPriorityQueue <User> priorityQueue = new HeapPriorityQueue <User>(MAX_USERS_IN_QUEUE);

            //Next, we'll create 5 users to enqueue
            User user1  = new User("1 - Jason");
            User user2  = new User("2 - Tyler");
            User user3  = new User("3 - Valerie");
            User user4  = new User("4 - Joseph");
            User user42 = new User("4 - Ryan");

            //Now, let's add them all to the queue (in some arbitrary order)!
            priorityQueue.Enqueue(user4, 4);
            priorityQueue.Enqueue(user2, 0); //Note: Priority = 0 right now!
            priorityQueue.Enqueue(user1, 1);
            priorityQueue.Enqueue(user42, 4);
            priorityQueue.Enqueue(user3, 3);

            //Change user2's priority to 2.  Since user2 is already in the priority queue, we call UpdatePriority() to do this
            priorityQueue.UpdatePriority(user2, 2);

            //Finally, we'll dequeue all the users and print out their names
            while (priorityQueue.Count != 0)
            {
                User nextUser = priorityQueue.Dequeue();
                Console.WriteLine(nextUser.Name);
            }
            Console.ReadKey();

            //Output:
            //1 - Jason
            //2 - Tyler
            //3 - Valerie
            //4 - Joseph
            //4 - Ryan

            //Notice that when two users with the same priority were enqueued, they were dequeued in the same order that they were enqueued.
        }
Exemple #11
0
    // tile based path
    private static List <Vector2> astar(Vector2 t1, HashSet <Vector2> t2Set)
    {
        // TODO: reverse this to start at t2 and go toward t1 so that inland points fail faster
        // TODO: find nearest water tiles to t2 if t2 is inland

        int MAX_OPEN = 1000;
        HeapPriorityQueue <PathNode>   open  = new HeapPriorityQueue <PathNode>(MAX_OPEN);
        Dictionary <Vector2, PathNode> nodes = new Dictionary <Vector2, PathNode>();
        HashSet <Vector2> closed             = new HashSet <Vector2>();

        PathNode node = getNode(nodes, t1, t2Set);

        node.g = 0;
        open.Enqueue(node, node.f);
        Vector2 destTile  = new Vector2();
        bool    foundDest = false;

        while (open.Count > 0)
        {
            node = open.Dequeue();
            closed.Add(node.tile);
            if (t2Set.Contains(node.tile))
            {
                destTile  = node.tile;
                foundDest = true;
                break;
            }
            foreach (Vector2 ntile in map.getNeighbours4(node.tile))
            {
                if (!map.isWalkable(map.getTile(ntile)) || closed.Contains(ntile))
                {
                    continue;
                }
                PathNode othernode = getNode(nodes, ntile, t2Set);
                int      newg      = (ntile.x == node.tile.x || ntile.y == node.tile.y) ? node.g + 10 : node.g + 14;
                if (othernode.seenBefore)
                {
                    if (newg < othernode.g)
                    {
                        othernode.g      = newg;
                        othernode.parent = node;
                        open.UpdatePriority(othernode, othernode.f);
                    }
                }
                else
                {
                    othernode.g      = newg;
                    othernode.parent = node;
                    open.Enqueue(othernode, othernode.f);
                }
            }
        }

        List <Vector2> points = new List <Vector2>();

        if (!foundDest || t2Set.Contains(t1))   // fix for path to current tile when current tile is a wall
        // no path found
        {
            points.Add(t1);
        }
        else if (foundDest)
        {
            // it should have stopped after exactly one item in t2set was reached
            PathNode prevN = nodes[destTile];
            while (prevN.parent != null)
            {
                points.Add(prevN.tile);
                prevN = prevN.parent;
            }
            points.Reverse();
        }
        return(points);
    }
        public void HeapPriorityQueueUpdatePriorityLowestTest()
        {
            HeapPriorityQueue<int> queue = new HeapPriorityQueue<int> (10);

            queue.Enqueue (5, 2);
            queue.Enqueue (6, 3);
            queue.Enqueue (7, 4);
            queue.Enqueue (8, 5);
            queue.Enqueue (9, 6);
            queue.Enqueue (10, 7);

            queue.UpdatePriority(5, 0);
            queue.UpdatePriority(6, 1);

            int first = queue.Dequeue ();
            int second = queue.Dequeue ();
            int third = queue.Dequeue();

            Assert.AreEqual (5, first);
            Assert.AreEqual (6, second);
            Assert.AreEqual (7, third);

            Assert.AreEqual(3, queue.Count);
        }
    // Get rid of all of the news, since they are creating garbage. Reuse the objects.
    public static List<Node> calculatePath(Int2 start, Int2 end)
    {
        Node startNode = new Node(null, start, calculatePointIndex(start));
        Node targetNode = new Node(null, end, calculatePointIndex(end));

        Node[] visited = new Node[world.GetLength(0) * world.GetLength(1)];

        HeapPriorityQueue<Node> frontier = new HeapPriorityQueue<Node>(100);
        List<Node> result = new List<Node>();
        frontier.Enqueue(startNode, 0); // dummy value for priority since it will be popped immediately.

        // Continue algorithm until there are no more open nodes.
        while (frontier.Count > 0)
        {
            Node current = frontier.Dequeue();

            // If the popped node is the target node, then you are done.
            if (current.index == targetNode.index)
            {
                result.Clear();
                result.Add(current);

                Node nodeInShortestPath = current.parent;

                while (nodeInShortestPath != null)
                {
                    result.Add(nodeInShortestPath);
                    nodeInShortestPath = nodeInShortestPath.parent;
                }

                result.Reverse();
            }
            else
            {
                List<Int2> neighbors = findNeighbors(current.point);

                foreach (Int2 neighbor in neighbors) { // foreach has a bug that creates garbage via wrappers
                    int pointIndex = calculatePointIndex(neighbor);

                    Node neighborNode = visited[pointIndex] != null ?
                        visited[pointIndex] : new Node(current, neighbor, pointIndex);
                    int newNeighborCost = current.g + manhattanDistance(neighbor, current.point);

                    if (visited[neighborNode.index] == null || neighborNode.g > newNeighborCost)
                    {
                        neighborNode.g = newNeighborCost;
                        neighborNode.f = neighborNode.g + manhattanDistance(neighbor, targetNode.point);
                        neighborNode.parent = current;

                        if (!frontier.Contains(neighborNode))
                        {
                            frontier.Enqueue(neighborNode, neighborNode.f);
                        }
                        else
                        {
                            frontier.UpdatePriority(neighborNode, neighborNode.f);
                        }

                        visited[neighborNode.index] = neighborNode;
                    }
                }
            }
        }

        // If frontier is emptied out and the target hasn't been reached, then the path is blocked and no shortest path exists.
        return result;
    }
        public void HeapPriorityQueueUpdatePriorityTest()
        {
            HeapPriorityQueue<int> queue = new HeapPriorityQueue<int> (10);

            queue.Enqueue (5, 1);
            queue.Enqueue (6, 3);
            queue.Enqueue (7, 5);
            queue.Enqueue (8, 6);
            queue.Enqueue (9, 7);
            queue.Enqueue (10, 2);

            queue.UpdatePriority(5, 10);
            queue.UpdatePriority(6, 11);

            int first = queue.Dequeue ();
            int second = queue.Dequeue ();

            Assert.AreEqual (10, first);
            Assert.AreEqual (7, second);

            Assert.AreEqual(4, queue.Count);
        }
        private Node Dijstra(by source, by target, Politik politik, pakke sendtPakke, float multiplier)
        {
            var queue = new HeapPriorityQueue<Node>(_byliste.Count * 2);
            _nodes = new List<Node>();
            Node targetBy = null;
            foreach (var by in _byliste)
            {
                var node = new Node
                {
                    By = by
                };

                if (by.CityId == target.CityId)
                {
                    targetBy = node;
                }

                node.Distance = by.CityId == source.CityId ? 0 : double.MaxValue;
                _nodes.Add(node);
                queue.Enqueue(node, node.Distance);
            }

            while (queue.Any())
            {
                var node = queue.Dequeue();

                if (node == targetBy && node.Distance != double.MaxValue)
                    return node;

                GetRoutes(node, politik, sendtPakke, multiplier);

                foreach (var neighbour in getNeighbourghNodes(node, queue))
                {
                    if (neighbour == null || !queue.Contains(neighbour))
                        continue;

                    var dist = node.Distance + DistanceBetween(node, neighbour, politik);
                    if (dist < neighbour.Distance)
                    {
                        neighbour.Distance = dist;
                        neighbour.Previous = node;
                        queue.UpdatePriority(neighbour, dist);
                    }
                }
            }
            return null;
        }
Exemple #16
0
    void SetVals(HeapPriorityQueue<MapNode> openQ, int x, int y, int g, int g_inc, int count, coord prev, int end_x, int end_y)
    {
        if(!m_Map[x,y].closed && m_Map[x,y].g > g+g_inc)
        {
            m_Map[x,y].g = g+g_inc;
            m_Map[x,y].h = Heuristic(x, y, end_x, end_y);
            m_Map[x,y].f = m_Map[x,y].g + m_Map[x,y].h;
            m_Map[x,y].count = count+1;
            m_Map[x,y].previous = prev;

            /*if(Heuristic(prev.x, prev.y, x, y) > 1)
            {
                Debug.Log("Err: H: " + Heuristic(prev.x, prev.y, x, y).ToString() + ": prev (" + prev.x.ToString() +", " + prev.y.ToString() + ") to current (" + x.ToString() + ", " + y.ToString() + ")");
            }*/

            if(openQ.Contains(m_Map[x,y]))
            {
                openQ.UpdatePriority(m_Map[x,y], m_Map[x,y].f);
            }
            else
            {
                openQ.Enqueue(m_Map[x,y], m_Map[x,y].f);
            }
        }
    }
Exemple #17
0
        public List<Coordinate> GetShortestPath(Coordinate start, Coordinate goal)
        {
            HashSet<Coordinate> visited = new HashSet<Coordinate>();
            Dictionary<Coordinate, Coordinate> parents = new Dictionary<Coordinate, Coordinate>();
            Dictionary<Coordinate, double> gScore = new Dictionary<Coordinate, double>();
            HeapPriorityQueue<Coordinate> fScoreQueue = new HeapPriorityQueue<Coordinate>(rows * cols);
            parents[start] = start;
            gScore.Add(start, 0);
            fScoreQueue.Enqueue(start, gScore[start] + Heuristic(start, goal));
            while (fScoreQueue.Count() != 0)
            {
                Coordinate current = fScoreQueue.Dequeue();
                Console.Out.WriteLine("");
                Console.Out.WriteLine("Current = " + current.ToString());
                Console.Out.WriteLine("Visited = " + visited.ToString());
                Console.Out.WriteLine("Parents = " + parents.ToString());
                Console.Out.WriteLine("gScore = " + gScore.ToString());
                Console.Out.WriteLine("fScoreQueue = " + fScoreQueue.ToString());
                if (current == goal)
                {
                    return ReconstructPath(parents, goal);
                }

                visited.Add(start);
                foreach (Coordinate neighbor in board[current.row,current.col].GetNeighborCoordinates())
                {
                    if (visited.Contains(neighbor)) continue;
                    double newGScore = gScore[current] + Distance(current, neighbor);
                    if (!fScoreQueue.Contains(neighbor))
                    {
                        parents[neighbor] = current;
                        gScore[neighbor] = newGScore;
                        fScoreQueue.Enqueue(neighbor, newGScore + Heuristic(neighbor, goal));
                    }
                    else if (newGScore < gScore[neighbor])
                    {
                        parents[neighbor] = current;
                        gScore[neighbor] = newGScore;
                        fScoreQueue.UpdatePriority(neighbor, newGScore + Heuristic(neighbor, goal));
                    }

                }
            }

            return null;
        }
Exemple #18
0
        /// <summary>
        /// Runs the Dijkstra algorithm which calculates the shortest paths from the source to any other node
        /// which is reachable from there.
        ///
        /// If this method is called multiple times with the same source it does only calculate the paths the first time
        ///
        /// Exceptions:
        /// ArgumentException if the nodes Enumerable is null, the source is null or the source is not part of the graph (the nodes)
        /// </summary>
        public void Run(IEnumerable <AdjacencyNode <T> > nodes, AdjacencyNode <T> source)
        {
            if (nodes == null || source == null)
            {
                throw new ArgumentException("Nodes Enumerable or Source is null");
            }

            if (Source != null && Source.Equals(source))
            {
                return;
            }

            /**
             * Initialize the Algorithm
             */
            Source = source;

            // Holds the shortest distance between the source and the node
            Dictionary <AdjacencyNode <T>, int> distance = new Dictionary <AdjacencyNode <T>, int>();

            // Holds the node from which we need to go to the current node if we are taking the shortest path
            PreviousNode = new Dictionary <AdjacencyNode <T>, AdjacencyNode <T> >();
            // Fast Access to the Node (of the Nodes to inspect) which has the shortest distance and thus needs to be processed next
            // if we processed all nodes in that queue or the remaining ones are not reachable the algorithm is finished
            HeapPriorityQueue <AdjacencyNode <T> > distanceQueue = new HeapPriorityQueue <AdjacencyNode <T> >();

            foreach (AdjacencyNode <T> n in nodes)
            {
                // previous nodes are unknown at the start
                PreviousNode.Add(n, null);
                // distance is assumed to be the maximum possible value. Therefore it can be improved if we find a shorter one
                distance.Add(n, int.MaxValue);
                distanceQueue.Enqueue(n, int.MaxValue);
            }

            if (!distanceQueue.Contains(source))
            {
                throw new ArgumentException("The source is not part of the graph (nodes)");
            }

            /**
             * Execute the Algorithm
             */
            distance[Source] = 0;
            distanceQueue.UpdatePriority(Source, 0);

            while (!distanceQueue.IsEmpty())
            {
                // The nearest node is a node which has never been reached (otherwise its path would have been improved)
                // This means all other nodes can also not be reached and our algorithm is finished...
                if (distanceQueue.PeekPriority() == int.MaxValue)
                {
                    break;
                }

                AdjacencyNode <T> nearestNode = distanceQueue.Dequeue();

                // Check all neighbours that still need to be inspected
                foreach (AdjacencyNode <T> neighbour in nearestNode.AdjacentNodes)
                {
                    if (!distanceQueue.Contains(neighbour))
                    {
                        continue;
                    }

                    // calculate distance with the currently inspected neighbour
                    int neighbourDist = distance[nearestNode] + 1;

                    // set the neighbour as shortest if it is better than the currently known shortest distance
                    if (neighbourDist < distance[neighbour])
                    {
                        distance[neighbour] = neighbourDist;
                        distanceQueue.UpdatePriority(neighbour, neighbourDist);
                        PreviousNode[neighbour] = nearestNode;
                    }
                }
            }
        }