boost::property_map 在 boost 中是如何实现的以及如何更改它

2024-04-30

我想知道属性映射是如何在提升图中实现的。例如,

我的顶点和边属性定义如下:

 //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 时,我可以使用以下属性将属性分配给顶点和边

for eg:

  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")

我的问题是:

  1. 这些属性如何存储在 Graph 对象中。
  2. 它是否存储在诸如 std::map 之类的地图中?或一些清单?或一些高效的类似地图的数据结构。
  3. 如果是这样,我如何将底层数据结构修改为 std::unordered_map 甚至 concurrent_hashmap 或 boost::vector_property_map ?

笔记: 我不确定我可以使用 vector_prop_map (此处),但我真的很想使用它,以便 顶点 id 成为向量索引并且更高效 --> 但它可能会导致边缘问题

我的图将包含一百万个顶点和许多边,以这种方式搜索 std::map 仍然是 log(n) 本身,但我希望可移植性改变 底层数据结构,以便我可以使用 unordered_map /并发_hashmap

我需要并发哈希图(来自英特尔TBB),因为我要并行化我的算法 因此希望同时访问属性映射,这将是 由线程修改。

请建议是否可以控制和修改boost graph中的此类底层数据结构来存储边和顶点属性。


这些属性如何存储在 Graph 对象中。

这些属性不会单独存储或类似存储。

顶点和边属性存储在图的顶点和边内。没有用std::map或一些其他关联容器。无论您向 adjacency_list 提供什么作为 VertexProperties 和 EdgeProperties 模板参数,都将存储在顶点和边中,即,与使用时相同std::list<T>其中 T 将存储在链表的节点中(以及必要的下一个指针)。换句话说,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 甚至并发_hashmap 或 boost::vector_property_map ?

您可以通过 OutEdgeList、VertexList 和 EdgeList 指定如何存储顶点和边。属性本身没有额外的存储方法。在这些上下文中使用映射或哈希图并没有多大意义。

我真的很想使用它,以便顶点 id 成为向量索引

当您指定时,adjacency_list 已经是这种情况vecS为了VertexList范围。

我需要并发哈希图(来自英特尔TBB),因为我将并行化我的算法,因此希望并发访问将由线程修改的属性映射。

你应该考虑使用平行图 http://www.boost.org/doc/libs/1_55_0/libs/graph_parallel/doc/html/index.html图书馆代替。

请建议是否可以控制和修改boost graph中的此类底层数据结构来存储边和顶点属性。

您可以指定用于存储顶点和边列表的数据结构。而且(理论上)您也可以为这些添加新类型的容器。然而,根据我的经验,这确实很困难,因为 adjacency_list 的实现非常难以理解,并且交换其底层容器并不像 Boost 网站上宣传的那么容易。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boost::property_map 在 boost 中是如何实现的以及如何更改它 的相关文章

  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • UWP 无法在两个应用程序之间创建本地主机连接

    我正在尝试在两个 UWP 应用程序之间设置 TCP 连接 当服务器和客户端在同一个应用程序中运行时 它可以正常工作 但是 当我将服务器部分移动到一个应用程序并将客户端部分移动到另一个应用程序时 ConnectAsync 会引发异常 服务器未
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • Fluent NHibernate 日期时间 UTC

    我想创建一个流畅的 nhibernate 映射来通过以下方式映射 DateTime 字段 保存时 保存 UTC 值 读取时 调整为本地时区值 实现此映射的最佳方法是什么 就我个人而言 我会将日期存储在 UTC 格式的对象中 然后在读 写时在
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat

随机推荐