我正在使用TreeSet
来存储执行A *算法时使用的路径查找位置。
基本上,除非有“开放”元素(仍然要详尽地访问),否则每个开放元素的邻居都会被考虑并添加到SortedSet
中,以便按成本和启发式成本对它们进行排序。这意味着我有一个类:
public class PathTileInfo implements Comparable<PathTileInfo>
{
int cost;
int hCost;
final int x, y;
@Override
public int compareTo(PathTileInfo t2) {
int c = cost + hCost;
int c2 = t2.cost + t2.hCost;
int costComp = c < c2 ? -1 : (c > c2 ? 1: 0);
return costComp != 0 ? costComp : (x < t2.x || y < t2.y ? -1 : (x > t2.x || y > t2.y ? 1 : 0));
}
@Override
public boolean equals(Object o2) {
if (o2 instanceof PathTileInfo) {
PathTileInfo i = (PathTileInfo)o2;
return i.cost + i.hCost == cost + hCost && x == i.x && y == i.y;
}
return false;
}
}
通过这种方式,首先考虑总成本,因为需要总排序(与equals的一致性),需要考虑根据x,y坐标的排序。
如果我在算法执行过程中迭代TreeSet,那么这应该可以工作,但它根本不会,
for (PathTileInfo t : openSet)
System.out.print("("+t.x+","+t.y+","+(t.cost+t.hCost)+") ");
我得到的结果是没有保留正确的顺序,例如:
(7,7,6)(7,6,7)(6,8,6)(6,6,7)(5,8,7)(5,7,7)(6,7, 6)(6,6,7)(6,5,7)(5,7,7)(5,5,8)(4,7,7)(4,6,8)(4,5,8) )
我有什么微妙的遗失吗? 谢谢!
答案 0 :(得分:1)
请确保在向TreeSet
添加后,不要更改元素的'可比较'值。如果您在添加到TreeSet
后更改了值,则TreeSet
无法维护新订单。
我认为您的PathTileInfo
是正确的,但在这种情况下不需要equals()
覆盖。
答案 1 :(得分:0)
TreeSet默认使用自然顺序对您添加的元素进行排序,这就是您的情况。你在创建它时是否告诉TreeSet使用自定义比较器?