A *路径查找在某些情况下会永远运行

时间:2018-08-09 15:46:59

标签: java a-star

我已经使用此伪代码在Java中编写了A *寻路算法。在某些情况下,它可以正常工作,但在某些情况下,它可以永久挂起,并在打开的列表中添加了无数个节点。这是我的伪代码执行还是伪代码本身存在问题?我已经尝试了一些打印语句进行调试,但是即使解决问题也遇到了麻烦。这是我的A *代码:

import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;

public class AStar {

    Point[] adjacents = {new Point(0,1),new Point(1,1), new Point(1,0), new Point(1,-1), new Point(0,-1), new Point(-1,-1), new Point(-1,0), new Point(-1,1)};

    public Node[] calculatePH(Node startNode, Node endNode, int[][] map) {
        // Initialize both open and closed list
        ArrayList<Node> open = new ArrayList<Node>();
        ArrayList<Node> closed = new ArrayList<Node>();
        // Add the start node
        open.add(startNode);
        // Loop until you find the end
        while(!open.isEmpty()) {
            // Get the current node
            Node currentNode = open.get(0);
            for(Node n : open) {
                if(n.f<currentNode.f) {
                    currentNode = n;
                }
            }

            open.remove(currentNode);
            closed.add(currentNode);

            // Found the goal
            if(currentNode.equals(endNode)) {
                ArrayList<Node> path = new ArrayList<Node>();
                Node current = currentNode;
                while(current!=null) {
                    path.add(current);
                    current = current.parent;
                }
                Collections.reverse(path);
                return path.toArray(new Node[path.size()]);
            }

            // Generate children

            ArrayList<Node> children = new ArrayList<Node>();
            for(Point p : adjacents) {
                Point childpos = currentNode.getLocation();
                childpos.translate(p.x, p.y);

                //Checks to ensure that the node is on the actual field, so we don't ram into a field tech lol
                if((childpos.y>(map.length-1)) || (childpos.y<0) || (childpos.x>(map[0].length-1)) || (childpos.x<0)) {
                    continue;
                }

                //Checks to ensure that the node is "walkable", or basically just not inside a wall or object.
                if(map[childpos.y][childpos.x] != 0) {
                    continue;
                }

                Node child = new Node(currentNode,childpos);
                children.add(child);
            }

            for(Node n : children) {
                // Child is on the closedList
                if(closed.indexOf(n)>-1) {
                    continue;
                }

                n.g = currentNode.g + currentNode.distance(n);
                n.h = n.distance(endNode);
                n.f = n.g+n.h;
                boolean inFlag = false;
                for(Node m : open) {
                    if((n==m) && (n.g>m.g)) {
                        inFlag = true;
                    }
                }

                if(!inFlag) {
                    open.add(n);
                }
            }
        }

        return new Node[0];
    }
}

还有Node类,它是java.awt.Point的子类,带有一些额外的东西。

import java.awt.Point;
import java.util.ArrayList;

public class Node extends Point { //Extends Point for conveinince and 
    //neatness. Maybe just use a has-a relationship if this breaks.

    public Node(Node Parent, Point loc) {
        super(loc);
        this.parent = Parent;
    }

    public Node(Point loc) {
        super(loc);

    }

    void translate(Point p){
        translate(p.x,p.y);
    }

    public Node parent;

    public double f;
    public double g;
    public double h;

    public String toString() {

        return "("+x+","+y+")";
    }
}

我正在使用一个高27宽54的迷宫,起点为(0,0),目标为(24,24),目前有两个障碍。在这种情况下,它可以正常工作:

enter image description here

但是在这种情况下,它会永远挂起。唯一的不同是第二个障碍物进一步向下延伸1行。

enter image description here

我们将不胜感激任何帮助,请告诉我是否应该更改问题或添加更多信息。

编辑:它并不漂亮,但是这里是int [] [],其中包含无法正常运行版本的地图数据。

int[][] map ={
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 
        {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
       };

1 个答案:

答案 0 :(得分:1)

只需弄清楚这一点,这要感谢bracco23将我指向正确的代码部分。原来我犯了一个菜鸟java错误,并使用==而不是.equals进行了比较。将其交换出去可以解决问题。