Java *星型openlist未按预期工作
我曾经问过一个*的数据结构。我现在解决了这个问题。但还有另一个问题。我的A*速度很慢,没有我预期的效果。这意味着 我用Java实现了Wikipedia伪代码(德语和英语)中的源代码。下图是我用于测试目的的图表。例如,该算法从节点1开始到目的地节点8。启发式函数将通过使用节点旁边方形制动器中的坐标计算曼哈顿距离。closedlist是从起始节点1(前置节点)构建到3(1)-6(3)-2(1)-4(1)-3(2)-2(3)-4(3)-8(6)。我认为A*是从1直接到8的,因为它是最短的路径。但它从6跳回到节点2,因为2的f值是列表中最低的。那么这是正确的吗?在示例中,我看到它在访问一个节点后,从未跳转回任何其他节点。我有一个从两个方向与其他节点相连的图。因此,我更改了源代码中的if条件,以证明反向方式是否在相应的列表中。否则它将以一个无休止的循环结束。 问题是什么?为什么从节点6跳回到节点2?我必须删除openlist中的节点吗? .Java *星型openlist未按预期工作,java,algorithm,graph,path-finding,a-star,Java,Algorithm,Graph,Path Finding,A Star,我曾经问过一个*的数据结构。我现在解决了这个问题。但还有另一个问题。我的A*速度很慢,没有我预期的效果。这意味着 我用Java实现了Wikipedia伪代码(德语和英语)中的源代码。下图是我用于测试目的的图表。例如,该算法从节点1开始到目的地节点8。启发式函数将通过使用节点旁边方形制动器中的坐标计算曼哈顿距离。closedlist是从起始节点1(前置节点)构建到3(1)-6(3)-2(1)-4(1)-3(2)-2(3)-4(3)-8(6)。我认为A*是从1直接到8的,因为它是最短的路径。但它从6
public ArrayList executestar(ArrayList数据、NodeD start、NodeD dest)
{
openlist=新的优先级队列(1,comp);
closedlist.clear();
openlist.offer(开始);
start.setg(0);
起始距离(起始距离、目的距离);
setf(start.getg()+start.geth());
而(!openlist.isEmpty())
{
NodeD currentnode=openlist.poll();
如果(currentnode.getnodenumber()==dest.getpredessor())
{
closedlist.add(当前节点);
返回关闭列表;
}
closedlist.add(当前节点);
对于(int i=0;i=successor.getg())
{
继续;
}
if(!(包含(继任者,openlist))| |(暂定的_g
A*中的启发必须是——也就是说,它决不能高估在两个节点之间移动的成本
在您的示例中,[2,4]
和[4,2]
之间的成本是3,但Manhatten距离是4。因此,它是不允许的,并且不会作为一种启发式方法对您起作用
我必须删除openlist中的节点吗
呃,是的,否则你的
while
循环将永远无法完成。删除甚至在中明确说明粘贴一个代码是有用的和好的。有关性能:首先,考虑将OpenOLLT中的项添加到<代码> SET/COD> >称为代码> OpenSET/<代码>。通过调用openSet.contains(节点)
,可以快速检查项目是否在openList中。只需确保在打开集关闭时也将其从打开集中删除即可。第二,考虑使用另一个OpenList:我在自己的A*算法中使用了一个使用了<代码> FiBoNoCithHAP的java代码的10X速度改进。或者我的代码是正确的,但选择的示例具有最坏的成本?我的while循环即将结束。它通过执行openlist.poll()进行删除;列表中f值最低的元素。使用欧几里德距离来计算启发式是否更好?@IrgendwPointer:这取决于实际问题所在-在某些情况下,没有好的启发式。返回最短路径必须是可接受的(如果也是,那将是最好的)。从你的例子来看,欧几里德距离也不起作用,因为[4,4]
和[4,6]
之间的距离只有1。我现在使用欧几里德距离,它比曼哈顿距离要好。但是在我的openlist中仍然有很多不必要的节点。但对于这个简短的示例,我的运行时间是62毫秒。但我觉得还是太高了,因为我的Dijkstra只需要14毫秒。所以我的算法仍然有问题,但我不知道是什么。
public ArrayList<NodeD> executeAstar(ArrayList<Arclistentry> data, NodeD start, NodeD dest)
{
openlist = new PriorityQueue<NodeD>(1,comp);
closedlist.clear();
openlist.offer(start);
start.setg(0);
start.seth( manhattendistance(start, dest));
start.setf(start.getg()+start.geth());
while(!openlist.isEmpty())
{
NodeD currentnode = openlist.poll();
if(currentnode.getnodenumber() == dest.getpredessor())
{
closedlist.add(currentnode);
return closedlist;
}
closedlist.add(currentnode);
for(int i=0; i< data.size(); i++)
{
if(data.get(i).getstart()==currentnode.getnodenumber())
{
NodeD successor = new NodeD(data.get(i).getnode(),data.get(i).getstart(), data.get(i).getcoorddest());
NodeD reversesuccessor = new NodeD(data.get(i).getstart(),data.get(i).getnode(),data.get(i).getcoordstart());
float tentative_g = currentnode.getg()+data.get(i).getcost();
if((contains(successor, closedlist)||contains(reversesuccessor, closedlist))&&(tentative_g >=successor.getg()))
{
continue;
}
if(!(contains(successor, openlist))|| (tentative_g < successor.getg()))
{
successor.setpredessor(currentnode.getnodenumber());
successor.setg(tentative_g);
successor.seth(manhattendistance(successor, dest));
successor.setf(successor.getg()+manhattendistance(successor, dest));
if(!contains(successor, openlist))
{
openlist.offer(successor);
}
}
}
}
}
ArrayList<NodeD> ret = null;
return ret;
}