java - A 星、H 值空指针 (Java)

标签 java nullpointerexception path-finding a-star

我正在研究 A* 寻路算法,由于某种原因,在某个时刻我遇到了空指针异常,但我不知道为什么。问题出现在类 Astar 第 79 行,这是 H 值的简单 setter 。

这是 Astar 类:

import java.util.*;

public class Astar {

private int[][] map;
private int Infinity = Integer.MAX_VALUE;
private GridElement startElement;
private GridElement endElement;
private GridElement[][] grid;
private int currentX;
private int currentY;
private int tmpV;
private int adjacentX;
private int adjacentY;
//private int x;
//private int y;
private GridElement adjacentE;
private GridElement adjacentW;
private GridElement adjacentN;
private GridElement adjacentS;



public Astar(int[][] map, int xStart, int yStart, int xEnd, int yEnd) {
    this.map= map;
    grid = new GridElement[map.length][map[0].length];
    for(int i=0;i<grid.length;i++)
        for(int j=0;j<grid[0].length;j++){

            grid[i][j]=new GridElement(i,j,map[i][j],grid);
            grid[i][j].setG(map[i][j]);}

    this.startElement=grid[xStart][yStart];
    this.endElement=grid[xEnd][yEnd];
}


public void AstarAlgortihm() {
    ArrayList<GridElement> openList = new ArrayList<GridElement>();

    for(int i=0;i<grid.length;i++)
        for(int j=0;j<grid[0].length;j++)
            openList.add(grid[i][j]);

    GridElement current = startElement;
    GridElement next;

    while(openList.isEmpty() == false){

        openList.remove(current);
        current.setVisited(true);
        if(current==endElement)
            break;



            int northF=Infinity;
            int southF=Infinity;
            int westF=Infinity;
            int eastF=Infinity;

        if(current.hasNeighbour(1,0)!=null && grid[current.getX()+1][current.getY()].checkVisited() == false) {
            adjacentS = current.hasNeighbour(1,0);
            grid[current.getX()+1][current.getY()].setParent(current);
            adjacentS.setH(H(current.getX()+1, current.getY()));
            adjacentS.setF();
            southF=adjacentS.getF();}

        if(current.hasNeighbour(-1,0)!=null && grid[current.getX()-1][current.getY()].checkVisited()==false) {
            adjacentN = current.hasNeighbour(-1,0);
            grid[current.getX()-1][current.getY()].setParent(current);
            adjacentN.setH(H(current.getX()-1, current.getY()));
            adjacentN.setF();
            northF=adjacentN.getF();}

        if(current.hasNeighbour(0,1)!=null && grid[current.getX()][current.getY()+1].checkVisited()==false) {
            adjacentE = current.hasNeighbour(1,0);
            grid[current.getX()][current.getY()+1].setParent(current);
            adjacentE.setH(H(current.getX(), current.getY()+1));
            adjacentE.setF();
            eastF=adjacentE.getF();}

        if(current.hasNeighbour(0,-1)!=null && grid[current.getX()][current.getY()-1].checkVisited()==false) {
            adjacentW = current.hasNeighbour(1,0);
            grid[current.getX()][current.getY()-1].setParent(current);
            adjacentW.setH(H(current.getX(), current.getY()-1));
            adjacentW.setF();
            westF=adjacentW.getF();}

        if(northF <southF &&northF < westF &&northF< eastF){
            current=adjacentN;
        }
        else if(eastF<southF && eastF< northF && eastF < westF){
            current=adjacentE;
        }
        else if(westF < southF && westF < northF && westF<eastF){
            current = adjacentW;
        }
        else
            current=adjacentS;

    }

    if(current==endElement) {

        while(current != startElement){
            current.setIsPathmember(true);
            current= current.getParent();
        }
        current.setIsPathmember(true);

        } else System.out.println("No path found");

}
    public int[][] getMap(){
        int[][] tempmap = new int[grid.length][grid[0].length];
        for(int i=0;i<grid.length;i++)
            for(int j=0;j<grid[0].length;j++)
                if(grid[i][j].getIsPathMember())
                    tempmap[i][j]=9;
                    else
                        tempmap[i][j]=grid[i][j].getCost();
        return tempmap;
}
    public int H(int x, int y){
    int xCoords=(endElement.getX())- x ;
    int yCoords=(endElement.getY()) - y ;
    return xCoords+yCoords;
}
}

这是 GridElement 类。这也是 Dijkstra 算法的 GridElement 类,所以如果您看到 Astar 不应该出现的任何内容,那就是原因。

public class GridElement {

private int x;
private int y;
private int value;
private boolean isVisited;
private GridElement parent;
private int cost;
private boolean isWall;
private GridElement[][] map;
private boolean isPathMember;
private int g;
private int h;
private int f;

public GridElement(int x, int y, int cost, GridElement[][] map) {
this.x=x;
this.y=y;
this.isPathMember=false;
this.isVisited=false;
this.parent=null;
this.value=Integer.MAX_VALUE;
if(cost==0)
    this.isWall=true;
else
    this.isWall=false;
this.cost = cost;   
this.map = map;
}

public int getX() {
    return x;
}
public int getY(){
    return y;
}
public void setValue(int v){
    this.value=v;
}
public boolean checkVisited(){
    return isVisited;
}
public int getValue(){
    return value;
}
public void setParent(GridElement p){
    this.parent=p;
}
public GridElement getParent(){
    return parent;
}
public boolean checkWall(){
    return isWall;
}
public void setVisited(boolean v){
    this.isVisited=v;
}
public void setIsPathmember(boolean is) {
    this.isPathMember = is;
}
public boolean getIsPathMember(){
    return isPathMember;
}
public int getCost(){
    return cost;
}

public void setG(int g){
    this.g=g;
}
public void setH(int h){
    this.h=h;
}

public void setF(){
    this.f=g+h;
}
public int getF(){
    return f;
}
public int getH(){
    return h;
}
public int getG(){
    return g;
}


public String toString() {
    String tempString="";
    tempString+="Node: "+getX()+","+getY()+","+getValue()+"|||";
    return tempString;
}

public GridElement hasNeighbour(int horizontalShift, int verticalShift){ // Params will be -+1
    if(getX()+horizontalShift>=0 && getX()+horizontalShift<map.length && getY()+verticalShift>=0 && getY()+verticalShift<map[0].length)
        if(!map[getX()+horizontalShift][getY()+verticalShift].checkWall())
            if(!map[getX()+horizontalShift][getY()+verticalShift].checkVisited())
                return map[getX()+horizontalShift][getY()+verticalShift];




return null;
}

}

我明白为什么“可能”有一个空指针,但 if 语句不应该在开始时处理这个问题吗? 提前致谢!

最佳答案

if(current.hasNeighbour(0,1)!=null ...

adjacentE = current.hasNeighbour(1,0);

您在 if 中检查了错误的值。 current.hasNeighbor(0,1) != null,但是current.hasNeighbor(1,0) == null。有人复制并粘贴并忘记更正参数。 ;)

关于java - A 星、H 值空指针 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17097007/

相关文章:

java - NullPointerException: 名称 == null

java - PrimeFaces 3.0.M4 <p :cellEditor> NullPointerException

java - hibernate :hbm2ddl.auto=生产中的更新?

java - 从库 jar 中引用 android 资源

java - 继续获取 "null has 00null"

c# - 应用 Dijkstra 算法实现时列表中的对象被删除

algorithm - 知识有限且无距离启发式寻路

java - JLabel 位于另一个 JLabel 之上?

android - 空指针异常 - findViewById()

java - 吃 bean 人角色 AI 建议的最佳下一个方向