<分区>
我正在尝试用 Java 实现 A* 算法。我遵循了本教程,特别是这个伪代码:http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html
问题是我的代码不起作用。它进入无限循环。我真的不知道为什么会这样……我怀疑问题出在 Graph 构造函数中实现的 F = G + H 函数中。我怀疑我没有正确计算邻居 F。
这是我的代码:
List<Graph> open;
List<Graph> close;
private void createRouteAStar(Unit u)
{
open = new ArrayList<Graph>();
close = new ArrayList<Graph>();
u.ai_route_endX = 11;
u.ai_route_endY = 5;
List<Graph> neigh;
int index;
int i;
boolean finish = false;
Graph current;
int cost;
Graph start = new Graph(u.xMap, u.yMap, 0, ManhattanDistance(u.xMap, u.yMap, u.ai_route_endX, u.ai_route_endY));
open.add(start);
current = start;
while(!finish)
{
index = findLowerF();
current = new Graph(open, index);
System.out.println(current.x);
System.out.println(current.y);
if (current.x == u.ai_route_endX && current.y == u.ai_route_endY)
{
finish = true;
}
else
{
close.add(current);
open.remove(open.indexOf(current)); //EDITED LATER
neigh = current.getNeighbors();
for (i = 0; i < neigh.size(); i++)
{
cost = current.g + ManhattanDistance(current.x, current.y, neigh.get(i).x, neigh.get(i).y);
if (open.contains(neigh.get(i)) && cost < neigh.get(i).g)
{
open.remove(open.indexOf(neigh));
}
else if (close.contains(neigh.get(i)) && cost < neigh.get(i).g)
{
close.remove(close.indexOf(neigh));
}
else if (!open.contains(neigh.get(i)) && !close.contains(neigh.get(i)))
{
neigh.get(i).g = cost;
neigh.get(i).f = cost + ManhattanDistance(neigh.get(i).x, neigh.get(i).y, u.ai_route_endX, u.ai_route_endY);
neigh.get(i).setParent(current);
open.add(neigh.get(i));
}
}
}
}
System.out.println("step");
for (i=0; i < close.size(); i++)
{
if (close.get(i).parent != null)
{
System.out.println(i);
System.out.println(close.get(i).parent.x);
System.out.println(close.get(i).parent.y);
}
}
}
private int findLowerF()
{
int i;
int min = 10000;
int minIndex = -1;
for (i=0; i < open.size(); i++)
{
if (open.get(i).f < min)
{
min = open.get(i).f;
minIndex = i;
System.out.println("min");
System.out.println(min);
}
}
return minIndex;
}
private int ManhattanDistance(int ax, int ay, int bx, int by)
{
return Math.abs(ax-bx) + Math.abs(ay-by);
}
而且,正如我所说的。我怀疑 Graph 类有主要问题。但是我一直无法检测和修复它。
public class Graph {
int x, y;
int f,g,h;
Graph parent;
public Graph(int x, int y, int g, int h)
{
this.x = x;
this.y = y;
this.g = g;
this.h = h;
this.f = g + h;
}
public Graph(List<Graph> list, int index)
{
this.x = list.get(index).x;
this.y = list.get(index).y;
this.g = list.get(index).g;
this.h = list.get(index).h;
this.f = list.get(index).f;
this.parent = list.get(index).parent;
}
public Graph(Graph gp)
{
this.x = gp.x;
this.y = gp.y;
this.g = gp.g;
this.h = gp.h;
this.f = gp.f;
}
public Graph(Graph gp, Graph parent)
{
this.x = gp.x;
this.y = gp.y;
this.g = gp.g;
this.h = gp.h;
this.f = g + h;
this.parent = parent;
}
public List<Graph> getNeighbors()
{
List<Graph> aux = new ArrayList<Graph>();
aux.add(new Graph(x+1, y, g,h));
aux.add(new Graph(x-1, y, g,h));
aux.add(new Graph(x, y+1, g,h));
aux.add(new Graph(x, y-1, g,h));
return aux;
}
public void setParent(Graph g)
{
parent = g;
}
//Added later. Generated by Eclipse
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Graph other = (Graph) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
小修改:
使用 System.out
和调试器我发现程序总是检查相同的“当前”图,(15,8)
这是 (u.xMap, u.yMap)
位置。看起来它永远保持在第一步中。