【问题标题】:Heterogeneous node types and edge types with boost::graph具有 boost::graph 的异构节点类型和边类型
【发布时间】:2015-02-23 18:41:41
【问题描述】:

是否可以使用 boost::graph 库拥有多种节点类型和多种边类型(节点到边类型映射)?

(这个问题与下面的代码审查有关:code

【问题讨论】:

    标签: templates c++11 graph containers boost-graph


    【解决方案1】:

    在这里回答您的代码审查问题:

    您的图表不是完全编译时的。

    不管底层结构“图”如何,想想像vertex v = add_vertex(graph)这样的函数。您可能可以使用类似的代码重载 traits<DataType>::vertex v = add_vertex(graph, data) 其中 add_vertex 是一个模板。

    对于相应的函数add_edge(s,t, graph, data);,您将需要更复杂的重载。

    编译器无法预想将添加哪些顶点。这意味着某种类型的运行时调度是不可避免的。它可以是虚拟表多态,也可以是 Boost.Variant,也可以是基于标志的朴素变体,甚至可以是双重调度(也称为访问者模式)。

    【讨论】:

    • 我认为你是对的,图表永远不会只有编译时调度,因为如果你查看 Node 中所需的存储类型总是异构的,这满足了一些需求变体(如在 boost:variant 中)、vtable 多态性等......但总是有一个运行时强制转换分支,但是我认为单独的特殊实现而不是 boost::graph 是更可取的,因为我们可以将不同的顶点类型存储在 独立存储(例如:std::tuple< std::vector<VertexType1> , std::vector<VertexType2> ... >),这使得应用访问者更快! ?
    • 使用您的实现,例如,需要在访问循环中访问节点上的每个顶点(带强制转换的运行时分支)(boost::variant),这很慢
    • 可以在不同的存储中存储不同的类型。您可以使用自定义结构来保留顶点和边。在这种情况下,某些操作(如 add_edge)会更快。然而,遍历将成为一场噩梦。你的迭代器将变成“boost::variants”。所有像“get_edges(v,g)”这样的 Boost 图函数都会返回变体等。
    【解决方案2】:

    理论上,您可以有一个顶点类型是多种类型的 Boost.Variant 的图。同样,您也可以将边缘类型设为 Boost.Variant。

    但是,如果您想要尽可能快的遍历,我建议您保持顶点和边类型的简单。相反,您可以将 Boost.Variant 用于边缘和顶点(捆绑)属性

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 2013-07-23
      相关资源
      最近更新 更多