BGL: Using bundled properties to store vertex descriptor of another vertex

懵懂的女人 提交于 2020-01-05 11:15:10

问题


I am trying to create a tree graph using boost::adjacency list and bundled properties to store the parent for every vertex, I want to store vertex descriptors in a way that they wont invalidate in case I remove a vertex, so I use boost::listS, the code should look something like this

// custom vertex for tree graphs
struct tree_vertex_info{
    // descriptor of parent vertex
    boost::graph_traits<Tree>::vertex_descriptor parent_in_tree;
};
// the tree graph type
typedef boost::adjacency_list<boost::listS, boost::listS, boost::directedS
        tree_vertex_info, boost::no_property, graph_info> Tree;

But this would not work since Tree must be defined after the struct definition. Is there any other way to do it with bundled properties? I thought I could use an int variable instead of vertex_descriptor type to store vertex_descriptors but since I use boost::listS to store them I am not sure if can.


回答1:


Theoretically, you could have something like this:

struct tree_vertex_info;  // forward-declaration

typedef boost::adjacency_list<
  boost::listS, boost::listS, boost::directedS, 
  tree_vertex_info, boost::no_property, graph_info> Tree;

struct tree_vertex_info {
  boost::graph_traits<Tree>::vertex_descriptor parent_in_tree;
};

However, this would require the boost::adjacency_list class template to support incomplete types (which is what tree_vertex_info is while there is only a forward-declaration, until the compiler reaches the complete declaration of it). As far as I know, the boost::adjacency_list class does not support incomplete types (and I know that implementation quite a bit, and I don't think it would work) and it is certainly not guaranteed to support them.

I am actually working on a new version of boost::adjacency_list which I call boost::adjacency_list_BC because it's based on Boost.Container containers, and it will support incomplete types. However, it is still kind at a beta stage (follow here or here), and the latest versions of Boost.Container seem to have broken something that I still need to figure out. By the way, I also have a number of BGL tree data-structures as well as new BGL concepts and traits for trees (since you seem to be implementing a kind of tree).

Also, if your motivation for this is really what you have there (the "parent-in-tree"), then you should be using boost::bidirectionalS in your adjacency_list to be able to get from a child vertex to its parent (that's what boost::bidirectionalS means, you get a BidirectionalGraph).

Finally, to actually solve this situation you are in, you'll have to use a type-erasure technique. A simple off-the-shelf way to do it is to use boost::any to erase the type of the vertex_descriptor, like so:

struct tree_vertex_info{
  // descriptor of parent vertex
  boost::any parent_in_tree;
};

// the tree graph type
typedef boost::adjacency_list<boost::listS, boost::listS, boost::directedS
        tree_vertex_info, boost::no_property, graph_info> Tree;

Just look up Boost.Any for instructions on using it.

I thought I could use an int variable instead of vertex_descriptor type to store vertex_descriptors but since I use listS to store them I am not sure if can.

No, you cannot. You cannot depend on the vertex_descriptor type being anything in particular (e.g., you cannot assume it is an integer type, let alone "int"). I happen to know that vertex_descriptor is usually either an iterator type (such as std::list<T>::iterator) or a size-type (like std::size_t or std::vector<T>::size_type), but that's an implementation detail that you should not and cannot rely on.



来源:https://stackoverflow.com/questions/25985929/bgl-using-bundled-properties-to-store-vertex-descriptor-of-another-vertex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!