【问题标题】:undirected DFS: how can I provide color maps as exterior properties?无向 DFS:如何提供颜色图作为外部属性?
【发布时间】:2017-04-18 16:01:45
【问题描述】:

我正在使用无向 DFS (Depth First Search) 算法 implemented in boost::graph

该算法需要顶点和边上的颜色值来跟踪已解析的值。 在the provided example 中,代码将这些颜色值存储为图形的内部属性:

typedef adjacency_list<
    vecS,
    vecS,
    undirectedS,
    no_property,       // vertex properties
    property<edge_color_t, default_color_type> // edge colors
> graph_t;

并且调用是使用“命名属性”版本完成的:

undirected_dfs(g, root_vertex(vertex_t(0)).visitor(vis)
             .edge_color_map(get(edge_color, g)));

我的问题是我有顶点和边的自定义值。我使用似乎是the preferred way of doing,它被称为 “捆绑属性”:

struct my_vertex { int a1; float a2; }
struct my_edge   { int b1; float b2; }
typedef adjacency_list<
    vecS,
    vecS,
    undirectedS,
    my_vertex,       // vertex properties
    my_edge          // edge properties
> graph_t;

当然,前面的 DFS 函数调用不适用于这种图形类型定义。 对于顶点,手册声明提供了默认值,并且它确实构建得很好,只有特定的顶点类型和边类型,如上所示。 但是如果我想要一个特定的边缘类型,我得出的结论是我需要单独提供算法所需的颜色,因为我不能使用示例代码中显示的属性。所以我认为这可以通过将它们提供为“外部属性”来完成。

我的问题是:我该怎么做?

Manual excerpt:

UTIL: edge_color_map(EdgeColorMap edge_color) 算法使用它来跟踪已访问过哪些边。 EdgeColorMap 类型必须是 Read/Write Property Map 及其键的模型 type 必须是图的边缘描述符类型和颜色的值类型 地图必须对 ColorValue 建模。

我不清楚,我试图阅读关于属性映射的部分,但我就是不明白。

this answer 的帮助下,我在下面尝试了这个,但是失败了: (使用“未命名参数”版本)

std::vector<int> edge_color(   boost::num_edges(g), 0);
std::vector<int> vertex_color( boost::num_vertices(g), 0 );

boost::undirected_dfs(
    g,
    boost::visitor( boost::default_dfs_visitor() ),
    boost::vertex_color_map( vertex_color ),
    boost::edge_color_map( edge_color ),
    boost::root_vertex( vertex_t(0) )
);

如果有人能指出我正确的方向......

【问题讨论】:

    标签: c++ boost depth-first-search boost-graph


    【解决方案1】:

    您需要满足记录的确切参数要求:http://www.boost.org/doc/libs/1_63_0/libs/graph/doc/undirected_dfs.html

    这意味着您/可以/摆脱顶点颜色的向量,但边缘颜色需要在关联容器中,因为边缘描述符不像顶点描述符对于您的图形类型那样是整数。

    std::vector<default_color_type> vertex_color(num_vertices(g));
    std::map<graph_t::edge_descriptor, default_color_type> edge_color;
    
    auto idmap = get(vertex_index, g);
    auto vcmap = make_iterator_property_map(vertex_color.begin(), idmap);
    auto ecmap = make_assoc_property_map(edge_color);
    
    graph_t::vertex_descriptor const start = 0;
    

    现在您可以调用算法的固定参数版本:

    undirected_dfs(g, vis, vcmap, ecmap, start);
    

    或者,使用命名参数版本调用完全相同的方法:

    undirected_dfs(g, 
            root_vertex(graph_t::vertex_descriptor(0))
            .visitor(vis)
            .vertex_color_map(vcmap)
            .edge_color_map(ecmap)
        );
    

    演示

    Live On Coliru

    #include <iostream>
    #include <boost/graph/depth_first_search.hpp>
    #include <boost/graph/undirected_dfs.hpp>
    #include <boost/graph/adjacency_list.hpp>
    
    using namespace boost;
    
    struct my_vertex { int a1; float a2; };
    struct my_edge   { int b1; float b2; };
    
    struct detect_loops : public boost::dfs_visitor<> {
        template <class Edge, class Graph>
        void back_edge(Edge e, const Graph& g) {
            std::cout << g[source(e,g)].a1 << " -- " << g[target(e,g)].a1 << "\n";
        }
    };
    
    
    typedef adjacency_list<vecS, vecS, undirectedS, my_vertex, my_edge> graph_t;
    
    int main() {
        detect_loops vis;
    
        graph_t g;
    
        std::vector<default_color_type> vertex_color(num_vertices(g));
        std::map<graph_t::edge_descriptor, default_color_type> edge_color;
    
        auto idmap = get(vertex_index, g);
        auto vcmap = make_iterator_property_map(vertex_color.begin(), idmap);
        auto ecmap = make_assoc_property_map(edge_color);
    
        graph_t::vertex_descriptor const start = 0;
    
        undirected_dfs(g, vis, vcmap, ecmap, start);
    
        undirected_dfs(g, 
                root_vertex(graph_t::vertex_descriptor(0))
                .visitor(vis)
                .vertex_color_map(vcmap)
                .edge_color_map(ecmap)
            );
    }
    

    【讨论】:

    • 谢谢@sehe,我需要一些时间来仔细研究这个,但我真的很感谢你详细的回答。
    • 好的,确认。但这提出了另一个问题:BGL 用户应该如何找到它?我的意思是,我在属性图上搜索了twopages,但那里似乎没有记录这两个make_XXX 函数。他们在其他地方解释过吗?如果没有,是怎么知道他们的?
    • 那些页面有货。它是如此抽象,以至于需要一些时间来适应它们,就像乐高积木一样。一旦你这样做了,非常简单的东西,比如:coliru.stacked-crooked.com/a/44f071dd0e299ae4,然后可能是coliru.stacked-crooked.com/a/3eff0ef4ae1ef829。乐高积木。
    • 现在要真正了解哪个属性映射可以满足 BGL 算法文档要求的哪些概念,请返回您已经找到的那些文档页面。它们真的很详尽,只是很干:)(顺便说一句,请确保单击Property Map Types 标题下的所有类型)。另外,参见例如stackoverflow.com/questions/27863061/…
    • 非常感谢这些 cmets 和 2 个(非常)有价值的样本:这确实是文档中缺少的那种东西!多亏了你,我想我开始了解属性图的工作原理了。
    猜你喜欢
    • 2011-02-26
    • 2011-02-01
    • 1970-01-01
    • 2011-10-01
    • 2011-12-17
    • 1970-01-01
    • 2014-06-08
    • 2019-12-23
    • 1970-01-01
    相关资源
    最近更新 更多