具有自定义顶点和边的Boost Graph

Boost Graph with custom vertices and edges

本文关键字:Boost Graph 自定义 顶点      更新时间:2023-10-16

我正在创建一个具有自己的节点和边属性的自定义提升图。我将图形定义如下:

class NavGraph : public boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS, NodeInfo, EdgeInfo > {
public:
  typedef boost::graph_traits<NavGraph>::vertex_descriptor Vertex;
  typedef boost::graph_traits<NavGraph>::edge_descriptor Edge;
  NavGraph(){}
      void init(const std::vector<NodeInfo>& nodes, const std::vector<EdgeInfo>& edges);
}   

我现在要做的是从节点和边属性列表(在init方法中)初始化这个图。NodeInfo和EdgeInfo是具有基元类型的简单结构。到目前为止,我已经这样做了:

void NavGraph::init(const std::vector<NodeInfo>& nodes, const std::vector<EdgeInfo>& edges){
  //Add the Vertices
    for (std::vector<NodeInfo>::const_iterator it = nodes.begin() ; it != nodes.end(); ++it){
        Vertex u = boost::add_vertex(*this);
        (*this)[u].nodeIndex = (*it).nodeIndex;
        (*this)[u].x = (*it).x;
        (*this)[u].y = (*it).y;
        (*this)[u].z = (*it).z;
    }
    //Add the edges
    for (std::vector<EdgeInfo>::const_iterator it = edges.begin() ; it != edges.end(); ++it){
    //To be implemented
    }
 }

因此,我设法添加顶点并设置属性(希望是正确的)。现在,每个EdgeInfo都有一个源id和目标id,用于标识边缘的两个节点。问题是,我需要从图中按Id检索它们(使用之前设置的nodeIndex属性),这样我就可以调用add_edge方法。我真的不知道该怎么做。希望你们能帮助我。

从顶部开始:专门化邻接列表并添加自己的方法不是一个好主意。

相反,您应该创建boost::adjacety_list类的一个实例,作为一个新类的成员,然后可以为其编写方法。

class cNavGraph {
  public:
  boost::adjacency_list < boost::vecS,
  boost::vecS,
  boost::undirectedS, 
  NodeInfo, EdgeInfo > myNavGraph;
...

现在,要通过顶点属性nodeIndex从图中检索顶点,您有两个选项:

  1. 在顶点中搜索所需的nodeIndex。这很简单,但如果图形很大,则会很慢。

  2. 添加顶点时创建从nodeIndex到顶点的映射,然后在需要从nodeIndex获取顶点时在映射上进行查找。这需要更多的代码和内存,但对于大型图来说会更快。

作为一个更激进的建议,我建议重新设计一些东西,使NodeIndex和顶点描述符相同,比如这个

for (std::vector<EdgeInfo>::const_iterator it = edges.begin() ;
   it != edges.end(); ++it)
{
   add_edge( it->first_node_index,
             it->second_node_index,
             myGraph );

请注意,在回复您的评论时,对add_edge的调用将自动添加两个顶点(如果它们还不存在),顶点描述符等于指定的节点索引。不要调用add_vertex!

添加完所有边后,可以在节点中迭代,添加属性(根据需要)。