Java A*执行问题

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

我在一个Java项目中使用*进行寻路。不过,我尝试实现它时遇到了一些问题。它不仅速度稍慢,而且有时会遇到无限循环问题,无法找到路径。我相信这是我的代码中某个地方的错误造成的。pathfinder在3d空间上运行,并使用一个基本的启发式(如果需要,我可以提供代码,但是,它只计算两点之间的距离平方)

代码如下:

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循环从未中断)。