A-Star的表现并不像它应该的那样

时间:2014-10-14 18:13:02

标签: java algorithm libgdx a-star

我对寻路很新,最近A-Star首次使用Libgdx在Java工作,但它有一些缺陷,它并不总能找到最快的路径,或者程序只是自杀(因为它太慢了?):/

(此处输入/输出:Imgur album:白色=未触摸的节点,绿色=开始,红色=目标,蓝色=路径,黄色=节点处于关闭列表但不相关)

可以找到其余代码on Github

这是算法本身的代码:

  

节点lastNode;

     

Node [] neighborNodes;

     

int lowestF = 2000;

     

节点bestNode;

public void findPath() {
    for(int x = 0; x < map.worldWidth; x++) {
        for(int y = 0; y < map.worldHeight; y++) {
            nodes[x][y].calculateHeuristic(targetNode);
        }
    }

    lastNode = startNode;

    while(lastNode != targetNode || !openList.isEmpty()) {
        neighborNodes = map.getNeighbors(lastNode);
        for(Node node:neighborNodes) {
            if(node != null)
                if(node.state != State.BLOCKED && !closedList.contains(node)) {
                    openList.add(node);
                    node.parentNode = lastNode;
                }
        }
        lowestF = 1000;
        for(Node node:openList) {
            if(node.f <= lowestF) {
                lowestF = node.f;
                bestNode = node;
            }
        }
        if(openList.isEmpty() && bestNode != targetNode) {
            System.out.println("No Path possible");
            return;
        }
        openList.remove(bestNode);
        closedList.add(bestNode);
        lastNode = bestNode;
        lastNode.setState(State.SEARCHED);
    }

    reconstructPath();
}

public void reconstructPath() {
    Node lastNode = targetNode;
    while(lastNode != startNode) {
        lastNode = lastNode.parentNode;
        lastNode.setState(State.PATH);
    }
    setStartAndEnd();
}

节点类:

public class Node {

public enum State {
    NORMAL, BLOCKED, START, END, SEARCHED, PATH
}

public State state;
int xPos, yPos;
Color color;
Node parentNode;

int f;
int movementCost = 10;
int heuristic;

public Node(int x, int y) {
    xPos = x;
    yPos = y;
    setState(State.NORMAL);
}

public void setState(State newState) {  
    state = newState;
}

public boolean isNodeClicked() {
    int inputX = Gdx.input.getX();
    int inputY = Gdx.graphics.getHeight() - Gdx.input.getY();
    if(inputX > xPos*32 && inputX < xPos*32+32 && 
        inputY > yPos*32 && inputY < yPos*32+32) {
        return true;
    }

    return false;
}

public void calculateHeuristic(Node targetNode) {
    heuristic = (Math.abs((xPos-targetNode.xPos)) + Math.abs((yPos-targetNode.yPos))) * movementCost;
    f = movementCost+heuristic;
}

public int calculateHeuristic(Node finishNode, int useless) {
    return (Math.abs((xPos-finishNode.xPos)) + Math.abs((yPos-finishNode.yPos))) * movementCost;
}

}

目前,我使用二维数组作为地图或节点,使用Arraylist作为打开和关闭列表。

如果有人能帮助我让我的A-star表现并向我解释我做错了什么,我会非常感激,我也会非常感谢任何其他批评,因为我想改进我的编程:)

感谢您在Advance中的帮助:)

1 个答案:

答案 0 :(得分:0)

你的问题在这里:

public void calculateHeuristic(Node targetNode) {
    heuristic = (Math.abs((xPos-targetNode.xPos)) + Math.abs((yPos- targetNode.yPos))) * movementCost;
    f = movementCost+heuristic;
}

您的启发式计算错误,因为您对movementCost的计算错误。节点的成本不是固定值。它是到目前为止沿着到该节点的路径的节点之间移动的所有成本的总和。所以你的节点实际上应该有一个函数,

public int calculateCost(){
    if(parentNode != null){
        return movementCost + parentNode.calculateCost();
    } else{
        return movementCost;
    }
}

你的启发式因此变成了:

public void calculateHeuristic(Node targetNode) {
    heuristic = (Math.abs((xPos-targetNode.xPos)) + Math.abs((yPos- targetNode.yPos))) * movementCost;
    f = calculateCost()+heuristic;
}

您的其他问题看起来可能都来自我在评论中提到的各种拼写错误/逻辑错误(while(...||openSet.isEmpty())而不是while(...|| !openSet.isEmpty())等)