2010-05-18 2 views
1

У меня есть график с настраиваемыми свойствами для вершин и ребер. Теперь я хочу создать копию этого графика, но я не хочу, чтобы вершины были такими же сложными, как в оригинале. Под этим я подразумеваю, что будет достаточно, чтобы вершины имели одинаковые индексы (vertex_index_t), как и в исходном графе.
Вместо того, чтобы делать копирование вручную, я хотел использовать копировальную-функциональность повышения :: adjacency_list (ы http://www.boost.org/doc/libs/1_37_0/libs/graph/doc/adjacency_list.html.):Пользовательский InputIterator для диаграммы Boost (BGL)

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.
Вот что я до сих пор преуспели:

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

У меня такая же проблема, и я использовал Transform Iterator от boost.

Я реализовал 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 но по крайней мере это решение работает.

Смежные вопросы