Java A*执行问题
我在一个Java项目中使用*进行寻路。不过,我尝试实现它时遇到了一些问题。它不仅速度稍慢,而且有时会遇到无限循环问题,无法找到路径。我相信这是我的代码中某个地方的错误造成的。pathfinder在3d空间上运行,并使用一个基本的启发式(如果需要,我可以提供代码,但是,它只计算两点之间的距离平方) 代码如下:Java A*执行问题,java,path-finding,a-star,Java,Path Finding,A Star,我在一个Java项目中使用*进行寻路。不过,我尝试实现它时遇到了一些问题。它不仅速度稍慢,而且有时会遇到无限循环问题,无法找到路径。我相信这是我的代码中某个地方的错误造成的。pathfinder在3d空间上运行,并使用一个基本的启发式(如果需要,我可以提供代码,但是,它只计算两点之间的距离平方) 代码如下: public class BinaryPathFinder extends PathFinder { private final PriorityBuffer<PathNode&g
public class BinaryPathFinder extends PathFinder {
private final PriorityBuffer<PathNode> paths;
private final HashMap<Point, Integer> mindists = new HashMap<Point, Integer>();
private final ComparableComparator<PathNode> comparator = new ComparableComparator<PathNode>();
private Path lastPath;
private Point start, end;
private final byte SIZE_INCREMENT = 20;
public BinaryPathFinder(PathHeuristic heuristic,
Pathplayer player, PathWorld pathWorld) {
super(heuristic, player, pathWorld);
this.world = pathWorld.getWorld();
paths = new PriorityBuffer<PathNode>(8000, comparator);
}
@Override
public boolean find() {
try {
PathNode root = new PathNode();
root.point = start;
calculateTotalCost(root, start, start, false);
expand(root);
while (true) {
PathNode p = paths.remove();
if (p == null)
return false;
Point last = p.point;
if (isGoal(last)) {
calculatePath(p); // Iterate back.
this.mindists.clear();
this.paths.clear();
return true;
}
expand(p);
}
} catch (Exception e) {
e.printStackTrace();
}
this.mindists.clear();
this.paths.clear();
return false;
}
@Override
public Path path() {
return this.lastPath;
}
@Override
public void recalculate(Point start, Point end) {
this.start = start;
this.end = end;
this.lastPath = null;
}
private void expand(PathNode path) {
Point p = path.point;
Integer min = mindists.get(p);
if (min == null || min > path.totalCost)
mindists.put(p, path.totalCost);
else
return;
Point[] successors = generateSuccessors(p);
for (Point t : successors) {
if (t == null)
continue;
PathNode newPath = new PathNode(path);
newPath.point = t;
calculateTotalCost(newPath, p, t, false);
paths.add(newPath);
}
}
private void calculatePath(PathNode p) {
Point[] retPath = new Point[20];
Point[] copy = null;
short added = 0;
for (PathNode i = p; i != null; i = i.parent) {
if (added >= retPath.length) {
copy = new Point[retPath.length + SIZE_INCREMENT];
System.arraycopy(retPath, 0, copy, 0, retPath.length);
retPath = copy;
}
retPath[added++] = i.point;
}
this.lastPath = new Path(retPath);
}
private int calculateHeuristic(Point start, Point end, boolean endPoint) {
return this.heuristic.calculate(start, end, this.pathWorld,
this.player, endPoint);
}
private int calculateTotalCost(PathNode p, Point from, Point to,
boolean endPoint) {
int g = (calculateHeuristic(from, to, endPoint) + ((p.parent != null) ? p.parent.cost
: 0));
int h = calculateHeuristic(from, to, endPoint);
p.cost = g;
p.totalCost = (g + h);
return p.totalCost;
}
private Point[] generateSuccessors(Point point) {
Point[] points = new Point[27];
Point temp = null;
byte counter = -1;
for (int x = point.x - 1; x <= point.x + 1; ++x) {
for (int y = point.y + 1; y >= point.y - 1; --y) {
for (int z = point.z - 1; z <= point.z + 1; ++z) {
++counter;
if (x == 0 && y == 0 && z == 0)
continue;
temp = new Point(x, y, z);
if (valid(temp))
points[counter] = temp;
}
}
}
return points;
}
private boolean isGoal(Point last) {
return last.equals(this.end);
}
}
public class PathNode implements Comparable<PathNode> {
public Point point;
public final PathNode parent;
public int cost;
public int totalCost;
public PathNode(Point point, PathNode parent, short cost, short totalCost) {
this.point = point;
this.parent = parent;
this.cost = cost;
this.totalCost = totalCost;
}
public PathNode() {
this.point = null;
this.parent = null;
this.cost = this.totalCost = 0;
}
public PathNode(PathNode path) {
this.parent = path;
this.cost = path.cost;
this.totalCost = path.totalCost;
}
@Override
public int compareTo(PathNode node) {
int result = node.totalCost - node.cost;
if (result > node.totalCost)
return 1;
else if (result == 0)
return 0;
else
return -1;
}
}
公共类二进制PathFinder扩展了PathFinder{
私有最终优先级缓冲路径;
private final HashMap mindists=新HashMap();
私人最终可比比较仪比较仪=新的可比比较仪();
私有路径;
私密的起点、终点;
专用最终字节大小_增量=20;
公共二进制寻路器(路径启发式,
Pathplayer播放器,PathWorld(PathWorld){
超级(启发式、玩家、路径世界);
this.world=pathWorld.getWorld();
路径=新的优先级缓冲区(8000,比较器);
}
@凌驾
公共布尔查找(){
试一试{
PathNode根=新的PathNode();
root.point=开始;
calculateTotalCost(根、开始、开始、假);
展开(根);
while(true){
PathNode p=path.remove();
if(p==null)
返回false;
最后一点=p点;
如果(isGoal(last)){
calculatePath(p);//返回迭代。
这个。明德主义者。清除();
this.path.clear();
返回true;
}
扩大(p);
}
}捕获(例外e){
e、 printStackTrace();
}
这个。明德主义者。清除();
this.path.clear();
返回false;
}
@凌驾
公共路径路径(){
返回此.lastPath;
}
@凌驾
公共空间重新计算(点起点、点终点){
this.start=start;
this.end=end;
this.lastPath=null;
}
专用void扩展(路径节点路径){
点p=路径点;
整数min=mindsts.get(p);
if(min==null | | min>path.totalCost)
心智主义者。投入(p,路径。总成本);
其他的
回来
第[]点继任者=发电机接受者(p);
对于(t点:继任者){
如果(t==null)
持续
PathNode newPath=新的PathNode(路径);
newPath.point=t;
计算总成本(newPath,p,t,false);
添加(newPath);
}
}
专用void calculatePath(路径节点p){
点[]retPath=新点[20];
点[]复制=空;
短加=0;
for(路径节点i=p;i!=null;i=i.parent){
如果(添加>=retPath.length){
复制=新点[retPath.length+SIZE_INCREMENT];
数组复制(retPath,0,copy,0,retPath.length);
retPath=复制;
}
retPath[added++]=i.point;
}
this.lastPath=新路径(retPath);
}
private int calculateEuristic(点起点、点终点、布尔端点){
返回this.heuristic.calculate(开始、结束、this.pathWorld、,
这是一种新的方法;
}
private int calculateTotalCost(路径节点p、点起点、点终点、,
布尔端点){
int g=(计算神经(从,到,端点)+(p.parent!=null)?p.parent.cost
: 0));
int h=计算神经(从,到,终点);
p、 成本=g;
p、 总成本=(g+h);
返回p.totalCost;
}
专用点[]生成成功者(点点){
点[]点=新点[27];
点温度=零;
字节计数器=-1;
对于(int x=点x-1;x=点y-1;--y){
for(int z=point.z-1;z node.totalCost)
返回1;
否则如果(结果==0)
返回0;
其他的
返回-1;
}
}
Point只是一个定义整数x、y、z值的包装类
我使用ApacheCommonsPriorityBuffer来存储路径节点。
非常感谢您的帮助-提前感谢!仅从编程角度来看-您确定吗
for(PathNode i=p;i!=null;i=i.parent)
总是终止?这似乎是它唯一可以挂起的地方。No,因为第一个节点总是有一个null父节点。它似乎只是继续生成节点,从未找到路径(while循环从未中断)。