我试图在图表中学习一些关于寻路的新方法 现在我正在探索A-star算法。
我根据Wikipedia编写了我的代码,它运行正常,但有一个问题我试图解决几个小时:
维基百科的实现允许“重建路径” - 它将显示用于查找路径的所有方法。
是否有机会仅显示连接起点和终点的路径而不显示中间步骤(当算法出错时)?
更新2 这是一个节点:
class aNode
{
public:
QHash<quint64,Node>::iterator it;
quint64 comeFrom;
double f;
double g;
double h;
}
所以我已经将aNode类中的类型从int更改为double(因为我使用具有真实地理坐标的两个节点之间的距离)并修改了我的算法。
这是:
bool Graph::findPath(Node* node_from, Node* node_to)
{
QMap<double,aNode> open; // key - cost function f
QMap<quint64,aNode> closed; // key - Node id
aNode sNode;
sNode.it = nodes.find(node_from->id);
sNode.g = 0;
sNode.h = distance(node_from,node_to);
sNode.f = sNode.g + sNode.h;
sNode.comeFrom = 0;
open.insert(sNode.f, sNode);
while (!open.isEmpty())
{
aNode x = open.begin().value();
if (x.it->id == node_to->id)
{
int comeFrom = x.comeFrom;
while (comeFrom != 0)
{
route.push_back(comeFrom);
comeFrom = closed.find(comeFrom)->comeFrom;
}
return true;
}
open.remove(x.f);
closed.insert(x.it->id,x);
for (int i = 0 ; i < x.it->adj.size() ; i++)
{
if (!edges.contains(QPair<quint64,quint64>(x.it->id,x.it->adj[i])))
continue;
if (closed.contains(x.it->adj[i]))
continue;
aNode y;
y.it = nodes.find(x.it->adj[i]);
y.g = x.g + edges.find(QPair<quint64,quint64>(x.it->id,x.it->adj[i]))->cost;
y.h = distance(&(*y.it),node_to);
y.f = y.g + y.h;
y.comeFrom = x.it->id;
if (open.key(y,-2) == -2)
open.insert(y.f,y);
else
if (y.g < open.find(open.key(y))->g )
open.insert(y.f, y);
}
}
return false;
}
但它仍在绘制中间步骤。在我看来史密斯错误的'comeFrom'提交
答案 0 :(得分:1)
您的算法不正确,因为您的开放集是地图,而不是优先级排队。要使星形正确执行,您需要始终评估具有最小成本函数的节点(tentative_score
)。在您的情况下aNode x