我正在实施A*
最短路径算法。 Openlist部分存储将要访问的所有节点。该列表就像一个优先级队列,第一个元素具有最小的成本值,因此在每次迭代中,我们只需弹出第一个元素并访问它。但是在迭代中,我们需要遍历此节点的邻居并检查邻居是否在Openlist中。
这意味着这个Openlist需要支持两种类型的操作:
这里的问题是Openlist将按成本值排序,而查找需要基于邻居节点(相邻节点)的ID。所以我在考虑使用set,其中元素是节点。但是我不知道如何通过它在这个集合中的ID来查找元素。
struct astar_node
{
string id;
double f; //estimated cost;
double g; //distance from source to this node;
double h; //heuristic cost from this node to target;
};
struct openlist_compare
{
bool operator()(const astar_node &node1, const astar_node &node2 ){
return node1.f < node2.f ;
}
};
std::set<astar_node, openlist_compare> Openlist;
答案 0 :(得分:1)
C ++容器,如std::set
,std::map
,std::list
和std::vector
以及其他容器,是&#34;单一目的&#34;或&#34原语&#34;容器。每一个都具有某些独特的特性,使它们与其他容器区别开来;否则,当然没有理由首先拥有所有这些容器。
std::set
的目的是按值查找容器中的值,并在集合中仅存储唯一值,即
与其他关联容器一样,std::set
允许您指定一个可选的比较器类,它实际上指定了&#34;值&#34;表示对于容器中的每个实际值。而且,您已经这样做了,实际上,只定义了f
类的astar_node
成员,这对于定义集合包含的内容很重要。 astar_node
的所有其他成员的所有其他值都将被忽略。
一旦完成,就std::set
而言,就是这样。该集可以由astar_node::f
查找,就是这样。这是在集合中查找内容的唯一方法。
正如我在开始时所说的那样,std::set
和其他人是&#34;原始&#34;容器,有时你会需要一些更复杂的东西,就像这里的情况一样。在这种情况下,您可以使用多个容器,并以实现所需结果的方式组合它们。没有法律禁止使用多个容器来存储单组数据。没有法律规定您必须使用单个容器来执行您需要执行的所有操作,并使用特定的数据集合。
在此,据我所知,您还需要能够通过astar_node
值在集合中找到id
。
精细:
typedef std::set<astar_node, openlist_compare> openlist_t;
openlist_t Openlist;
std::map<std::string, openlist_t::iterator> OpenList_by_id;
在insert()
astar_node
OpenList
insert()
之后,openlist_t
会返回astar_node
中新元素的迭代器。您将获得插入的OpenList_by_id
的迭代器。取这个迭代器,并将其放入id
,密钥为OpenList
。
现在,如果要在id
中找到remove
的内容,请使用地图查找迭代器,然后取消引用它。问题解决了。
此外:
astar_node
()来自std::set
的{{1}}也需要从OpenList_by_id
查找地图中删除其迭代器。
由于std::set
包含唯一值,因此您需要处理集合中已存在astar_node
f
的情况,并适当处理此情况。