Пользовательский InputIterator для графа Boost (BGL) - PullRequest
1 голос
/ 18 мая 2010

У меня есть график с пользовательскими свойствами для вершин и ребер. Теперь я хочу создать копию этого графа, но я не хочу, чтобы вершины были такими же сложными, как в оригинале. Под этим я подразумеваю, что будет достаточно, чтобы вершины имели те же индексы (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).

К сожалению, я должен признать, что я не совсем понимаю, как определить 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 Ответ

1 голос
/ 30 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...