在boost中实现的地图以及如何更改它
我想知道如何在增强图中实现属性映射。 例如,
我有像这样定义的顶点和边的属性:
//vertex property:-->
struct NodeInfo { int a , b , c; }; //actual bundled property
struct NodeInfoPropertyTag { // tag and kind (as in boost documentation)
typedef boost::vertex_property_tag kind;
static std::size_t const num;
};
std::size_t const NodeInfoPropertyTag::num = (std::size_t) &NodeInfoPropertyTag::num;
//typedef the Vertex Property
typedef boost::property <NodeInfoPropertyTag, NodeInfo> NodeProperty;
//Similar fashion for Edge Property --> some property for each edge of graph.
typedef boost::property <EdgeInfoPropertyTag, EdgeInfo> EdgeProperty;
我的图是typedef'd如下:
typedef boost::adjacency_list <vecS, vecS, undirectedS, NodeProperty, EdgeProperty, no_property, listS> Graph_t;
现在,在使用上面的typedef初始化图G时,我可以使用属性为顶点和边指定属性
例如:
Graph_t G;
typedef graph_traits<Graph_t>::vertex_descriptor vd_t;
// edge_descriptor ed_t;
NodeInfo ninfo1, ninfo2; //put some values in ninfo
vd_t v = add_vertex (ninfo1, G) //add a vertex in G with property ninfo1
vd_t u = add_vertex (ninfo2, G) //add a vertex in G with property ninfo2
EdgeInfo einfo; //initialize edgeinfo for edge property
add_edge (u, v, einfo, G ) edge (u, v) with property einfo is added in G
要访问任何顶点的节点属性,我可以使用2种方法中的任何一种,如下所示:
//method 1: direct method: using Tags
// for a vertex "v" --> get()
NodInfo info = boost::get (NodeInfoPropertyTag(), G, v) //get v's property
//modify info
//put the modified property
put (NodeInfoPropertyTag(), G, v, info) // (put in G, key = v, value = info )
//method 2 : using property maps.
//Edge Map and Node Map
typedef typename boost::property_map <Graph_t, EdgeInfoPropertyTag>::type EdgeMap;
typedef typename boost::property_map <Graph_t, NodeInfoPropertyTag>::type NodeMap;
//edge e --> get
EdgeInfo einfo = boost::get (EdgeMap, e)
//modify einfo
//put
put (EdgeMap, e, einfo) //put in the EdgeMap key = e, value = einfo
现在,这两种操作基本相同:即使用
//former is translated to the latter -->
get(NodeInfoPropertyTag(), G, "key") is equivalent to get (NodeMap, "key")
我的问题是:
注意:我不确定我可以使用vector_prop_map(这里),但我真的想使用它,以便顶点id变成矢量索引并且更高效 - >它可能会导致边缘问题
我的图将包含一百万个顶点和许多边,通过这种方式,std :: map <>中的搜索仍然是log(n),但我希望可移植性更改底层数据结构,以便可以使用unordered_map / concurrent_hashmap
我需要concurrent_hashmap(来自英特尔TBB),因为我将并行化我的算法,因此希望并发访问将由线程修改的属性映射。
请提出是否可以控制和修改增强图中用于存储边和顶点属性的基础数据结构。
这些属性如何存储在Graph对象中。
这些属性不是单独存储的或者其他类似的东西。
顶点和边的属性存储在图的顶点和边上。 没有使用std::map
或其他关联容器。 无论您提供给adjacency_list的是什么,因为VertexProperties和EdgeProperties模板参数将存储在顶点和边上,即它与使用std::list<T>
时的相同,其中T将存储在链接的节点中-list(以及必要的next-prev指针)。 换句话说,adjacency_list将存储包含VertexProperties类型对象的顶点,以及所需的任何边界列表(入和出)。
当你使用property_map
(通过get / put函数)时,它只是做一些模板元编程魔术来创建一个薄包装器,它将只读/写一个顶点或边的正确单个属性。 从概念上讲,这是等价的:
NodeInfo info = boost::get (NodeInfoPropertyTag(), G, v);
// is conceptual equivalent to:
NodeInfo info = G[v].NodeInfoProperty;
这是属性映射的全部功能,它查找顶点属性(通过给定图形对象中的顶点描述符),并获取与给定对应的顶点属性的数据成员(或子对象)标签类型。 弄清楚如何为正确的属性标签获取正确的数据成员(或子对象)是一种模板元编程魔术,可以在编译时计算出来(无运行时开销)。 而且,通常,从顶点描述符查找顶点属性是一个常量操作(例如,取消引用指针,按索引查找等)。
总体而言,读取(读取或写入)特定顶点的特定属性是一种常量操作。 就我所知,对于使用adjacency_list的模板参数所做的任何选择都是如此。
如果是这样,我怎么能修改底层数据结构为std :: unordered_map甚至concurrent_hashmap或boost :: vector_property_map?
您可以通过OutEdgeList,VertexList和EdgeList指定如何存储顶点和边。 这些属性本身没有额外的存储方法。 在这些情况下使用地图或hashmaps并没有多大意义。
我真的很想使用它,以便顶点ID变成矢量索引
当您为VertexList
参数指定vecS
时,这已经是adjacency_list的情况。
我需要concurrent_hashmap(来自英特尔TBB),因为我将并行化我的算法,因此希望并发访问将由线程修改的属性映射。
您应该考虑使用并行图库来代替。
请提出是否可以控制和修改增强图中用于存储边和顶点属性的基础数据结构。
您可以指定用于存储顶点和边界列表的数据结构。 你可以(理论上)为这些添加新的容器类型。 然而,根据我的经验,这很难实现,因为adjacency_list的实现很难将您的思想包装起来,并且交换其底层容器并不像在Boost网站上宣传的那么容易。
链接地址: http://www.djcxy.com/p/51057.html上一篇: map implemented in boost and how to change it
下一篇: vector of the boost