File indexing completed on 2025-01-18 09:37:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_FILTERED_GRAPH_HPP
0011 #define BOOST_FILTERED_GRAPH_HPP
0012
0013 #include <boost/graph/graph_traits.hpp>
0014 #include <boost/graph/properties.hpp>
0015 #include <boost/graph/adjacency_iterator.hpp>
0016 #include <boost/graph/detail/set_adaptor.hpp>
0017 #include <boost/iterator/filter_iterator.hpp>
0018
0019 namespace boost
0020 {
0021
0022
0023
0024
0025 struct keep_all
0026 {
0027 template < typename T > bool operator()(const T&) const { return true; }
0028 };
0029
0030
0031 template < typename ResidualCapacityEdgeMap > struct is_residual_edge
0032 {
0033 is_residual_edge() {}
0034 is_residual_edge(ResidualCapacityEdgeMap rcap) : m_rcap(rcap) {}
0035 template < typename Edge > bool operator()(const Edge& e) const
0036 {
0037 return 0 < get(m_rcap, e);
0038 }
0039 ResidualCapacityEdgeMap m_rcap;
0040 };
0041
0042 template < typename Set > struct is_in_subset
0043 {
0044 is_in_subset() : m_s(0) {}
0045 is_in_subset(const Set& s) : m_s(&s) {}
0046
0047 template < typename Elt > bool operator()(const Elt& x) const
0048 {
0049 return set_contains(*m_s, x);
0050 }
0051 const Set* m_s;
0052 };
0053
0054 template < typename Set > struct is_not_in_subset
0055 {
0056 is_not_in_subset() : m_s(0) {}
0057 is_not_in_subset(const Set& s) : m_s(&s) {}
0058
0059 template < typename Elt > bool operator()(const Elt& x) const
0060 {
0061 return !set_contains(*m_s, x);
0062 }
0063 const Set* m_s;
0064 };
0065
0066 namespace detail
0067 {
0068
0069 template < typename EdgePredicate, typename VertexPredicate,
0070 typename Graph >
0071 struct out_edge_predicate
0072 {
0073 out_edge_predicate() {}
0074 out_edge_predicate(EdgePredicate ep, VertexPredicate vp, const Graph& g)
0075 : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g)
0076 {
0077 }
0078
0079 template < typename Edge > bool operator()(const Edge& e) const
0080 {
0081 return m_edge_pred(e) && m_vertex_pred(target(e, *m_g));
0082 }
0083 EdgePredicate m_edge_pred;
0084 VertexPredicate m_vertex_pred;
0085 const Graph* m_g;
0086 };
0087
0088 template < typename EdgePredicate, typename VertexPredicate,
0089 typename Graph >
0090 struct in_edge_predicate
0091 {
0092 in_edge_predicate() {}
0093 in_edge_predicate(EdgePredicate ep, VertexPredicate vp, const Graph& g)
0094 : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g)
0095 {
0096 }
0097
0098 template < typename Edge > bool operator()(const Edge& e) const
0099 {
0100 return m_edge_pred(e) && m_vertex_pred(source(e, *m_g));
0101 }
0102 EdgePredicate m_edge_pred;
0103 VertexPredicate m_vertex_pred;
0104 const Graph* m_g;
0105 };
0106
0107 template < typename EdgePredicate, typename VertexPredicate,
0108 typename Graph >
0109 struct edge_predicate
0110 {
0111 edge_predicate() {}
0112 edge_predicate(EdgePredicate ep, VertexPredicate vp, const Graph& g)
0113 : m_edge_pred(ep), m_vertex_pred(vp), m_g(&g)
0114 {
0115 }
0116
0117 template < typename Edge > bool operator()(const Edge& e) const
0118 {
0119 return m_edge_pred(e) && m_vertex_pred(source(e, *m_g))
0120 && m_vertex_pred(target(e, *m_g));
0121 }
0122 EdgePredicate m_edge_pred;
0123 VertexPredicate m_vertex_pred;
0124 const Graph* m_g;
0125 };
0126
0127 }
0128
0129
0130
0131
0132 struct filtered_graph_tag
0133 {
0134 };
0135
0136
0137
0138
0139
0140 template < class G > struct filtered_graph_base
0141 {
0142 typedef graph_traits< G > Traits;
0143 typedef typename Traits::vertex_descriptor vertex_descriptor;
0144 typedef typename Traits::edge_descriptor edge_descriptor;
0145 filtered_graph_base(const G& g) : m_g(g) {}
0146
0147 const G& m_g;
0148 };
0149
0150 template < typename Graph, typename EdgePredicate,
0151 typename VertexPredicate = keep_all >
0152 class filtered_graph : public filtered_graph_base< Graph >
0153 {
0154 typedef filtered_graph_base< Graph > Base;
0155 typedef graph_traits< Graph > Traits;
0156 typedef filtered_graph self;
0157
0158 public:
0159 typedef Graph graph_type;
0160 typedef detail::out_edge_predicate< EdgePredicate, VertexPredicate, self >
0161 OutEdgePred;
0162 typedef detail::in_edge_predicate< EdgePredicate, VertexPredicate, self >
0163 InEdgePred;
0164 typedef detail::edge_predicate< EdgePredicate, VertexPredicate, self >
0165 EdgePred;
0166
0167
0168 filtered_graph(const Graph& g, EdgePredicate ep) : Base(g), m_edge_pred(ep)
0169 {
0170 }
0171
0172 filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp)
0173 : Base(g), m_edge_pred(ep), m_vertex_pred(vp)
0174 {
0175 }
0176
0177
0178 typedef typename Traits::vertex_descriptor vertex_descriptor;
0179 typedef typename Traits::edge_descriptor edge_descriptor;
0180 typedef typename Traits::directed_category directed_category;
0181 typedef typename Traits::edge_parallel_category edge_parallel_category;
0182 typedef typename Traits::traversal_category traversal_category;
0183
0184
0185 typedef filter_iterator< OutEdgePred, typename Traits::out_edge_iterator >
0186 out_edge_iterator;
0187
0188 typedef typename Traits::degree_size_type degree_size_type;
0189
0190
0191 typedef typename adjacency_iterator_generator< self, vertex_descriptor,
0192 out_edge_iterator >::type adjacency_iterator;
0193
0194
0195 typedef filter_iterator< InEdgePred, typename Traits::in_edge_iterator >
0196 in_edge_iterator;
0197
0198
0199 typedef filter_iterator< VertexPredicate, typename Traits::vertex_iterator >
0200 vertex_iterator;
0201 typedef typename Traits::vertices_size_type vertices_size_type;
0202
0203
0204 typedef filter_iterator< EdgePred, typename Traits::edge_iterator >
0205 edge_iterator;
0206 typedef typename Traits::edges_size_type edges_size_type;
0207
0208 typedef filtered_graph_tag graph_tag;
0209
0210
0211 template < typename Descriptor >
0212 typename graph::detail::bundled_result< Graph, Descriptor >::type&
0213 operator[](Descriptor x)
0214 {
0215 return const_cast< Graph& >(this->m_g)[x];
0216 }
0217
0218 template < typename Descriptor >
0219 typename graph::detail::bundled_result< Graph, Descriptor >::type const&
0220 operator[](Descriptor x) const
0221 {
0222 return this->m_g[x];
0223 }
0224
0225 static vertex_descriptor null_vertex() { return Traits::null_vertex(); }
0226
0227
0228 EdgePredicate m_edge_pred;
0229 VertexPredicate m_vertex_pred;
0230 };
0231
0232
0233 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0234 struct vertex_property_type<
0235 filtered_graph< Graph, EdgePredicate, VertexPredicate > >
0236 : vertex_property_type< Graph >
0237 {
0238 };
0239
0240 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0241 struct edge_property_type<
0242 filtered_graph< Graph, EdgePredicate, VertexPredicate > >
0243 : edge_property_type< Graph >
0244 {
0245 };
0246
0247 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0248 struct graph_property_type<
0249 filtered_graph< Graph, EdgePredicate, VertexPredicate > >
0250 : graph_property_type< Graph >
0251 {
0252 };
0253
0254 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0255 struct vertex_bundle_type<
0256 filtered_graph< Graph, EdgePredicate, VertexPredicate > >
0257 : vertex_bundle_type< Graph >
0258 {
0259 };
0260
0261 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0262 struct edge_bundle_type<
0263 filtered_graph< Graph, EdgePredicate, VertexPredicate > >
0264 : edge_bundle_type< Graph >
0265 {
0266 };
0267
0268 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0269 struct graph_bundle_type<
0270 filtered_graph< Graph, EdgePredicate, VertexPredicate > >
0271 : graph_bundle_type< Graph >
0272 {
0273 };
0274
0275
0276
0277
0278
0279 template < typename Graph, typename EdgePredicate >
0280 inline filtered_graph< Graph, EdgePredicate > make_filtered_graph(
0281 Graph& g, EdgePredicate ep)
0282 {
0283 return filtered_graph< Graph, EdgePredicate >(g, ep);
0284 }
0285 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0286 inline filtered_graph< Graph, EdgePredicate, VertexPredicate >
0287 make_filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp)
0288 {
0289 return filtered_graph< Graph, EdgePredicate, VertexPredicate >(g, ep, vp);
0290 }
0291
0292 template < typename Graph, typename EdgePredicate >
0293 inline filtered_graph< const Graph, EdgePredicate > make_filtered_graph(
0294 const Graph& g, EdgePredicate ep)
0295 {
0296 return filtered_graph< const Graph, EdgePredicate >(g, ep);
0297 }
0298 template < typename Graph, typename EdgePredicate, typename VertexPredicate >
0299 inline filtered_graph< const Graph, EdgePredicate, VertexPredicate >
0300 make_filtered_graph(const Graph& g, EdgePredicate ep, VertexPredicate vp)
0301 {
0302 return filtered_graph< const Graph, EdgePredicate, VertexPredicate >(
0303 g, ep, vp);
0304 }
0305
0306 template < typename G, typename EP, typename VP >
0307 std::pair< typename filtered_graph< G, EP, VP >::vertex_iterator,
0308 typename filtered_graph< G, EP, VP >::vertex_iterator >
0309 vertices(const filtered_graph< G, EP, VP >& g)
0310 {
0311 typedef filtered_graph< G, EP, VP > Graph;
0312 typename graph_traits< G >::vertex_iterator f, l;
0313 boost::tie(f, l) = vertices(g.m_g);
0314 typedef typename Graph::vertex_iterator iter;
0315 return std::make_pair(
0316 iter(g.m_vertex_pred, f, l), iter(g.m_vertex_pred, l, l));
0317 }
0318
0319 template < typename G, typename EP, typename VP >
0320 std::pair< typename filtered_graph< G, EP, VP >::edge_iterator,
0321 typename filtered_graph< G, EP, VP >::edge_iterator >
0322 edges(const filtered_graph< G, EP, VP >& g)
0323 {
0324 typedef filtered_graph< G, EP, VP > Graph;
0325 typename Graph::EdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
0326 typename graph_traits< G >::edge_iterator f, l;
0327 boost::tie(f, l) = edges(g.m_g);
0328 typedef typename Graph::edge_iterator iter;
0329 return std::make_pair(iter(pred, f, l), iter(pred, l, l));
0330 }
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 template < typename G, typename EP, typename VP >
0346 typename filtered_graph< G, EP, VP >::vertices_size_type num_vertices(
0347 const filtered_graph< G, EP, VP >& g)
0348 {
0349 return num_vertices(g.m_g);
0350 }
0351
0352 template < typename G, typename EP, typename VP >
0353 typename filtered_graph< G, EP, VP >::edges_size_type num_edges(
0354 const filtered_graph< G, EP, VP >& g)
0355 {
0356 return num_edges(g.m_g);
0357 }
0358
0359 template < typename G >
0360 typename filtered_graph_base< G >::vertex_descriptor source(
0361 typename filtered_graph_base< G >::edge_descriptor e,
0362 const filtered_graph_base< G >& g)
0363 {
0364 return source(e, g.m_g);
0365 }
0366
0367 template < typename G >
0368 typename filtered_graph_base< G >::vertex_descriptor target(
0369 typename filtered_graph_base< G >::edge_descriptor e,
0370 const filtered_graph_base< G >& g)
0371 {
0372 return target(e, g.m_g);
0373 }
0374
0375 template < typename G, typename EP, typename VP >
0376 std::pair< typename filtered_graph< G, EP, VP >::out_edge_iterator,
0377 typename filtered_graph< G, EP, VP >::out_edge_iterator >
0378 out_edges(typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0379 const filtered_graph< G, EP, VP >& g)
0380 {
0381 typedef filtered_graph< G, EP, VP > Graph;
0382 typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
0383 typedef typename Graph::out_edge_iterator iter;
0384 typename graph_traits< G >::out_edge_iterator f, l;
0385 boost::tie(f, l) = out_edges(u, g.m_g);
0386 return std::make_pair(iter(pred, f, l), iter(pred, l, l));
0387 }
0388
0389 template < typename G, typename EP, typename VP >
0390 typename filtered_graph< G, EP, VP >::degree_size_type out_degree(
0391 typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0392 const filtered_graph< G, EP, VP >& g)
0393 {
0394 typename filtered_graph< G, EP, VP >::degree_size_type n = 0;
0395 typename filtered_graph< G, EP, VP >::out_edge_iterator f, l;
0396 for (boost::tie(f, l) = out_edges(u, g); f != l; ++f)
0397 ++n;
0398 return n;
0399 }
0400
0401 template < typename G, typename EP, typename VP >
0402 std::pair< typename filtered_graph< G, EP, VP >::adjacency_iterator,
0403 typename filtered_graph< G, EP, VP >::adjacency_iterator >
0404 adjacent_vertices(typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0405 const filtered_graph< G, EP, VP >& g)
0406 {
0407 typedef filtered_graph< G, EP, VP > Graph;
0408 typedef typename Graph::adjacency_iterator adjacency_iterator;
0409 typename Graph::out_edge_iterator f, l;
0410 boost::tie(f, l) = out_edges(u, g);
0411 return std::make_pair(adjacency_iterator(f, const_cast< Graph* >(&g)),
0412 adjacency_iterator(l, const_cast< Graph* >(&g)));
0413 }
0414
0415 template < typename G, typename EP, typename VP >
0416 std::pair< typename filtered_graph< G, EP, VP >::in_edge_iterator,
0417 typename filtered_graph< G, EP, VP >::in_edge_iterator >
0418 in_edges(typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0419 const filtered_graph< G, EP, VP >& g)
0420 {
0421 typedef filtered_graph< G, EP, VP > Graph;
0422 typename Graph::InEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
0423 typedef typename Graph::in_edge_iterator iter;
0424 typename graph_traits< G >::in_edge_iterator f, l;
0425 boost::tie(f, l) = in_edges(u, g.m_g);
0426 return std::make_pair(iter(pred, f, l), iter(pred, l, l));
0427 }
0428
0429 template < typename G, typename EP, typename VP >
0430 typename filtered_graph< G, EP, VP >::degree_size_type in_degree(
0431 typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0432 const filtered_graph< G, EP, VP >& g)
0433 {
0434 typename filtered_graph< G, EP, VP >::degree_size_type n = 0;
0435 typename filtered_graph< G, EP, VP >::in_edge_iterator f, l;
0436 for (boost::tie(f, l) = in_edges(u, g); f != l; ++f)
0437 ++n;
0438 return n;
0439 }
0440
0441 template < typename G, typename EP, typename VP >
0442 typename enable_if< typename is_directed_graph< G >::type,
0443 typename filtered_graph< G, EP, VP >::degree_size_type >::type
0444 degree(typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0445 const filtered_graph< G, EP, VP >& g)
0446 {
0447 return out_degree(u, g) + in_degree(u, g);
0448 }
0449
0450 template < typename G, typename EP, typename VP >
0451 typename disable_if< typename is_directed_graph< G >::type,
0452 typename filtered_graph< G, EP, VP >::degree_size_type >::type
0453 degree(typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0454 const filtered_graph< G, EP, VP >& g)
0455 {
0456 return out_degree(u, g);
0457 }
0458
0459 template < typename G, typename EP, typename VP >
0460 std::pair< typename filtered_graph< G, EP, VP >::edge_descriptor, bool > edge(
0461 typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0462 typename filtered_graph< G, EP, VP >::vertex_descriptor v,
0463 const filtered_graph< G, EP, VP >& g)
0464 {
0465 typename graph_traits< G >::edge_descriptor e;
0466 bool exists;
0467 boost::tie(e, exists) = edge(u, v, g.m_g);
0468 return std::make_pair(e, exists && g.m_edge_pred(e));
0469 }
0470
0471 template < typename G, typename EP, typename VP >
0472 std::pair< typename filtered_graph< G, EP, VP >::out_edge_iterator,
0473 typename filtered_graph< G, EP, VP >::out_edge_iterator >
0474 edge_range(typename filtered_graph< G, EP, VP >::vertex_descriptor u,
0475 typename filtered_graph< G, EP, VP >::vertex_descriptor v,
0476 const filtered_graph< G, EP, VP >& g)
0477 {
0478 typedef filtered_graph< G, EP, VP > Graph;
0479 typename Graph::OutEdgePred pred(g.m_edge_pred, g.m_vertex_pred, g);
0480 typedef typename Graph::out_edge_iterator iter;
0481 typename graph_traits< G >::out_edge_iterator f, l;
0482 boost::tie(f, l) = edge_range(u, v, g.m_g);
0483 return std::make_pair(iter(pred, f, l), iter(pred, l, l));
0484 }
0485
0486
0487
0488
0489 template < typename G, typename EP, typename VP, typename Property >
0490 struct property_map< filtered_graph< G, EP, VP >, Property >
0491 : property_map< G, Property >
0492 {
0493 };
0494
0495 template < typename G, typename EP, typename VP, typename Property >
0496 typename property_map< G, Property >::type get(
0497 Property p, filtered_graph< G, EP, VP >& g)
0498 {
0499 return get(p, const_cast< G& >(g.m_g));
0500 }
0501
0502 template < typename G, typename EP, typename VP, typename Property >
0503 typename property_map< G, Property >::const_type get(
0504 Property p, const filtered_graph< G, EP, VP >& g)
0505 {
0506 return get(p, (const G&)g.m_g);
0507 }
0508
0509 template < typename G, typename EP, typename VP, typename Property,
0510 typename Key >
0511 typename property_map_value< G, Property >::type get(
0512 Property p, const filtered_graph< G, EP, VP >& g, const Key& k)
0513 {
0514 return get(p, (const G&)g.m_g, k);
0515 }
0516
0517 template < typename G, typename EP, typename VP, typename Property,
0518 typename Key, typename Value >
0519 void put(Property p, const filtered_graph< G, EP, VP >& g, const Key& k,
0520 const Value& val)
0521 {
0522 put(p, const_cast< G& >(g.m_g), k, val);
0523 }
0524
0525
0526
0527
0528 template < typename Graph, typename Set > struct vertex_subset_filter
0529 {
0530 typedef filtered_graph< Graph, keep_all, is_in_subset< Set > > type;
0531 };
0532 template < typename Graph, typename Set >
0533 inline typename vertex_subset_filter< Graph, Set >::type
0534 make_vertex_subset_filter(Graph& g, const Set& s)
0535 {
0536 typedef typename vertex_subset_filter< Graph, Set >::type Filter;
0537 is_in_subset< Set > p(s);
0538 return Filter(g, keep_all(), p);
0539 }
0540
0541
0542
0543 template < typename Graph, typename Set > struct vertex_subset_compliment_filter
0544 {
0545 typedef filtered_graph< Graph, keep_all, is_not_in_subset< Set > > type;
0546 };
0547 template < typename Graph, typename Set >
0548 inline typename vertex_subset_compliment_filter< Graph, Set >::type
0549 make_vertex_subset_compliment_filter(Graph& g, const Set& s)
0550 {
0551 typedef typename vertex_subset_compliment_filter< Graph, Set >::type Filter;
0552 is_not_in_subset< Set > p(s);
0553 return Filter(g, keep_all(), p);
0554 }
0555
0556 template < typename Graph, typename Set > struct vertex_subset_complement_filter
0557 {
0558 typedef filtered_graph< Graph, keep_all, is_not_in_subset< Set > > type;
0559 };
0560 template < typename Graph, typename Set >
0561 inline typename vertex_subset_complement_filter< Graph, Set >::type
0562 make_vertex_subset_complement_filter(Graph& g, const Set& s)
0563 {
0564 typedef typename vertex_subset_complement_filter< Graph, Set >::type Filter;
0565 is_not_in_subset< Set > p(s);
0566 return Filter(g, keep_all(), p);
0567 }
0568
0569
0570 template < typename PropertyMap > struct property_map_filter
0571 {
0572
0573 property_map_filter() {}
0574
0575 property_map_filter(const PropertyMap& property_map)
0576 : m_property_map(property_map)
0577 {
0578 }
0579
0580 template < typename Key > bool operator()(const Key& key) const
0581 {
0582 return (get(m_property_map, key));
0583 }
0584
0585 private:
0586 PropertyMap m_property_map;
0587 };
0588
0589 }
0590
0591 #endif