【问题标题】:How does boost::copy_graph's vertex_copy work?boost::copy_graph 的 vertex_copy 是如何工作的?
【发布时间】:2016-11-05 20:10:38
【问题描述】:

我正在使用 boost::copy_graphadjacency_list 复制到另一个 adjacency_list 并使用不同的 VertexProperties 模板。为此,我尝试使用vertex_copy 参数(doc here)。我遇到了一个编译器错误,告诉我第二个(要复制的)图的顶点属性类型错误。

小例子

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>

typedef boost::adjacency_list<boost::vecS,
                              boost::vecS,
                              boost::undirectedS,
                              uint32_t,
                              float> AdjacencyList;

typedef AdjacencyList::vertex_descriptor VertexID;

struct custom_property
{
    uint32_t label;
    float f;
};

typedef boost::adjacency_list<boost::vecS,
                              boost::vecS,
                              boost::undirectedS,
                              custom_property,
                              float> AdjacencyListCustom;

struct vertex_copier
{
    void operator() (uint32_t &input, custom_property &output)
    {
        output.label = input;
        output.f = 0.;
    }
};


int main(int argc, char** argv)
{
    AdjacencyList adj;
    VertexID id_0 = boost::add_vertex(0, adj);
    VertexID id_1 = boost::add_vertex(1, adj);
    VertexID id_2 = boost::add_vertex(2, adj);
    VertexID id_3 = boost::add_vertex(4, adj);
    boost::add_edge(id_0, id_1, 1.0f, adj);
    boost::add_edge(id_2, id_3, 2.0f, adj);

    AdjacencyListCustom adj_custom;
    boost::copy_graph(adj, adj_custom,  boost::vertex_copy(vertex_copier()));

}

g++编译错误

...
/usr/include/boost/graph/copy.hpp:164:22: error: no match for call to '(vertex_copier) (boost::iterators::detail::iterator_facade_base<boost::range_detail::integer_iterator<long unsigned int>, long unsigned int, boost::iterators::random_access_traversal_tag, long unsigned int, long int, false, false>::reference, boost::graph_traits<boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, custom_property, float> >::vertex_descriptor&)'
           copy_vertex(*vi, new_v);
           ~~~~~~~~~~~^~~~~~~~~~~~
/path/to/file.cpp: note: candidate: void vertex_copier::operator()(uint32_t&, custom_property&)
     void operator() (uint32_t &input, custom_property &output)
          ^~~~~~~~
/path/to/file.cpp: note:   no known conversion for argument 2 from 'boost::graph_traits<boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, custom_property, float> >::vertex_descriptor {aka long unsigned int}' to 'custom_property&'

这告诉我vertex_copy 实际上是在尝试复制vertex_descriptor,它是long unsigned int,而不是custom_property。这似乎与文档中的规定背道而驰:

这是一个二元函数,将原始图中某个顶点的属性复制到副本中对应的顶点中。

vertex_copy 是如何工作的?它可以用来设置/定义复制图中不在原始图中的顶点属性吗?如果不是,是否必须在复制后通过遍历图形来设置这些属性?我可以应用映射en masse 还是必须访问和更新每个顶点?

编辑: 如果我尝试使用copy_graph 而不指定vertex_copy,则会出现错误,因为= 运算符在custom_propertyuint32_t 之间不存在。

【问题讨论】:

    标签: c++ boost boost-graph


    【解决方案1】:

    暂时回避这个问题,实现事情的最简单方法是将适当的转换构造函数添加到自定义属性:

    struct custom_property {
        custom_property(uint32_t label = 0, float f = 0) : label(label), f(f) {}
        uint32_t label;
        float f;
    };
    

    在这种情况下,一个简单的副本将起作用:

    boost::copy_graph(adj, adj_custom);
    

    Live On Coliru


    关于顶点复制器,它接收顶点描述符。要访问顶点属性,您需要有图形参考:

    struct vertex_copier {
        AdjacencyList& from;
        AdjacencyListCustom& to;
    
        void operator()(AdjacencyList::vertex_descriptor input, AdjacencyListCustom::vertex_descriptor output) const {
            to[output] = { from[input], 0.f };
        }
    };
    

    在这种情况下你会调用一些东西:

    boost::copy_graph(adj, adj_custom, boost::vertex_copy(vertex_copier{adj, adj_custom}));
    

    再次,Live On Coliru

    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/copy.hpp>
    #include <iostream>
    
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, uint32_t, float> AdjacencyList;
    
    typedef AdjacencyList::vertex_descriptor VertexID;
    
        struct custom_property {
            //custom_property(uint32_t label = 0, float f = 0) : label(label), f(f) {}
            uint32_t label;
            float f;
        };
    
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, custom_property, float> AdjacencyListCustom;
    
    struct vertex_copier {
        AdjacencyList& from;
        AdjacencyListCustom& to;
    
        void operator()(AdjacencyList::vertex_descriptor input, AdjacencyListCustom::vertex_descriptor output) const {
            to[output] = { from[input], 0.f };
        }
    };
    
    int main(int argc, char **argv) {
        AdjacencyList adj;
        VertexID id_0 = boost::add_vertex(0, adj);
        VertexID id_1 = boost::add_vertex(1, adj);
        VertexID id_2 = boost::add_vertex(2, adj);
        VertexID id_3 = boost::add_vertex(4, adj);
        boost::add_edge(id_0, id_1, 1.0f, adj);
        boost::add_edge(id_2, id_3, 2.0f, adj);
    
        AdjacencyListCustom adj_custom;
        boost::copy_graph(adj, adj_custom, boost::vertex_copy(vertex_copier{adj, adj_custom}));
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      相关资源
      最近更新 更多