示例#1
0
        /// <summary>
        /// Adds a node to the graph
        /// </summary>
        /// <param name="node">The node to be added</param>
        public void AddNavNode(NavNode node)
        {
            Nodes.Add(node);

            //set the bounds of the grid
            if (node.Indexes.Item1 > maxX)
            {
                maxX = node.Indexes.Item1;
            }

            if (node.Indexes.Item2 > maxY)
            {
                maxY = node.Indexes.Item2;
            }
        }
示例#2
0
        /// <summary>
        /// Uses a modification of Dijkstra Shortest Path Algorithm to find
        /// the farthest path away from the target node, relative to the
        /// "from" node
        /// </summary>
        /// <param name="from">The starting node</param>
        /// <param name="target">The target node to run way from</param>
        /// /// <param name="exclude">Nodes of the types in the list won't be considered</param>
        /// <returns>A list containing the shortest path between the given nodes</returns>
        public List <NavNode> FarthestPath(NavNode from, NavNode target, List <NodeType> exclude = null)
        {
            List <NavNode> result = new List <NavNode>();

            //limits the path size for performance
            const int maxSize          = 10;
            int       greatestDistance = 0;

            //mark all nodes as unvisited
            //set the distance to "- infinity"
            //and clear the path
            foreach (var node in Nodes)
            {
                node.Visited            = false;
                node.Distance           = int.MinValue;
                node.PreviousNodeInPath = null;
            }

            //set the from node distance to 0
            from.Distance = 0;

            //the current node, set it to "from"
            NavNode currentNode = from;

            //number of nodes yet to be visited - target
            int nodesToBeVisited = Nodes.Count - 1;

            //iterate trhough the nodes until the
            //"to" node is visited
            while (nodesToBeVisited > 0 || greatestDistance < maxSize)
            {
                //mark current node as visited
                //and remove a node to be visited
                currentNode.Visited = true;

                nodesToBeVisited--;

                //calc the distance to the neighbors
                foreach (var neighbor in currentNode.Neighbors)
                {
                    //if the neighbor is already visited, ignore it
                    if (neighbor == null || neighbor.Visited)
                    {
                        continue;
                    }

                    //ignore target
                    if (neighbor == target)
                    {
                        continue;
                    }

                    //ignore neighbor if it matches any exluded type
                    if (exclude != null && exclude.Contains(neighbor.NodeType))
                    {
                        continue;
                    }

                    //cumulative distance from the starting node
                    int distance = currentNode.Distance + 1;
                    if (distance > neighbor.Distance)
                    {
                        neighbor.Distance           = distance;
                        neighbor.PreviousNodeInPath = currentNode;
                        if (distance > greatestDistance)
                        {
                            greatestDistance = distance;
                        }
                    }
                }

                //change the current node to the non-visited
                //node with the greatest distance
                currentNode = Nodes.Where(n => !n.Visited && n != target).OrderByDescending(n => n.Distance).FirstOrDefault();
            }

            //fill the result starting from the node with greatest distance
            currentNode = Nodes.Where(n => n != target).OrderByDescending(n => n.Distance).FirstOrDefault();
            while (greatestDistance > 0)
            {
                greatestDistance--;
                result.Add(currentNode.PreviousNodeInPath);
                currentNode = currentNode.PreviousNodeInPath;
            }

            result.Reverse();
            return(result.ToList());
        }
示例#3
0
        /// <summary>
        /// Uses Dijkstra Shortest Path Algorithm to find the shortest path
        /// between the given nodes, using adjacency matrix representation
        /// and fixing the distance between neighbor nodes as 1
        /// </summary>
        /// <param name="from">The starting node</param>
        /// <param name="to">The target node</param>
        /// /// <param name="exclude">Nodes of the types in the list won't be considered</param>
        /// <returns>A list containing the shortest path between the given nodes</returns>
        public List <NavNode> ShortestPath(NavNode from, NavNode to, List <NodeType> exclude = null)
        {
            List <NavNode> result = new List <NavNode>();

            //mark all nodes as unvisited
            //set the distance to "infinity"
            //and clear the path
            foreach (var node in Nodes)
            {
                node.Visited            = false;
                node.Distance           = int.MaxValue;
                node.PreviousNodeInPath = null;
            }

            //set the from node distance to 0
            from.Distance = 0;

            //the current node, set it to "from"
            NavNode currentNode = from;

            //iterate trhough the nodes until the
            //"to" node is visited
            while (!to.Visited)
            {
                //mark current node as visited
                //and remove a node to be visited
                currentNode.Visited = true;

                //calc the distance to the neighbors
                foreach (var neighbor in currentNode.Neighbors)
                {
                    //if the neighbor is already visited, ignore it
                    if (neighbor == null || neighbor.Visited)
                    {
                        continue;
                    }

                    //ignore neighbor if it matches any exluded type
                    if (exclude != null && exclude.Contains(neighbor.NodeType))
                    {
                        continue;
                    }

                    //cumulative distance from the starting node
                    int distance = currentNode.Distance + 1;
                    if (distance < neighbor.Distance)
                    {
                        neighbor.Distance           = distance;
                        neighbor.PreviousNodeInPath = currentNode;
                    }
                }

                //change the current node to the non-visited
                //node with the shortest distance
                currentNode = Nodes.Where(n => !n.Visited).OrderBy(n => n.Distance).FirstOrDefault();
            }

            //fill the result
            result.Add(to);
            currentNode = to;
            while (currentNode != from)
            {
                result.Add(currentNode.PreviousNodeInPath);
                currentNode = currentNode.PreviousNodeInPath;
            }

            result.Reverse();
            return(result.ToList());
        }