filtered_graph<Graph, EdgePredicate, VertexPredicate>
这个filtered_graph类模板是一个适配器,用于创建图的过滤视图。谓词函数对象决定了原始图的哪些边和顶点将显示在过滤图中。如果边谓词返回true对于一条边,则它会显示在过滤图中;如果谓词返回false则该边不会出现在过滤图中。顶点也是如此。这个filtered_graph类不会创建原始图的副本,而是使用对原始图的引用。原始图的生命周期必须超过对过滤图的任何使用。过滤图不会更改原始图的结构,但原始图的顶点和边属性可以通过过滤图的属性映射来更改。过滤图的顶点和边描述符与原始图的顶点和边描述符相同且可互换。
num_vertices 和 num_edges 函数在返回结果之前不进行过滤,因此它们返回底层图中未过滤的顶点或边的数量 [2]。
在这个示例中,我们将基于边权重过滤图的边。我们将保留所有具有正边权重的边。首先,我们创建一个谓词函数对象。
template <typename EdgeWeightMap> struct positive_edge_weight { positive_edge_weight() { } positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) { } template <typename Edge> bool operator()(const Edge& e) const { return 0 < get(m_weight, e); } EdgeWeightMap m_weight; };现在我们创建一个图并打印输出过滤图。
int main() { using namespace boost; typedef adjacency_list<vecS, vecS, directedS, no_property, property<edge_weight_t, int> > Graph; typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap; enum { A, B, C, D, E, N }; const char* name = "ABCDE"; Graph g(N); add_edge(A, B, 2, g); add_edge(A, C, 0, g); add_edge(C, D, 1, g); add_edge(C, E, 0, g); add_edge(D, B, 3, g); add_edge(E, C, 0, g); positive_edge_weight<EdgeWeightMap> filter(get(edge_weight, g)); filtered_graph<Graph, positive_edge_weight<EdgeWeightMap> > fg(g, filter); std::cout << "filtered edge set: "; print_edges(fg, name); std::cout << "filtered out-edges:" << std::endl; print_graph(fg, name); return 0; }输出是
filtered edge set: (A,B) (C,D) (D,B) filtered out-edges: A --> B B --> C --> D D --> B E -->
参数 | 描述 | 默认值 |
---|---|---|
图 | 底层图类型。 | |
边谓词 | 一个函数对象,用于选择原始图中哪些边将出现在过滤图中。该函数对象必须符合 Predicate 模型。函数对象的参数类型必须是图的边描述符类型。此外,该谓词必须是 Default Constructible 模型 [1]。 | |
顶点谓词 | 一个函数对象,用于选择原始图中哪些顶点将出现在过滤图中。该函数对象必须符合 Predicate 模型。函数对象的参数类型必须是图的顶点描述符类型。此外,该谓词必须是 Default Constructible 模型 [1]。 | keep_all |
这取决于底层图类型。如果底层图类型符合 VertexAndEdgeListGraph 和 PropertyGraph 模型,则过滤图也符合。如果底层图类型符合比这些更少或更小的概念,则过滤图也符合。
boost/graph/filtered_graph.hpp
filter_iterator<VertexPredicate, graph_traits<Graph>::vertex_iterator>该迭代器是 MultiPassInputIterator 的模型。
filter_iterator<EdgePredicate, graph_traits<Graph>::edge_iterator>该迭代器是 MultiPassInputIterator 的模型。
filter_iterator<EdgePredicate, graph_traits<Graph>::out_edge_iterator>该迭代器是 MultiPassInputIterator 的模型。
filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp)基于图 g 以及边过滤器 ep 和顶点过滤器 vp 创建一个过滤图。
filtered_graph(Graph& g, EdgePredicate ep)基于图 g 和边过滤器 ep 创建一个过滤图。原始图中的所有顶点都将被保留。
filtered_graph& operator=(const filtered_graph& x)这会为与 x 相同的底层图创建一个过滤图。换句话说,这是一个浅拷贝。
std::pair<vertex_iterator, vertex_iterator> vertices(const filtered_graph& g)返回一个迭代器范围,提供对图的顶点集的访问g.
std::pair<edge_iterator, edge_iterator> edges(const filtered_graph& g)返回一个迭代器范围,提供对图的边集的访问g.
std::pair<adjacency_iterator, adjacency_iterator> adjacent_vertices(vertex_descriptor u, const filtered_graph& g)返回一个迭代器范围,提供对顶点相邻顶点的访问u在图中g.
std::pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor u, const filtered_graph& g)返回一个迭代器范围,提供对顶点出边的访问u在图中g。 如果图是无向图,则此迭代器范围提供对顶点上所有关联边的访问u。 对于有向图和无向图,对于出边e, source(e, g) == u和target(e, g) == v其中v是与...相邻的顶点u.
std::pair<in_edge_iterator, in_edge_iterator> in_edges(vertex_descriptor v, const filtered_graph& g)返回一个迭代器范围,提供对顶点入边的访问v在图中g。 对于入边e, target(e, g) == v和source(e, g) == u对于某些顶点u,它与...相邻v,无论图是有向图还是无向图。
vertex_descriptor source(edge_descriptor e, const filtered_graph& g)返回边的源顶点e.
vertex_descriptor target(edge_descriptor e, const filtered_graph& g)返回边的目标顶点e.
degree_size_type out_degree(vertex_descriptor u, const filtered_graph& g)返回离开顶点的边数u.
degree_size_type in_degree(vertex_descriptor u, const filtered_graph& g)返回进入顶点的边数u.
vertices_size_type num_vertices(const filtered_graph& g)返回底层图中顶点的数量 [2]。
edges_size_type num_edges(const filtered_graph& g)返回底层图中边的数量 [2]。
std::pair<edge_descriptor, bool> edge(vertex_descriptor u, vertex_descriptor v, const filtered_graph& g)返回连接顶点的边u到顶点v在图中g.
template <typename G, typename EP, typename VP> std::pair<out_edge_iterator, out_edge_iterator> edge_range(vertex_descriptor u, vertex_descriptor v, const filtered_graph& g)返回一对出边迭代器,它们给出了从...到...的所有平行边的范围u到v。 此函数仅在底层图支持edge_range时才有效,这要求它根据目标顶点对其出边进行排序并允许平行边。adjacency_list类,其中OutEdgeList=multisetS是这种图的一个示例。
template <class PropertyTag> property_map<filtered_graph, PropertyTag>::type get(PropertyTag, filtered_graph& g) template <class PropertyTag> property_map<filtered_graph, Tag>::const_type get(PropertyTag, const filtered_graph& g)返回由以下项指定的顶点属性的属性映射对象PropertyTag。 该PropertyTag必须匹配图中指定的属性之一VertexProperty模板参数。
template <class PropertyTag, class X> typename property_traits<property_map<filtered_graph, PropertyTag>::const_type>::value_type get(PropertyTag, const filtered_graph& g, X x)这将返回...的属性值x,其中x是顶点或边描述符。
template <class PropertyTag, class X, class Value> void put(PropertyTag, const filtered_graph& g, X x, const Value& value)这将设置...的属性值x到value. x是顶点或边描述符。Value必须可转换为typename property_traits<property_map<filtered_graph, PropertyTag>::type>::value_type
[1] 在以下项中要求 Default Constructible 的原因是边谓词和顶点谓词类型的原因是,这些谓词在过滤器迭代器适配器中按值存储(出于性能原因),并且 C++ 标准要求迭代器是默认可构造的。
[2] 如果返回应用过滤器后剩余的顶点(或边)的数量会更好,但这有两个问题。第一个是计算时间会更长,第二个是它会与底层的顶点/边索引映射产生不良的交互。索引映射将不再落入以下范围[0,num_vertices(g))(分别是[0, num_edges(g))),这在许多算法中是假设的。
版权所有 © 2000-2001 |
Jeremy Siek,印第安纳大学(jsiek@osl.iu.edu) 李列权,印第安纳大学(llee@cs.indiana.edu) Andrew Lumsdaine,印第安纳大学(lums@osl.iu.edu) |