首页 文章

用于Boost图的自定义InputIterator(BGL)

提问于
浏览
1

我有一个图表,其中包含顶点和边的自定义属性 . 我现在想要创建此图的副本,但我不希望顶点像原始顶点一样复杂 . 我的意思是,顶点具有与原始图中相同的索引(vertex_index_t)就足够了 .
我没有手动复制,而是想使用boost :: adjacency_list(s . http://www.boost.org/doc/libs/1_37_0/libs/graph/doc/adjacency_list.html)的复制功能:

template <class EdgeIterator>
adjacency_list(EdgeIterator first, EdgeIterator last,
           vertices_size_type n,
           edges_size_type m = 0,
           const GraphProperty& p = GraphProperty())

那里的描述说:

EdgeIterator必须是InputIterator的模型 . EdgeIterator的值类型必须是std :: pair,其中对中的类型是整数类型 . 整数将对应于顶点,它们必须全部落在[0,n]的范围内 .

不幸的是,我不得不承认我不太了解如何定义作为InputIterator模型的EdgeIterator .
到目前为止's what I'成功了:

template< class EdgeIterator, class Edge >
class MyEdgeIterator// : public input_iterator< std::pair<int, int> > 
{
public:
        MyEdgeIterator() {}; 

        MyEdgeIterator(EdgeIterator& rhs) : actual_edge_it_(rhs) {}; 

        MyEdgeIterator(const MyEdgeIterator& to_copy) {}; 

        bool operator==(const MyEdgeIterator& to_compare)
        {   
                return actual_edge_it_ == to_compare.actual_edge_it_;
        }   

        bool operator!=(const MyEdgeIterator& to_compare)
        {   
                return !(*this == to_compare);
        }   

        Edge operator*() const
        {   
                return *actual_edge_it_;
        }

        const MyEdgeIterator* operator->() const;
        MyEdgeIterator& operator ++()
        {   
                ++actual_edge_it_;
                return *this;
        }   

        MyEdgeIterator operator ++(int)
        {   
                MyEdgeIterator<EdgeIterator, Edge> tmp = *this;
                ++*this;
                return tmp;
        }

private:
        EdgeIterator& actual_edge_it_;
}

然而,这并不像它应该的那样有效,而且我的线索已经用尽了 .
那么,我该如何定义合适的InputIterator呢?

1 回答

  • 1

    我遇到了同样的问题,我使用了来自boost的Transform Iterator .

    我实现了进行转换的copyGraph .

    例:

    SimpleGraphType simple = copyGraph<ComplexGraphType, SimpleGraphType>(complex);
    

    和代码:

    #include <boost/iterator/transform_iterator.hpp>
    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/graph_traits.hpp>
    #include <utility>
    
    template <class Graph>
    class EdgeToPair
    {
    public:
       typedef std::pair<int, int> result_type;
    
       typedef typename boost::graph_traits<Graph>::edge_iterator edge_iter;
       typedef typename std::iterator_traits<edge_iter>::value_type edge_type;
    
       EdgeToPair(const Graph& graph) : _graph(graph) {}
    
       std::pair<int, int> operator()(edge_type edge) const
       {
          return std::make_pair(boost::source(edge, _graph),
                                boost::target(edge, _graph));
       }
    
    private:
       const Graph& _graph;
    };
    
    template <class GraphIn, class GraphOut>
    GraphOut copyGraph(const GraphIn& graphIn)
    {
       EdgeToPair<GraphIn> edgeToPair(graphIn);
    
       typename boost::graph_traits<GraphIn>::edge_iterator ei, eend;
    
       boost::tie(ei, eend) = boost::edges(graphIn);
    
       return GraphOut(boost::make_transform_iterator(ei, edgeToPair),
                       boost::make_transform_iterator(eend, edgeToPair),
                       boost::num_vertices(graphIn));
    }
    

    我确信使用boost::copy_graph并通过传递自定义edge_copy存在更好的解决方案,但至少这个解决方案有效 .

相关问题