【发布时间】:2021-02-03 17:03:20
【问题描述】:
我目前正在尝试实现 A*(A 星)- 算法。当我没有墙壁并且只需要在墙壁旁边时,我已经让它工作了。我现在的问题是,当我将起点放在墙内时,我的算法正在无限计算,因为我认为它不会倒退。你们能帮帮我吗?
这是来自节点类的代码:
int[][] mMap; // if there is a wall => 1
int[][] mAStarField;
ArrayList<AStarNode> mAStarPath;
public class AStarNode implements Comparable<AStarNode>{
public int x;
public int y;
public float c;
public AStarNode p;
public AStarNode(int x, int y, float c, AStarNode p) {
this.x = x; //X pos
this.y = y; //Y pos
this.c = c; //Cost to get to the node
this.p = p; //Parent of the node
}
//override the compareTo method
public int compareTo(AStarNode node)
{
if (c == node.c)
return 0;
else if (c > node.c)
return 1;
else
return -1;
}
}
public class Node {
public int x;
public int y;
public int z;
public int w;
public Node(int x, int y, int z, int w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
}
这是我的 A* 算法的代码:
//Pathfinding with A*
//return path length
int updateAStar() {
//Needed for drawing:
//Array containing the distance to the start node (filled with max int at start)
mAStarField = new int[mMap.length][mMap[0].length];
//List containing the found path
mAStarPath = new ArrayList<AStarNode>();
for (int j = 0; j < mMap.length; j++) {
for (int k = 0; k < mMap[0].length; k++) {
mAStarField[j][k]=Integer.MAX_VALUE;
}
}
//AStarNode(x,y,c,w)
//x X pos
//y Y pos
//c Cost to get to the node
//p Parent of the node
//List can be sorted expensive but simple by c value with
//Collections.sort(openList);
ArrayList<AStarNode> openList = new ArrayList<AStarNode>();
ArrayList<AStarNode> closedList = new ArrayList<AStarNode>();
int dist = abs(mStartNode[0]-mEndNode[0])+abs(mStartNode[1]-mEndNode[1]);
//If there is any target, that isn't on my field, add start node to list
if (dist>0 && mMap[mStartNode[0]][mStartNode[1]] != 1 && mMap[mEndNode[0]][mEndNode[1]]!=1) {
openList.add(new AStarNode(mStartNode[0], mStartNode[1], 0, null));
mAStarField[mStartNode[0]][mStartNode[1]] = 0;
}
// my code begins here (only everything from here on can be edited!)
while(!openList.isEmpty())
{
Collections.sort(openList);
AStarNode current = openList.get(0);
if(current.x == mEndNode[0] && current.y == mEndNode[1])
{
return 1;
}
openList.remove(0);
closedList.add(current);
ArrayList<AStarNode> neighbors = new ArrayList<AStarNode>();
neighbors.add(new AStarNode(current.x - 1, current.y, current.c + 1, current));
neighbors.add(new AStarNode(current.x + 1, current.y, current.c + 1, current));
neighbors.add(new AStarNode(current.x, current.y - 1, current.c + 1, current));
neighbors.add(new AStarNode(current.x, current.y + 1, current.c + 1, current));
for(AStarNode n : neighbors)
{
if(n.x >= 0 && n.y >= 0 && n.x < mMap.length && n.y < mMap.length && mMap[n.x][n.y] != 1){
float cost = estimateDistanceEnd(n.x, n.y);
n.c = cost;
if(closedList.contains(n) && cost >= n.c) continue;
if(!openList.contains(n) || cost < n.c)
{
n.p = current;
if(!openList.contains(n)){
mAStarField[n.x][n.y] = (int) n.c;
openList.add(n);
Collections.sort(openList);
}
}
}
}
}
return -1;
}
int estimateDistanceEnd(int x, int y){
return abs(x-mEndNode[0])+abs(y-mEndNode[1]);
}
int estimateDistanceStart(AStarNode a){
return abs(a.x-mStartNode[0])+abs(a.y-mStartNode[1]);
}
int estimateDistance(AStarNode a, AStarNode b){
return abs(a.x-b.x)+abs(a.y-b.y);
}
A picture of my current path solving result
重要提示:我只能在我标记的区域内更改代码。
谢谢!
【问题讨论】:
-
it doesn't go backward我认为在经典算法中,它会从堆栈中弹出值(先前的位置)以反转到先前的状态。如果你以不同的方式实现你的代码,你需要做一些等效的事情。 -
使用整数数组来存储节点位置...我不赞成这个(我知道这不是你的事,别担心)。
-
请帮我做这个测试:把这个单行语句 (
if(closedList.contains(n) && cost >= n.c) continue;) 写成普通的 if 并在 if 内放置一个断点。如果我是对的,你将永远不会达到那个断点。通过在您的回复中标记我,让我知道测试结果。 -
@laancelot 我试过了,你是对的。它永远不会达到断点。但我不知道为什么。编辑:我认为这是因为我总是在创建一个新节点,因此列表永远不会包含新节点。但是我应该如何解决这个问题?
标签: java data-structures processing path-finding a-star