File indexing completed on 2025-01-18 09:37:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifndef BOOST_GRAPH_COPY_HPP
0041 #define BOOST_GRAPH_COPY_HPP
0042
0043 #include <boost/config.hpp>
0044 #include <vector>
0045 #include <boost/graph/graph_traits.hpp>
0046 #include <boost/graph/reverse_graph.hpp>
0047 #include <boost/property_map/property_map.hpp>
0048 #include <boost/graph/named_function_params.hpp>
0049 #include <boost/graph/breadth_first_search.hpp>
0050 #include <boost/type_traits/conversion_traits.hpp>
0051
0052 namespace boost
0053 {
0054
0055 namespace detail
0056 {
0057
0058
0059 template < typename Graph, typename Desc >
0060 struct remove_reverse_edge_descriptor
0061 {
0062 typedef Desc type;
0063 static Desc convert(const Desc& d, const Graph&) { return d; }
0064 };
0065
0066 template < typename Graph, typename Desc >
0067 struct remove_reverse_edge_descriptor< Graph,
0068 reverse_graph_edge_descriptor< Desc > >
0069 {
0070 typedef Desc type;
0071 static Desc convert(
0072 const reverse_graph_edge_descriptor< Desc >& d, const Graph& g)
0073 {
0074 return get(edge_underlying, g, d);
0075 }
0076 };
0077
0078
0079
0080
0081
0082
0083 template < typename Desc, typename Graph >
0084 struct add_reverse_edge_descriptor
0085 {
0086 typedef Desc type;
0087 static Desc convert(const Desc& d) { return d; }
0088 };
0089
0090 template < typename Desc, typename G, typename GR >
0091 struct add_reverse_edge_descriptor< Desc, boost::reverse_graph< G, GR > >
0092 {
0093 typedef reverse_graph_edge_descriptor< Desc > type;
0094 static reverse_graph_edge_descriptor< Desc > convert(const Desc& d)
0095 {
0096 return reverse_graph_edge_descriptor< Desc >(d);
0097 }
0098 };
0099
0100 template < typename Desc, typename G, typename GR >
0101 struct add_reverse_edge_descriptor< reverse_graph_edge_descriptor< Desc >,
0102 boost::reverse_graph< G, GR > >
0103 {
0104 typedef reverse_graph_edge_descriptor< Desc > type;
0105 static reverse_graph_edge_descriptor< Desc > convert(
0106 const reverse_graph_edge_descriptor< Desc >& d)
0107 {
0108 return d;
0109 }
0110 };
0111
0112
0113
0114 template < typename Graph1, typename Graph2 > struct edge_copier
0115 {
0116 edge_copier(const Graph1& g1, Graph2& g2)
0117 : edge_all_map1(get(edge_all, g1)), edge_all_map2(get(edge_all, g2))
0118 {
0119 }
0120
0121 template < typename Edge1, typename Edge2 >
0122 void operator()(const Edge1& e1, Edge2& e2) const
0123 {
0124 put(edge_all_map2, e2,
0125 get(edge_all_map1,
0126 add_reverse_edge_descriptor< Edge1, Graph1 >::convert(e1)));
0127 }
0128 typename property_map< Graph1, edge_all_t >::const_type edge_all_map1;
0129 mutable typename property_map< Graph2, edge_all_t >::type edge_all_map2;
0130 };
0131 template < typename Graph1, typename Graph2 >
0132 inline edge_copier< Graph1, Graph2 > make_edge_copier(
0133 const Graph1& g1, Graph2& g2)
0134 {
0135 return edge_copier< Graph1, Graph2 >(g1, g2);
0136 }
0137
0138 template < typename Graph1, typename Graph2 > struct vertex_copier
0139 {
0140 vertex_copier(const Graph1& g1, Graph2& g2)
0141 : vertex_all_map1(get(vertex_all, g1))
0142 , vertex_all_map2(get(vertex_all, g2))
0143 {
0144 }
0145
0146 template < typename Vertex1, typename Vertex2 >
0147 void operator()(const Vertex1& v1, Vertex2& v2) const
0148 {
0149 put(vertex_all_map2, v2, get(vertex_all_map1, v1));
0150 }
0151 typename property_map< Graph1, vertex_all_t >::const_type
0152 vertex_all_map1;
0153 mutable
0154 typename property_map< Graph2, vertex_all_t >::type vertex_all_map2;
0155 };
0156 template < typename Graph1, typename Graph2 >
0157 inline vertex_copier< Graph1, Graph2 > make_vertex_copier(
0158 const Graph1& g1, Graph2& g2)
0159 {
0160 return vertex_copier< Graph1, Graph2 >(g1, g2);
0161 }
0162
0163
0164
0165
0166
0167 template < int Version > struct copy_graph_impl
0168 {
0169 };
0170
0171 template <> struct copy_graph_impl< 0 >
0172 {
0173 template < typename Graph, typename MutableGraph, typename CopyVertex,
0174 typename CopyEdge, typename IndexMap,
0175 typename Orig2CopyVertexIndexMap >
0176 static void apply(const Graph& g_in, MutableGraph& g_out,
0177 CopyVertex copy_vertex, CopyEdge copy_edge,
0178 Orig2CopyVertexIndexMap orig2copy, IndexMap)
0179 {
0180 typedef remove_reverse_edge_descriptor< Graph,
0181 typename graph_traits< Graph >::edge_descriptor >
0182 cvt;
0183 typename graph_traits< Graph >::vertex_iterator vi, vi_end;
0184 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
0185 {
0186 typename graph_traits< MutableGraph >::vertex_descriptor new_v
0187 = add_vertex(g_out);
0188 put(orig2copy, *vi, new_v);
0189 copy_vertex(*vi, new_v);
0190 }
0191 typename graph_traits< Graph >::edge_iterator ei, ei_end;
0192 for (boost::tie(ei, ei_end) = edges(g_in); ei != ei_end; ++ei)
0193 {
0194 typename graph_traits< MutableGraph >::edge_descriptor new_e;
0195 bool inserted;
0196 boost::tie(new_e, inserted)
0197 = add_edge(get(orig2copy, source(*ei, g_in)),
0198 get(orig2copy, target(*ei, g_in)), g_out);
0199 copy_edge(cvt::convert(*ei, g_in), new_e);
0200 }
0201 }
0202 };
0203
0204
0205 template <> struct copy_graph_impl< 1 >
0206 {
0207 template < typename Graph, typename MutableGraph, typename CopyVertex,
0208 typename CopyEdge, typename IndexMap,
0209 typename Orig2CopyVertexIndexMap >
0210 static void apply(const Graph& g_in, MutableGraph& g_out,
0211 CopyVertex copy_vertex, CopyEdge copy_edge,
0212 Orig2CopyVertexIndexMap orig2copy, IndexMap)
0213 {
0214 typedef remove_reverse_edge_descriptor< Graph,
0215 typename graph_traits< Graph >::edge_descriptor >
0216 cvt;
0217 typename graph_traits< Graph >::vertex_iterator vi, vi_end;
0218 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
0219 {
0220 typename graph_traits< MutableGraph >::vertex_descriptor new_v
0221 = add_vertex(g_out);
0222 put(orig2copy, *vi, new_v);
0223 copy_vertex(*vi, new_v);
0224 }
0225 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
0226 {
0227 typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
0228 for (boost::tie(ei, ei_end) = out_edges(*vi, g_in);
0229 ei != ei_end; ++ei)
0230 {
0231 typename graph_traits< MutableGraph >::edge_descriptor
0232 new_e;
0233 bool inserted;
0234 boost::tie(new_e, inserted)
0235 = add_edge(get(orig2copy, source(*ei, g_in)),
0236 get(orig2copy, target(*ei, g_in)), g_out);
0237 copy_edge(cvt::convert(*ei, g_in), new_e);
0238 }
0239 }
0240 }
0241 };
0242
0243
0244 template <> struct copy_graph_impl< 2 >
0245 {
0246 template < typename Graph, typename MutableGraph, typename CopyVertex,
0247 typename CopyEdge, typename IndexMap,
0248 typename Orig2CopyVertexIndexMap >
0249 static void apply(const Graph& g_in, MutableGraph& g_out,
0250 CopyVertex copy_vertex, CopyEdge copy_edge,
0251 Orig2CopyVertexIndexMap orig2copy, IndexMap index_map)
0252 {
0253 typedef remove_reverse_edge_descriptor< Graph,
0254 typename graph_traits< Graph >::edge_descriptor >
0255 cvt;
0256 typedef color_traits< default_color_type > Color;
0257 std::vector< default_color_type > color(
0258 num_vertices(g_in), Color::white());
0259 typename graph_traits< Graph >::vertex_iterator vi, vi_end;
0260 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
0261 {
0262 typename graph_traits< MutableGraph >::vertex_descriptor new_v
0263 = add_vertex(g_out);
0264 put(orig2copy, *vi, new_v);
0265 copy_vertex(*vi, new_v);
0266 }
0267 for (boost::tie(vi, vi_end) = vertices(g_in); vi != vi_end; ++vi)
0268 {
0269 typename graph_traits< Graph >::out_edge_iterator ei, ei_end;
0270 for (boost::tie(ei, ei_end) = out_edges(*vi, g_in);
0271 ei != ei_end; ++ei)
0272 {
0273 typename graph_traits< MutableGraph >::edge_descriptor
0274 new_e;
0275 bool inserted;
0276 if (color[get(index_map, target(*ei, g_in))]
0277 == Color::white())
0278 {
0279 boost::tie(new_e, inserted)
0280 = add_edge(get(orig2copy, source(*ei, g_in)),
0281 get(orig2copy, target(*ei, g_in)), g_out);
0282 copy_edge(cvt::convert(*ei, g_in), new_e);
0283 }
0284 }
0285 color[get(index_map, *vi)] = Color::black();
0286 }
0287 }
0288 };
0289
0290 template < class Graph > struct choose_graph_copy
0291 {
0292 typedef typename graph_traits< Graph >::traversal_category Trv;
0293 typedef typename graph_traits< Graph >::directed_category Dr;
0294 enum
0295 {
0296 algo = (is_convertible< Trv, vertex_list_graph_tag >::value
0297 && is_convertible< Trv, edge_list_graph_tag >::value)
0298 ? 0
0299 : is_convertible< Dr, directed_tag >::value ? 1 : 2
0300 };
0301 typedef copy_graph_impl< algo > type;
0302 };
0303
0304
0305 struct choose_copier_parameter
0306 {
0307 template < class P, class G1, class G2 > struct bind_
0308 {
0309 typedef const P& result_type;
0310 static result_type apply(const P& p, const G1&, G2&) { return p; }
0311 };
0312 };
0313 struct choose_default_edge_copier
0314 {
0315 template < class P, class G1, class G2 > struct bind_
0316 {
0317 typedef edge_copier< G1, G2 > result_type;
0318 static result_type apply(const P&, const G1& g1, G2& g2)
0319 {
0320 return result_type(g1, g2);
0321 }
0322 };
0323 };
0324 template < class Param > struct choose_edge_copy
0325 {
0326 typedef choose_copier_parameter type;
0327 };
0328 template <> struct choose_edge_copy< param_not_found >
0329 {
0330 typedef choose_default_edge_copier type;
0331 };
0332 template < class Param, class G1, class G2 >
0333 struct choose_edge_copier_helper
0334 {
0335 typedef typename choose_edge_copy< Param >::type Selector;
0336 typedef typename Selector::template bind_< Param, G1, G2 > Bind;
0337 typedef Bind type;
0338 typedef typename Bind::result_type result_type;
0339 };
0340 template < typename Param, typename G1, typename G2 >
0341 typename detail::choose_edge_copier_helper< Param, G1, G2 >::result_type
0342 choose_edge_copier(const Param& params, const G1& g_in, G2& g_out)
0343 {
0344 typedef
0345 typename detail::choose_edge_copier_helper< Param, G1, G2 >::type
0346 Choice;
0347 return Choice::apply(params, g_in, g_out);
0348 }
0349
0350 struct choose_default_vertex_copier
0351 {
0352 template < class P, class G1, class G2 > struct bind_
0353 {
0354 typedef vertex_copier< G1, G2 > result_type;
0355 static result_type apply(const P&, const G1& g1, G2& g2)
0356 {
0357 return result_type(g1, g2);
0358 }
0359 };
0360 };
0361 template < class Param > struct choose_vertex_copy
0362 {
0363 typedef choose_copier_parameter type;
0364 };
0365 template <> struct choose_vertex_copy< param_not_found >
0366 {
0367 typedef choose_default_vertex_copier type;
0368 };
0369 template < class Param, class G1, class G2 >
0370 struct choose_vertex_copier_helper
0371 {
0372 typedef typename choose_vertex_copy< Param >::type Selector;
0373 typedef typename Selector::template bind_< Param, G1, G2 > Bind;
0374 typedef Bind type;
0375 typedef typename Bind::result_type result_type;
0376 };
0377 template < typename Param, typename G1, typename G2 >
0378 typename detail::choose_vertex_copier_helper< Param, G1, G2 >::result_type
0379 choose_vertex_copier(const Param& params, const G1& g_in, G2& g_out)
0380 {
0381 typedef
0382 typename detail::choose_vertex_copier_helper< Param, G1, G2 >::type
0383 Choice;
0384 return Choice::apply(params, g_in, g_out);
0385 }
0386
0387 }
0388
0389 template < typename VertexListGraph, typename MutableGraph >
0390 void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out)
0391 {
0392 if (num_vertices(g_in) == 0)
0393 return;
0394 typedef typename graph_traits< MutableGraph >::vertex_descriptor vertex_t;
0395 std::vector< vertex_t > orig2copy(num_vertices(g_in));
0396 typedef
0397 typename detail::choose_graph_copy< VertexListGraph >::type copy_impl;
0398 copy_impl::apply(g_in, g_out, detail::make_vertex_copier(g_in, g_out),
0399 detail::make_edge_copier(g_in, g_out),
0400 make_iterator_property_map(
0401 orig2copy.begin(), get(vertex_index, g_in), orig2copy[0]),
0402 get(vertex_index, g_in));
0403 }
0404
0405 template < typename VertexListGraph, typename MutableGraph, class P, class T,
0406 class R >
0407 void copy_graph(const VertexListGraph& g_in, MutableGraph& g_out,
0408 const bgl_named_params< P, T, R >& params)
0409 {
0410 typename std::vector< T >::size_type n;
0411 n = is_default_param(get_param(params, orig_to_copy_t()))
0412 ? num_vertices(g_in)
0413 : 1;
0414 if (n == 0)
0415 return;
0416 std::vector<
0417 BOOST_DEDUCED_TYPENAME graph_traits< MutableGraph >::vertex_descriptor >
0418 orig2copy(n);
0419
0420 typedef
0421 typename detail::choose_graph_copy< VertexListGraph >::type copy_impl;
0422 copy_impl::apply(g_in, g_out,
0423 detail::choose_vertex_copier(
0424 get_param(params, vertex_copy_t()), g_in, g_out),
0425 detail::choose_edge_copier(
0426 get_param(params, edge_copy_t()), g_in, g_out),
0427 choose_param(get_param(params, orig_to_copy_t()),
0428 make_iterator_property_map(orig2copy.begin(),
0429 choose_const_pmap(
0430 get_param(params, vertex_index), g_in, vertex_index),
0431 orig2copy[0])),
0432 choose_const_pmap(get_param(params, vertex_index), g_in, vertex_index));
0433 }
0434
0435 namespace detail
0436 {
0437
0438 template < class NewGraph, class Copy2OrigIndexMap, class CopyVertex,
0439 class CopyEdge >
0440 struct graph_copy_visitor : public bfs_visitor<>
0441 {
0442 graph_copy_visitor(
0443 NewGraph& graph, Copy2OrigIndexMap c, CopyVertex cv, CopyEdge ce)
0444 : g_out(graph), orig2copy(c), copy_vertex(cv), copy_edge(ce)
0445 {
0446 }
0447
0448 template < class Vertex >
0449 typename graph_traits< NewGraph >::vertex_descriptor copy_one_vertex(
0450 Vertex u) const
0451 {
0452 typename graph_traits< NewGraph >::vertex_descriptor new_u
0453 = add_vertex(g_out);
0454 put(orig2copy, u, new_u);
0455 copy_vertex(u, new_u);
0456 return new_u;
0457 }
0458
0459 template < class Edge, class Graph >
0460 void tree_edge(Edge e, const Graph& g_in) const
0461 {
0462
0463 typename graph_traits< NewGraph >::edge_descriptor new_e;
0464 bool inserted;
0465 boost::tie(new_e, inserted)
0466 = add_edge(get(orig2copy, source(e, g_in)),
0467 this->copy_one_vertex(target(e, g_in)), g_out);
0468 copy_edge(e, new_e);
0469 }
0470
0471 template < class Edge, class Graph >
0472 void non_tree_edge(Edge e, const Graph& g_in) const
0473 {
0474
0475 typename graph_traits< NewGraph >::edge_descriptor new_e;
0476 bool inserted;
0477 boost::tie(new_e, inserted)
0478 = add_edge(get(orig2copy, source(e, g_in)),
0479 get(orig2copy, target(e, g_in)), g_out);
0480 copy_edge(e, new_e);
0481 }
0482
0483 private:
0484 NewGraph& g_out;
0485 Copy2OrigIndexMap orig2copy;
0486 CopyVertex copy_vertex;
0487 CopyEdge copy_edge;
0488 };
0489
0490 template < typename Graph, typename MutableGraph, typename CopyVertex,
0491 typename CopyEdge, typename Orig2CopyVertexIndexMap, typename Params >
0492 typename graph_traits< MutableGraph >::vertex_descriptor
0493 copy_component_impl(const Graph& g_in,
0494 typename graph_traits< Graph >::vertex_descriptor src,
0495 MutableGraph& g_out, CopyVertex copy_vertex, CopyEdge copy_edge,
0496 Orig2CopyVertexIndexMap orig2copy, const Params& params)
0497 {
0498 graph_copy_visitor< MutableGraph, Orig2CopyVertexIndexMap, CopyVertex,
0499 CopyEdge >
0500 vis(g_out, orig2copy, copy_vertex, copy_edge);
0501 typename graph_traits< MutableGraph >::vertex_descriptor src_copy
0502 = vis.copy_one_vertex(src);
0503 breadth_first_search(g_in, src, params.visitor(vis));
0504 return src_copy;
0505 }
0506
0507 }
0508
0509
0510
0511
0512 template < typename IncidenceGraph, typename MutableGraph, typename P,
0513 typename T, typename R >
0514 typename graph_traits< MutableGraph >::vertex_descriptor copy_component(
0515 IncidenceGraph& g_in,
0516 typename graph_traits< IncidenceGraph >::vertex_descriptor src,
0517 MutableGraph& g_out, const bgl_named_params< P, T, R >& params)
0518 {
0519 typename std::vector< T >::size_type n;
0520 n = is_default_param(get_param(params, orig_to_copy_t()))
0521 ? num_vertices(g_in)
0522 : 1;
0523 std::vector< typename graph_traits< IncidenceGraph >::vertex_descriptor >
0524 orig2copy(n);
0525
0526 return detail::copy_component_impl(g_in, src, g_out,
0527 detail::choose_vertex_copier(
0528 get_param(params, vertex_copy_t()), g_in, g_out),
0529 detail::choose_edge_copier(
0530 get_param(params, edge_copy_t()), g_in, g_out),
0531 choose_param(get_param(params, orig_to_copy_t()),
0532 make_iterator_property_map(orig2copy.begin(),
0533 choose_pmap(
0534 get_param(params, vertex_index), g_in, vertex_index),
0535 orig2copy[0])),
0536 params);
0537 }
0538
0539 template < typename IncidenceGraph, typename MutableGraph >
0540 typename graph_traits< MutableGraph >::vertex_descriptor copy_component(
0541 IncidenceGraph& g_in,
0542 typename graph_traits< IncidenceGraph >::vertex_descriptor src,
0543 MutableGraph& g_out)
0544 {
0545 std::vector< typename graph_traits< IncidenceGraph >::vertex_descriptor >
0546 orig2copy(num_vertices(g_in));
0547
0548 return detail::copy_component_impl(g_in, src, g_out,
0549 make_vertex_copier(g_in, g_out), make_edge_copier(g_in, g_out),
0550 make_iterator_property_map(
0551 orig2copy.begin(), get(vertex_index, g_in), orig2copy[0]),
0552 bgl_named_params< char, char >('x')
0553 );
0554 }
0555
0556 }
0557
0558 #endif