我已经使用欧几里德启发式实现了一个明星实现,并且它可以工作,但在某些情况下会产生不必要的动作。
以下是截图: http://clip2net.com/s/6v2iU4
路径从蓝色圆圈开始,理论上,它右边的单元格具有较少的F(移动成本+启发式成本),因此a-star首先采用它,但最终建立的不是最短路径。
我该如何解决这个问题? 或者a-star应该以这种方式工作,我不需要做任何事情?
我的代码:http://pastebin.com/02u33jY6(h + cpp)
答案 0 :(得分:0)
您的算法存在的问题是,当您的openList
找到目标时,您的实现会返回路径。
当目标节点在closedList
中而不在打开列表中时,A *应该终止。
// check if there is dst node on the closed list
for ( unsigned int i = 0; i < closedList.size(); i++ )
{
if ( closedList.at( i ).getIndex() == dstTileIndex )
{
GSPathFinderNode* backtrackNode = &closedList.at( i );
resultPathNodes->insert( resultPathNodes->begin(), GSCommonMapNode( backtrackNode->getIndex(),
backtrackNode->getPosX(),
backtrackNode->getPosY() ) );
while ( 1 )
{
for ( unsigned int j = 0; j < closedList.size(); j++ )
{
if ( closedList.at( j ).getIndex() == backtrackNode->getParentNodeIndex() )
{
backtrackNode = &closedList.at( j );
resultPathNodes->insert( resultPathNodes->begin(), GSCommonMapNode( backtrackNode->getIndex(),
backtrackNode->getPosX(),
backtrackNode->getPosY() ) );
if ( backtrackNode->getIndex() == srcTileIndex )
return true; // success
}
}
}
}
}