boost::propertymap是如何在boost中实现的,以及如何更改它
how is boost::property_map implemented in boost and how to change it
我想知道属性映射是如何在boost Graph中实现的。例如,
我有这样定义的顶点和边属性:
//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 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
要访问任何顶点的节点属性,我可以使用以下两种方法中的任何一种:
//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")
我的问题是:
- 这些属性是如何存储在Graph对象中的
- 它是否存储在std::map<>之类的映射中?还是一些清单?或者一些有效的类似地图的数据结构
- 如果是,我如何将底层数据结构修改为std::unordered_map,甚至concurrent_hashmap或boost::vector_property_map
注:我不确定我是否可以使用vector_prop_map(在这里),但我真的很想使用它顶点id变为矢量索引,效率更高-->通过可能会导致边缘问题
我的图将包含一百万个顶点和许多边,通过这种方式在std::映射<>仍然是log(n),但我希望可移植性更改底层数据结构,以便我可以使用unordereded_map/concurrent_hashmap
我需要concurrent_hashmap(来自英特尔TBB),因为我将并行化我的算法因此希望同时访问属性映射通过线程修改。
请建议是否可以在boost图中控制和修改这些底层数据结构,以存储边和顶点属性。
这些属性是如何存储在Graph对象中的。
属性不会单独存储或类似存储。
顶点和边属性存储在图形的顶点和边中。不使用std::map
或某些其他关联容器。作为"顶点属性"answers"边属性"模板参数提供给"邻接列表"的任何内容都将存储在顶点和边中,即与使用std::list<T>
时相同,其中T将存储在链表的节点中(以及必要的下一个prev指针)。换句话说,邻接列表将存储包含类型为"顶点属性"的对象的顶点,以及所需的任何边列表(入和出)。
当您使用property_map
(通过get/put函数)时,它只是在做一点模板元编程魔术,来创建一个只会读/写顶点或边的正确单个属性的薄包装器。从概念上讲,这是等价的:
NodeInfo info = boost::get (NodeInfoPropertyTag(), G, v);
// is conceptual equivalent to:
NodeInfo info = G[v].NodeInfoProperty;
这就是属性映射真正所做的一切,它查找顶点属性(通过给定图形对象中的顶点描述符),并获取与给定标记类型对应的顶点属性的数据成员(或子对象)。弄清楚如何为正确的属性标记获得正确的数据成员(或子对象)是一项模板元编程魔法,它可以在编译时解决(没有运行时开销)。而且,一般来说,从顶点描述符中查找顶点属性是一种恒定时间操作(例如,取消引用指针、按索引查找等)
总的来说,为特定顶点获取(读取或写入)特定属性是一个恒定的时间操作。据我所知,这适用于您使用邻接列表的模板参数所做的任何选择。
如果是这样,我如何将底层数据结构修改为std::unordered_map,甚至concurrent_hashmap或boost::vector_property_map?
可以通过OutEdgeList、VertexList和EdgeList指定顶点和边的存储方式。属性本身没有其他存储方法。在这种情况下,使用地图或哈希图并没有多大意义。
我真的很想使用它,这样顶点id就变成了向量索引
当为VertexList
参数指定vecS
时,相邻列表已经是这种情况。
我需要concurrent_hashmap(来自Intel TBB),因为我将并行化我的算法,因此希望并发访问将由线程修改的属性映射。
您应该考虑使用并行图库。
请建议是否可以在boost图中控制和修改这些底层数据结构,以存储边和顶点属性。
可以指定用于存储顶点和边列表的数据结构。你也可以(理论上)为它们添加新类型的容器。然而,根据我的经验,这真的很困难,因为邻接列表的实现很难让你思考,而且交换其底层容器并不像Boost网站上宣传的那样容易。
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- C++ ReadDirectoryChangesW 和 Boost 将目录更改作为文件(旧名称)返回
- boost::split会在输入字符串不是常量时更改输入字符串吗?
- 浏览器将随机HTTP消息正文发送到我的boost.asio服务器.我可以更改此设置吗?
- BASIC_SOCKETD_ACCEPTOR接口在Boost 1.66中更改.这是一个错误
- 使用 boost::filesystem 迭代目录时可以更改文件的顺序吗?
- boost last_write_time更改最后一个写入值
- 更改命名空间以自定义 Boost XML 的标记名称后的反序列化问题
- C++11: boost::make_tuple 与 std::make_tuple 有何不同?
- 在构建过程中更改Boost库的路径
- Boost::random::discrete_distribution构建后如何更改权重
- 更改多态性boost :: shared_ptr(内部std :: vector)中的值
- 将 boost::scoped_ptr 更改为标准::unique_ptr
- 使用 boost::regex 更改文件中数据的格式
- 当使用信号处理程序触发事件时,如何使boost.msm正确更改状态
- 更改boost属性树的数据类型
- boost asio-更改有缺陷的代码
- 如何使用Boost库更改文件权限
- 如何使用boost库更改文件所有权
- 如何使用Boost.Filesystem更改当前路径?