Exemple #1
0
        /// <summary>
        /// This runs A* assuming that both start and nextDestination
        /// clusters are clusters belonging to the lowest level of the HPA* abstraction.
        /// </summary>
        /// <param name="start"></param>
        /// <param name="nextDestination"></param>
        /// <returns></returns>
        private List <int> AstarHPALowestLevelSearch(ClusterNode start, ClusterNode nextDestination, int startPosition)
        {
            Cluster startC = clusterOfClusterNode(start);
            Cluster nextC  = clusterOfClusterNode(nextDestination);

            HashSet <int> nodesToSearch = new HashSet <int>();

            foreach (int id in startC.InnerNodes)
            {
                if (gMap.Nodes[id].IsTraversable())
                {
                    nodesToSearch.Add(id);
                }
            }
            foreach (int id in nextC.InnerNodes)
            {
                if (gMap.Nodes[id].IsTraversable())
                {
                    nodesToSearch.Add(id);
                }
            }
            List <int> sol = new List <int>();

            Dictionary <int, bool> closedSet = new Dictionary <int, bool>();

            foreach (int id in nodesToSearch)
            {
                closedSet.Add(id, false);
            }
            Dictionary <int, Node> openSet = new Dictionary <int, Node>();

            //starting node is in the open set
            openSet.Add(startPosition, gMap.Nodes[startPosition]);

            // For each clusternode, which clusternode it can most efficiently be reached from.
            // If a cnode can be reached from many cnodes, cameFrom will eventually contain the
            // most efficient previous step.
            Dictionary <int, int> cameFrom = new Dictionary <int, int>();

            // For each node, the cost of getting from the start node to that node.
            Dictionary <int, float> gScore = new Dictionary <int, float>();

            //default values are infinity
            foreach (int nodeID in nodesToSearch)
            {
                gScore.Add(nodeID, float.MaxValue);
            }
            // The cost of going from start to start is zero.
            gScore[start.GNodeID] = 0;

            // For each node, the total cost of getting from the start node to the goal
            // by passing by that node. That value is partly known, partly heuristic.
            Dictionary <int, float> fScore = new Dictionary <int, float>();

            //default values are infinity
            foreach (int nodeID in nodesToSearch)
            {
                fScore.Add(nodeID, float.MaxValue);
            }

            // For the first node, that value is completely heuristic.
            fScore[startPosition] = H_lowHPA(startPosition, nextDestination);

            int currNode = 0; //default value

            while (openSet.Count != 0)
            {
                //the node in openSet having the lowest fScore value
                currNode = openSet.OrderBy(i => fScore[i.Key]).FirstOrDefault().Key;
                if (currNode == nextDestination.GNodeID)
                {
                    //break the loop and reconstruct path below
                    break;
                }

                openSet.Remove(currNode);
                closedSet[currNode] = true; //"added" to closedList

                foreach (var neighbor in gMap.Nodes[currNode].Neighbors)
                {
                    // Ignore the neighbor which is already evaluated or a neighbor
                    //that doesn't belong to neither start nor nextDestination cluster.
                    if ((!startC.InnerNodes.Contains(neighbor.Key) && !nextC.InnerNodes.Contains(neighbor.Key)) ||
                        (!closedSet.ContainsKey(neighbor.Key) || closedSet[neighbor.Key] == true))
                    {
                        continue;
                    }

                    // The distance from start to a neighbor
                    float tentativeG = gScore[currNode] + neighbor.Value;
                    if (!openSet.ContainsKey(neighbor.Key)) // Discover a new node
                    {
                        searchedNodes.Add(neighbor.Key);
                        expandedNodesCount++;
                        setSearchedBgColor(neighbor.Key);
                        openSet.Add(neighbor.Key, gMap.Nodes[neighbor.Key]);
                    }
                    else if (tentativeG >= gScore[neighbor.Key])
                    {
                        continue; //not a better path
                    }

                    // This path is the best until now. Record it!
                    cameFrom[neighbor.Key] = currNode;
                    gScore[neighbor.Key]   = tentativeG;
                    fScore[neighbor.Key]   = gScore[neighbor.Key] + H_lowHPA(neighbor.Key, nextDestination);
                }
            }

            sol.Add(currNode);
            while (cameFrom.ContainsKey(currNode))
            {
                int child = currNode;
                currNode = cameFrom[currNode];

                pathCost += gMap.Nodes[currNode].Neighbors[child];

                sol.Add(currNode);
            }
            // pathfinder.CancelAsync();

            return(sol);
        }
Exemple #2
0
        private void StartHPAstarSearch(object sender, DoWorkEventArgs e)
        {
            List <int> path     = new List <int>();
            bool       startNew = true;
            bool       endNew   = true;

            //get the start node cluster
            int     startCID        = gMap.Nodes[gMap.StartNodeID].HPAClusterParent;
            int     endCID          = gMap.Nodes[gMap.EndNodeID].HPAClusterParent;
            Cluster startingCluster = HierarchicalGraph[0].Clusters[startCID];
            Cluster endingCluster   = HierarchicalGraph[0].Clusters[endCID];

            //we create the temporary start clusterNode and calculate the distance between
            //it and other cluster nodes
            ClusterNode tmpStart = new ClusterNode(gMap.StartNodeID);

            if (startingCluster.ClusterNodes.ContainsKey(tmpStart.GNodeID))
            {
                startNew = false;
                tmpStart = startingCluster.ClusterNodes[tmpStart.GNodeID];
            }
            else
            {
                startingCluster.ClusterNodes.Add(tmpStart.GNodeID, tmpStart);
                HierarchicalGraph[0].AbstractNodes.Add(tmpStart.GNodeID, tmpStart);
                tmpStart.ClusterParent = startCID;
                calculateDistInnerClusterNodes_Tmp(tmpStart, startingCluster);
            }

            ClusterNode tmpEnd = new ClusterNode(gMap.EndNodeID);

            if (endingCluster.ClusterNodes.ContainsKey(tmpEnd.GNodeID))
            {
                endNew = false;
                tmpEnd = endingCluster.ClusterNodes[tmpEnd.GNodeID];
            }
            else
            {
                endingCluster.ClusterNodes.Add(tmpEnd.GNodeID, tmpEnd);
                HierarchicalGraph[0].AbstractNodes.Add(tmpEnd.GNodeID, tmpEnd);
                tmpEnd.ClusterParent = endCID;
                calculateDistInnerClusterNodes_Tmp(tmpEnd, endingCluster);
            }
            var abstractPath = AstarAbstractHPASearch(tmpStart, endingCluster);

            //goes through the low-level clusters and partially builds a path on the grid base.
            //abstractPath contains the indices of low-level clusters. Therefore,
            //by doing HierarchicalAbstraction[0].ClusterNodes[i] we get the cluster we need
            int startID = gMap.StartNodeID;

            for (int i = abstractPath.Count - 1; i > 0; --i)
            {
                List <int> partialPath = new List <int>();

                partialPath = AstarHPALowestLevelSearch(HierarchicalGraph[0].AbstractNodes[abstractPath[i]],
                                                        HierarchicalGraph[0].AbstractNodes[abstractPath[i - 1]],
                                                        startID);
                AddToPathfSol(partialPath);

                if (i == abstractPath.Count - 1)
                {
                    StartAgent();
                }

                //the next start node is going to be the end node of this search.
                //since A* path returned is reversed, the first element was the last (end) node.
                startID = partialPath[0];
            }
            if (endNew)
            {
                endingCluster.ClusterNodes.Remove(tmpEnd.GNodeID);
                HierarchicalGraph[0].AbstractNodes.Remove(tmpEnd.GNodeID);
            }
            if (startNew)
            {
                startingCluster.ClusterNodes.Remove(tmpStart.GNodeID);
                HierarchicalGraph[0].AbstractNodes.Remove(tmpStart.GNodeID);
            }

            pfStopWatch.Stop();
        }
Exemple #3
0
        private List <int> AstarAbstractHPASearch(ClusterNode start, Cluster end)
        {
            bool       lastCluster = false;
            List <int> sol         = new List <int>();

            Dictionary <int, bool> closedSet = new Dictionary <int, bool>();

            foreach (var c in HierarchicalGraph[0].Clusters)
            {
                foreach (var cn in c.Value.ClusterNodes.Values)
                {
                    closedSet.Add(cn.GNodeID, false);
                }
            }
            Dictionary <int, ClusterNode> openSet = new Dictionary <int, ClusterNode>();

            //starting node is in the open set
            openSet.Add(gMap.StartNodeID, start);

            // For each clusternode, which clusternode it can most efficiently be reached from.
            // If a cnode can be reached from many cnodes, cameFrom will eventually contain the
            // most efficient previous step.
            Dictionary <int, int> cameFrom = new Dictionary <int, int>();

            // For each node, the cost of getting from the start node to that node.
            Dictionary <int, float> gScore = new Dictionary <int, float>();

            //default values are infinity
            foreach (var c in HierarchicalGraph[0].Clusters)
            {
                foreach (var cn in c.Value.ClusterNodes.Values)
                {
                    gScore.Add(cn.GNodeID, float.MaxValue);
                }
            }
            // The cost of going from start to start is zero.
            gScore[start.GNodeID] = 0;

            // For each node, the total cost of getting from the start node to the goal
            // by passing by that node. That value is partly known, partly heuristic.
            Dictionary <int, float> fScore = new Dictionary <int, float>();

            //default values are infinity
            foreach (var c in HierarchicalGraph[0].Clusters)
            {
                foreach (var cn in c.Value.ClusterNodes.Values)
                {
                    fScore.Add(cn.GNodeID, float.MaxValue);
                }
            }

            // For the first node, that value is completely heuristic.
            fScore[start.GNodeID] = H_startEnd(start.GNodeID, gMap.EndNodeID);

            int currNode = 0; //default value

            while (openSet.Count != 0)
            {
                //the node in openSet having the lowest fScore value
                currNode = openSet.OrderBy(i => fScore[i.Key]).FirstOrDefault().Key;
                if (end.InnerNodes.Contains(currNode) && end.ClusterNodes[gMap.EndNodeID].Neighbors.ContainsKey(currNode))
                {
                    //break the loop and reconstruct path below
                    //we reached the end cluster. Break and finish the path to the end node below
                    lastCluster = true;
                    break;
                }

                openSet.Remove(currNode);
                closedSet[currNode] = true; //"added" to closedList

                int         cID = gMap.Nodes[currNode].HPAClusterParent;
                Cluster     c   = HierarchicalGraph[0].Clusters[cID];
                ClusterNode cn  = HierarchicalGraph[0].AbstractNodes[currNode];

                foreach (var neighbor in cn.Neighbors)
                {
                    // Ignore the neighbor which is already evaluated.
                    if (!closedSet.ContainsKey(neighbor.Key) || closedSet[neighbor.Key] == true)
                    {
                        continue;
                    }

                    // The distance from start to a neighbor
                    float tentativeG = gScore[currNode] + neighbor.Value;
                    if (!openSet.ContainsKey(neighbor.Key)) // Discover a new node
                    {
                        Cluster neighC = HierarchicalGraph[0].Clusters[gMap.Nodes[neighbor.Key].HPAClusterParent];
                        openSet.Add(neighbor.Key, HierarchicalGraph[0].AbstractNodes[neighbor.Key]);
                    }
                    else if (tentativeG >= gScore[neighbor.Key])
                    {
                        continue; //not a better path
                    }

                    // This path is the best until now. Record it!
                    cameFrom[neighbor.Key] = currNode;
                    gScore[neighbor.Key]   = tentativeG;
                    fScore[neighbor.Key]   = gScore[neighbor.Key] + H_startEnd(neighbor.Key, gMap.EndNodeID);
                }
            }
            if (lastCluster)
            {
                sol.Add(gMap.EndNodeID);
            }

            sol.Add(currNode);
            while (cameFrom.ContainsKey(currNode))
            {
                currNode = cameFrom[currNode];
                sol.Add(currNode);
            }
            //NOT setting pathcost since this is still an abstraction layer
            //pathCost = gScore[gMap.EndNodeID];
            // pathfinder.CancelAsync();
            //invalidater.CancelAsync();

            return(sol);
        }
Exemple #4
0
 private Cluster clusterOfClusterNode(ClusterNode c)
 {
     return(HierarchicalGraph[0].Clusters[gMap.Nodes[c.GNodeID].HPAClusterParent]);
 }