2010-05-18 17 views
1

我有一個圖表,其中包含頂點和邊的自定義屬性。我現在想創建這個圖的一個副本,但我不希望頂點的複雜程度與原始圖一樣複雜。通過這個,我的意思是,頂點具有與原始圖中相同的索引(vertex_index_t)就足夠了。
而是做手工拷貝的,我想使用boost的複製功能::的adjacency_list(S http://www.boost.org/doc/libs/1_37_0/libs/graph/doc/adjacency_list.html):用於Boost圖表(BGL)的自定義InputIterator

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)的範圍內。

不幸的是我不得不承認,我不太明白如何定義EdgeIterator是InputIterator的模型。
這裏是我到目前爲止succeded:

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

我遇到同樣的問題,我用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但至少這個解決方案工作。