[英]Custom InputIterator for Boost graph (BGL)
I have a graph with custom properties to the vertices and edges. 我有一个具有自定义属性的图的顶点和边缘。 I now want to create a copy of this graph, but I don't want the vertices to be as complex as in the original. 现在,我想创建该图的副本,但我不希望顶点像原始图一样复杂。 By this I mean that it would suffice that the vertices have the same indices (vertex_index_t) as they do in the original graph. 我的意思是,与原始图中的顶点具有相同的索引(vertex_index_t)就足够了。
Instead of doing the copying by hand I wanted to use the copy-functionality of boost::adjacency_list (s. http://www.boost.org/doc/libs/1_37_0/libs/graph/doc/adjacency_list.html ): 我不想使用手工复制功能,而是想使用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())
The description there says: 那里的说明说:
The EdgeIterator must be a model of InputIterator. EdgeIterator必须是InputIterator的模型。 The value type of the EdgeIterator must be a std::pair, where the type in the pair is an integer type. EdgeIterator的值类型必须为std :: pair,其中对中的类型为整数类型。 The integers will correspond to vertices, and they must all fall in the range of [0, n). 整数将对应于顶点,并且它们都必须都在[0,n)范围内。
Unfortunately I have to admit that I don't quite get it how to define an EdgeIterator that is a model of InputIterator. 不幸的是,我不得不承认我并没有完全了解如何定义作为InputIterator模型的EdgeIterator。
Here's what I've succeded so far: 到目前为止,这是我成功执行的操作:
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_;
}
However, this doesn't work as it is supposed to and I ran out of clues. 但是,这没有按预期的方式工作,我没有任何线索。
So, how do I define the appropriate InputIterator? 那么,如何定义适当的InputIterator?
I encounter the same problem and I used Transform Iterator from boost. 我遇到了同样的问题,我从boost使用了Transform Iterator 。
I implemented copyGraph that does the conversion. 我实现了执行转换的copyGraph。
Example: 例:
SimpleGraphType simple = copyGraph<ComplexGraphType, SimpleGraphType>(complex);
And the code: 和代码:
#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));
}
I'm sure there exists a better solution using boost::copy_graph and by passing a custom edge_copy but at least this solution works. 我确信使用boost :: copy_graph并通过传递自定义edge_copy存在更好的解决方案,但至少此解决方案有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.