跳转点搜索在连续失败

时间:2016-02-09 05:32:33

标签: c# a-star

如果在迭代之间保存节点成本启发式算法,则算法将在第一次迭代后中断。如果更改了起点和目标,则无法找到新路径。只有通过清算成本才能找到新的途径。这是正常的吗?

添加了代码。优先级队列尚未实现。它适用于从Unity 3D中的XYZ空间转换的网格。

 if (newMovementCostToNeighbor < jumpPoint.gCost || jumpPoint.fCost <= 0)
        {
            jumpPoint.gCost = newMovementCostToNeighbor;
            jumpPoint.hCost = getDistance(jumpPoint, targetNode);
            jumpPoint.parent = currentNode;
            successors.Add(jumpPoint);
        }

识别IDSuccessors中的问题,检查路径成本是否为&lt;保存的gcost或者从未访问过jumpPoint(如果它的fCost&lt; = 0)。由于检查主要取决于jumpPoint小于保存的gCost的路径成本,因此路径查找在运行一次后会中断。

if (newMovementCostToNeighbor < jumpPoint.gCost || (!openSet.Contains(jumpPoint) && !closedSet.Contains(jumpPoint)) || jumpPoint.fCost <= 0)
            {
                jumpPoint.gCost = newMovementCostToNeighbor;
                jumpPoint.hCost = getDistance(jumpPoint, targetNode);
                jumpPoint.parent = currentNode;
                successors.Add(jumpPoint);
            }

找到解决方案。补充支票。我们的想法是检查runPoint在运行期间是否从未见过,所以一种方法是检查openSet或closedSet中是否缺少它。

    void FindPath(Vector3 startPos, Vector3 targetPos)
{

    Node startNode = grid.NodeFromWorldPoint(startPos);
    Node targetNode = grid.NodeFromWorldPoint(targetPos);

    List<Node> openSet = new List<Node>();
    HashSet<Node> closedSet = new HashSet<Node>();
    openSet.Add(startNode);

    while(openSet.Count > 0)
    {
        Node currentNode = openSet[0];
        for(int i = 1; i < openSet.Count; i++)
        {
            if(openSet[i].fCost < currentNode.fCost || (openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost))
            {
                currentNode = openSet[i];
            }
        }

        openSet.Remove(currentNode);
        closedSet.Add(currentNode);

        if(currentNode == targetNode)
        {
            RetracePath(startNode, targetNode);
            return;
        }

        List<Node> successors = IDSuccessors(currentNode, startNode, targetNode);

        foreach(Node n in successors)
        {
            if(n != null)
            {

                openSet.Add(n);
            }
        }
    }

}

public List<Node> IDSuccessors(Node currentNode, Node startNode, Node targetNode)
{
    List<Node> successors = new List<Node>();
    List<Node> neighbors = grid.getNeighbors(currentNode);

    foreach (Node neighbor in neighbors)
    {
            int dx = Mathf.Clamp(neighbor.gridX - currentNode.gridX, -1, 1);
            int dy = Mathf.Clamp(neighbor.gridY - currentNode.gridY, -1, 1);

            Node jumpPoint = Jump(currentNode.gridX, currentNode.gridY, dx, dy, startNode, targetNode);

        if (jumpPoint != null)
        {

            int newMovementCostToNeighbor = currentNode.gCost + getDistance(currentNode, jumpPoint);
            if (newMovementCostToNeighbor < jumpPoint.gCost || jumpPoint.fCost <= 0)
            {
                jumpPoint.gCost = newMovementCostToNeighbor;
                jumpPoint.hCost = getDistance(jumpPoint, targetNode);
                jumpPoint.parent = currentNode;
                successors.Add(jumpPoint);
            }
        }


    }

    return successors;
}

0 个答案:

没有答案