subgraph.hpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. //=======================================================================
  2. // Copyright 2001 University of Notre Dame.
  3. // Authors: Jeremy G. Siek and Lie-Quan Lee
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #ifndef BOOST_SUBGRAPH_HPP
  10. #define BOOST_SUBGRAPH_HPP
  11. // UNDER CONSTRUCTION
  12. #include <boost/config.hpp>
  13. #include <list>
  14. #include <vector>
  15. #include <map>
  16. #include <boost/assert.hpp>
  17. #include <boost/graph/graph_traits.hpp>
  18. #include <boost/graph/graph_mutability_traits.hpp>
  19. #include <boost/graph/properties.hpp>
  20. #include <boost/iterator/indirect_iterator.hpp>
  21. #include <boost/static_assert.hpp>
  22. #include <boost/assert.hpp>
  23. #include <boost/type_traits.hpp>
  24. #include <boost/mpl/if.hpp>
  25. #include <boost/mpl/or.hpp>
  26. namespace boost {
  27. struct subgraph_tag { };
  28. /** @name Property Lookup
  29. * The local_property and global_property functions are used to create
  30. * structures that determine the lookup strategy for properties in subgraphs.
  31. * Note that the nested kind member is used to help interoperate with actual
  32. * Property types.
  33. */
  34. //@{
  35. template <typename T>
  36. struct local_property
  37. {
  38. typedef T kind;
  39. local_property(T x) : value(x) { }
  40. T value;
  41. };
  42. template <typename T>
  43. inline local_property<T> local(T x)
  44. { return local_property<T>(x); }
  45. template <typename T>
  46. struct global_property
  47. {
  48. typedef T kind;
  49. global_property(T x) : value(x) { }
  50. T value;
  51. };
  52. template <typename T>
  53. inline global_property<T> global(T x)
  54. { return global_property<T>(x); }
  55. //@}
  56. // Invariants of an induced subgraph:
  57. // - If vertex u is in subgraph g, then u must be in g.parent().
  58. // - If edge e is in subgraph g, then e must be in g.parent().
  59. // - If edge e=(u,v) is in the root graph, then edge e
  60. // is also in any subgraph that contains both vertex u and v.
  61. // The Graph template parameter must have a vertex_index and edge_index
  62. // internal property. It is assumed that the vertex indices are assigned
  63. // automatically by the graph during a call to add_vertex(). It is not
  64. // assumed that the edge vertices are assigned automatically, they are
  65. // explicitly assigned here.
  66. template <typename Graph>
  67. class subgraph {
  68. typedef graph_traits<Graph> Traits;
  69. typedef std::list<subgraph<Graph>*> ChildrenList;
  70. public:
  71. // Graph requirements
  72. typedef typename Traits::vertex_descriptor vertex_descriptor;
  73. typedef typename Traits::edge_descriptor edge_descriptor;
  74. typedef typename Traits::directed_category directed_category;
  75. typedef typename Traits::edge_parallel_category edge_parallel_category;
  76. typedef typename Traits::traversal_category traversal_category;
  77. // IncidenceGraph requirements
  78. typedef typename Traits::out_edge_iterator out_edge_iterator;
  79. typedef typename Traits::degree_size_type degree_size_type;
  80. // AdjacencyGraph requirements
  81. typedef typename Traits::adjacency_iterator adjacency_iterator;
  82. // VertexListGraph requirements
  83. typedef typename Traits::vertex_iterator vertex_iterator;
  84. typedef typename Traits::vertices_size_type vertices_size_type;
  85. // EdgeListGraph requirements
  86. typedef typename Traits::edge_iterator edge_iterator;
  87. typedef typename Traits::edges_size_type edges_size_type;
  88. typedef typename Traits::in_edge_iterator in_edge_iterator;
  89. typedef typename edge_property_type<Graph>::type edge_property_type;
  90. typedef typename vertex_property_type<Graph>::type vertex_property_type;
  91. typedef subgraph_tag graph_tag;
  92. typedef Graph graph_type;
  93. typedef typename graph_property_type<Graph>::type graph_property_type;
  94. // Create the main graph, the root of the subgraph tree
  95. subgraph()
  96. : m_parent(0), m_edge_counter(0)
  97. { }
  98. subgraph(const graph_property_type& p)
  99. : m_graph(p), m_parent(0), m_edge_counter(0)
  100. { }
  101. subgraph(vertices_size_type n, const graph_property_type& p = graph_property_type())
  102. : m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n)
  103. {
  104. typename Graph::vertex_iterator v, v_end;
  105. vertices_size_type i = 0;
  106. for(boost::tie(v, v_end) = vertices(m_graph); v != v_end; ++v)
  107. m_global_vertex[i++] = *v;
  108. }
  109. // copy constructor
  110. subgraph(const subgraph& x)
  111. : m_parent(x.m_parent), m_edge_counter(0)
  112. {
  113. if(x.is_root())
  114. {
  115. m_graph = x.m_graph;
  116. m_edge_counter = x.m_edge_counter;
  117. m_global_vertex = x.m_global_vertex;
  118. m_global_edge = x.m_global_edge;
  119. }
  120. else
  121. {
  122. get_property(*this) = get_property(x);
  123. typename subgraph<Graph>::vertex_iterator vi,vi_end;
  124. boost::tie(vi, vi_end) = vertices(x);
  125. for(; vi != vi_end; ++vi)
  126. {
  127. add_vertex(x.local_to_global(*vi), *this);
  128. }
  129. }
  130. // Do a deep copy (recursive).
  131. // Only the root graph is copied, the subgraphs contain
  132. // only references to the global vertices they own.
  133. typename subgraph<Graph>::children_iterator i,i_end;
  134. boost::tie(i,i_end) = x.children();
  135. for(; i != i_end; ++i)
  136. {
  137. m_children.push_back(new subgraph<Graph>(*i));
  138. m_children.back()->m_parent = this;
  139. }
  140. }
  141. ~subgraph() {
  142. for(typename ChildrenList::iterator i = m_children.begin();
  143. i != m_children.end(); ++i)
  144. {
  145. delete *i;
  146. }
  147. }
  148. // Return a null vertex descriptor for the graph.
  149. static vertex_descriptor null_vertex()
  150. { return Traits::null_vertex(); }
  151. // Create a subgraph
  152. subgraph<Graph>& create_subgraph() {
  153. m_children.push_back(new subgraph<Graph>());
  154. m_children.back()->m_parent = this;
  155. return *m_children.back();
  156. }
  157. // Create a subgraph with the specified vertex set.
  158. template <typename VertexIterator>
  159. subgraph<Graph>& create_subgraph(VertexIterator first, VertexIterator last) {
  160. m_children.push_back(new subgraph<Graph>());
  161. m_children.back()->m_parent = this;
  162. for(; first != last; ++first) {
  163. add_vertex(*first, *m_children.back());
  164. }
  165. return *m_children.back();
  166. }
  167. // local <-> global descriptor conversion functions
  168. vertex_descriptor local_to_global(vertex_descriptor u_local) const
  169. { return is_root() ? u_local : m_global_vertex[u_local]; }
  170. vertex_descriptor global_to_local(vertex_descriptor u_global) const {
  171. vertex_descriptor u_local; bool in_subgraph;
  172. if (is_root()) return u_global;
  173. boost::tie(u_local, in_subgraph) = this->find_vertex(u_global);
  174. BOOST_ASSERT(in_subgraph == true);
  175. return u_local;
  176. }
  177. edge_descriptor local_to_global(edge_descriptor e_local) const
  178. { return is_root() ? e_local : m_global_edge[get(get(edge_index, m_graph), e_local)]; }
  179. edge_descriptor global_to_local(edge_descriptor e_global) const
  180. { return is_root() ? e_global : (*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second; }
  181. // Is vertex u (of the root graph) contained in this subgraph?
  182. // If so, return the matching local vertex.
  183. std::pair<vertex_descriptor, bool>
  184. find_vertex(vertex_descriptor u_global) const {
  185. if (is_root()) return std::make_pair(u_global, true);
  186. typename LocalVertexMap::const_iterator i = m_local_vertex.find(u_global);
  187. bool valid = i != m_local_vertex.end();
  188. return std::make_pair((valid ? (*i).second : null_vertex()), valid);
  189. }
  190. // Is edge e (of the root graph) contained in this subgraph?
  191. // If so, return the matching local edge.
  192. std::pair<edge_descriptor, bool>
  193. find_edge(edge_descriptor e_global) const {
  194. if (is_root()) return std::make_pair(e_global, true);
  195. typename LocalEdgeMap::const_iterator i =
  196. m_local_edge.find(get(get(edge_index, root().m_graph), e_global));
  197. bool valid = i != m_local_edge.end();
  198. return std::make_pair((valid ? (*i).second : edge_descriptor()), valid);
  199. }
  200. // Return the parent graph.
  201. subgraph& parent() { return *m_parent; }
  202. const subgraph& parent() const { return *m_parent; }
  203. // Return true if this is the root subgraph
  204. bool is_root() const { return m_parent == 0; }
  205. // Return the root graph of the subgraph tree.
  206. subgraph& root()
  207. { return is_root() ? *this : m_parent->root(); }
  208. const subgraph& root() const
  209. { return is_root() ? *this : m_parent->root(); }
  210. // Return the children subgraphs of this graph/subgraph.
  211. // Use a list of pointers because the VC++ std::list doesn't like
  212. // storing incomplete type.
  213. typedef indirect_iterator<
  214. typename ChildrenList::const_iterator
  215. , subgraph<Graph>
  216. , std::bidirectional_iterator_tag
  217. >
  218. children_iterator;
  219. typedef indirect_iterator<
  220. typename ChildrenList::const_iterator
  221. , subgraph<Graph> const
  222. , std::bidirectional_iterator_tag
  223. >
  224. const_children_iterator;
  225. std::pair<const_children_iterator, const_children_iterator> children() const {
  226. return std::make_pair(const_children_iterator(m_children.begin()),
  227. const_children_iterator(m_children.end()));
  228. }
  229. std::pair<children_iterator, children_iterator> children() {
  230. return std::make_pair(children_iterator(m_children.begin()),
  231. children_iterator(m_children.end()));
  232. }
  233. std::size_t num_children() const { return m_children.size(); }
  234. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  235. // Defualt property access delegates the lookup to global properties.
  236. template <typename Descriptor>
  237. typename graph::detail::bundled_result<Graph, Descriptor>::type&
  238. operator[](Descriptor x)
  239. { return is_root() ? m_graph[x] : root().m_graph[local_to_global(x)]; }
  240. template <typename Descriptor>
  241. typename graph::detail::bundled_result<Graph, Descriptor>::type const&
  242. operator[](Descriptor x) const
  243. { return is_root() ? m_graph[x] : root().m_graph[local_to_global(x)]; }
  244. // Local property access returns the local property of the given descripor.
  245. template <typename Descriptor>
  246. typename graph::detail::bundled_result<Graph, Descriptor>::type&
  247. operator[](local_property<Descriptor> x)
  248. { return m_graph[x.value]; }
  249. template <typename Descriptor>
  250. typename graph::detail::bundled_result<Graph, Descriptor>::type const&
  251. operator[](local_property<Descriptor> x) const
  252. { return m_graph[x.value]; }
  253. // Global property access returns the global property associated with the
  254. // given descriptor. This is an alias for the default bundled property
  255. // access operations.
  256. template <typename Descriptor>
  257. typename graph::detail::bundled_result<Graph, Descriptor>::type&
  258. operator[](global_property<Descriptor> x)
  259. { return (*this)[x.value]; }
  260. template <typename Descriptor>
  261. typename graph::detail::bundled_result<Graph, Descriptor>::type const&
  262. operator[](global_property<Descriptor> x) const
  263. { return (*this)[x.value]; }
  264. #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  265. // private:
  266. typedef typename property_map<Graph, edge_index_t>::type EdgeIndexMap;
  267. typedef typename property_traits<EdgeIndexMap>::value_type edge_index_type;
  268. BOOST_STATIC_ASSERT((!is_same<edge_index_type,
  269. boost::detail::error_property_not_found>::value));
  270. private:
  271. typedef std::vector<vertex_descriptor> GlobalVertexList;
  272. typedef std::vector<edge_descriptor> GlobalEdgeList;
  273. typedef std::map<vertex_descriptor, vertex_descriptor> LocalVertexMap;
  274. typedef std::map<edge_index_type, edge_descriptor> LocalEdgeMap;
  275. // TODO: Should the LocalVertexMap be: map<index_type, descriptor>?
  276. // TODO: Can we relax the indexing requirement if both descriptors are
  277. // LessThanComparable?
  278. // TODO: Should we really be using unorderd_map for improved lookup times?
  279. public: // Probably shouldn't be public....
  280. Graph m_graph;
  281. subgraph<Graph>* m_parent;
  282. edge_index_type m_edge_counter; // for generating unique edge indices
  283. ChildrenList m_children;
  284. GlobalVertexList m_global_vertex; // local -> global
  285. LocalVertexMap m_local_vertex; // global -> local
  286. GlobalEdgeList m_global_edge; // local -> global
  287. LocalEdgeMap m_local_edge; // global -> local
  288. edge_descriptor local_add_edge(vertex_descriptor u_local,
  289. vertex_descriptor v_local,
  290. edge_descriptor e_global)
  291. {
  292. edge_descriptor e_local;
  293. bool inserted;
  294. boost::tie(e_local, inserted) = add_edge(u_local, v_local, m_graph);
  295. put(edge_index, m_graph, e_local, m_edge_counter++);
  296. m_global_edge.push_back(e_global);
  297. m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local;
  298. return e_local;
  299. }
  300. };
  301. template <typename Graph>
  302. struct vertex_bundle_type<subgraph<Graph> >
  303. : vertex_bundle_type<Graph>
  304. { };
  305. template<typename Graph>
  306. struct edge_bundle_type<subgraph<Graph> >
  307. : edge_bundle_type<Graph>
  308. { };
  309. template<typename Graph>
  310. struct graph_bundle_type<subgraph<Graph> >
  311. : graph_bundle_type<Graph>
  312. { };
  313. //===========================================================================
  314. // Functions special to the Subgraph Class
  315. template <typename G>
  316. typename subgraph<G>::vertex_descriptor
  317. add_vertex(typename subgraph<G>::vertex_descriptor u_global,
  318. subgraph<G>& g)
  319. {
  320. BOOST_ASSERT(!g.is_root());
  321. typename subgraph<G>::vertex_descriptor u_local;
  322. bool exists_local;
  323. boost::tie(u_local, exists_local) = g.find_vertex(u_global);
  324. if (!exists_local) {
  325. typename subgraph<G>::vertex_descriptor v_global;
  326. typename subgraph<G>::edge_descriptor e_global;
  327. // call recursion for parent subgraph
  328. if (!g.parent().is_root())
  329. add_vertex(u_global, g.parent());
  330. u_local = add_vertex(g.m_graph);
  331. g.m_global_vertex.push_back(u_global);
  332. g.m_local_vertex[u_global] = u_local;
  333. subgraph<G>& r = g.root();
  334. // remember edge global and local maps
  335. {
  336. typename subgraph<G>::out_edge_iterator ei, ei_end;
  337. for (boost::tie(ei, ei_end) = out_edges(u_global, r);
  338. ei != ei_end; ++ei) {
  339. e_global = *ei;
  340. v_global = target(e_global, r);
  341. if (g.find_vertex(v_global).second == true)
  342. g.local_add_edge(u_local, g.global_to_local(v_global), e_global);
  343. }
  344. }
  345. if (is_directed(g)) { // not necessary for undirected graph
  346. typename subgraph<G>::vertex_iterator vi, vi_end;
  347. typename subgraph<G>::out_edge_iterator ei, ei_end;
  348. for(boost::tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {
  349. v_global = *vi;
  350. if (v_global == u_global)
  351. continue; // don't insert self loops twice!
  352. if (!g.find_vertex(v_global).second)
  353. continue; // not a subgraph vertex => try next one
  354. for(boost::tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {
  355. e_global = *ei;
  356. if(target(e_global, r) == u_global) {
  357. g.local_add_edge(g.global_to_local(v_global), u_local, e_global);
  358. }
  359. }
  360. }
  361. }
  362. }
  363. return u_local;
  364. }
  365. // NOTE: Descriptors are local unless otherwise noted.
  366. //===========================================================================
  367. // Functions required by the IncidenceGraph concept
  368. template <typename G>
  369. std::pair<typename graph_traits<G>::out_edge_iterator,
  370. typename graph_traits<G>::out_edge_iterator>
  371. out_edges(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
  372. { return out_edges(v, g.m_graph); }
  373. template <typename G>
  374. typename graph_traits<G>::degree_size_type
  375. out_degree(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
  376. { return out_degree(v, g.m_graph); }
  377. template <typename G>
  378. typename graph_traits<G>::vertex_descriptor
  379. source(typename graph_traits<G>::edge_descriptor e, const subgraph<G>& g)
  380. { return source(e, g.m_graph); }
  381. template <typename G>
  382. typename graph_traits<G>::vertex_descriptor
  383. target(typename graph_traits<G>::edge_descriptor e, const subgraph<G>& g)
  384. { return target(e, g.m_graph); }
  385. //===========================================================================
  386. // Functions required by the BidirectionalGraph concept
  387. template <typename G>
  388. std::pair<typename graph_traits<G>::in_edge_iterator,
  389. typename graph_traits<G>::in_edge_iterator>
  390. in_edges(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
  391. { return in_edges(v, g.m_graph); }
  392. template <typename G>
  393. typename graph_traits<G>::degree_size_type
  394. in_degree(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
  395. { return in_degree(v, g.m_graph); }
  396. template <typename G>
  397. typename graph_traits<G>::degree_size_type
  398. degree(typename graph_traits<G>::vertex_descriptor v, const subgraph<G>& g)
  399. { return degree(v, g.m_graph); }
  400. //===========================================================================
  401. // Functions required by the AdjacencyGraph concept
  402. template <typename G>
  403. std::pair<typename subgraph<G>::adjacency_iterator,
  404. typename subgraph<G>::adjacency_iterator>
  405. adjacent_vertices(typename subgraph<G>::vertex_descriptor v, const subgraph<G>& g)
  406. { return adjacent_vertices(v, g.m_graph); }
  407. //===========================================================================
  408. // Functions required by the VertexListGraph concept
  409. template <typename G>
  410. std::pair<typename subgraph<G>::vertex_iterator,
  411. typename subgraph<G>::vertex_iterator>
  412. vertices(const subgraph<G>& g)
  413. { return vertices(g.m_graph); }
  414. template <typename G>
  415. typename subgraph<G>::vertices_size_type
  416. num_vertices(const subgraph<G>& g)
  417. { return num_vertices(g.m_graph); }
  418. //===========================================================================
  419. // Functions required by the EdgeListGraph concept
  420. template <typename G>
  421. std::pair<typename subgraph<G>::edge_iterator,
  422. typename subgraph<G>::edge_iterator>
  423. edges(const subgraph<G>& g)
  424. { return edges(g.m_graph); }
  425. template <typename G>
  426. typename subgraph<G>::edges_size_type
  427. num_edges(const subgraph<G>& g)
  428. { return num_edges(g.m_graph); }
  429. //===========================================================================
  430. // Functions required by the AdjacencyMatrix concept
  431. template <typename G>
  432. std::pair<typename subgraph<G>::edge_descriptor, bool>
  433. edge(typename subgraph<G>::vertex_descriptor u,
  434. typename subgraph<G>::vertex_descriptor v,
  435. const subgraph<G>& g)
  436. { return edge(u, v, g.m_graph); }
  437. //===========================================================================
  438. // Functions required by the MutableGraph concept
  439. namespace detail {
  440. template <typename Vertex, typename Edge, typename Graph>
  441. void add_edge_recur_down(Vertex u_global, Vertex v_global, Edge e_global,
  442. subgraph<Graph>& g);
  443. template <typename Vertex, typename Edge, typename Children, typename G>
  444. void children_add_edge(Vertex u_global, Vertex v_global, Edge e_global,
  445. Children& c, subgraph<G>* orig)
  446. {
  447. for(typename Children::iterator i = c.begin(); i != c.end(); ++i) {
  448. if ((*i)->find_vertex(u_global).second &&
  449. (*i)->find_vertex(v_global).second)
  450. {
  451. add_edge_recur_down(u_global, v_global, e_global, **i, orig);
  452. }
  453. }
  454. }
  455. template <typename Vertex, typename Edge, typename Graph>
  456. void add_edge_recur_down(Vertex u_global, Vertex v_global, Edge e_global,
  457. subgraph<Graph>& g, subgraph<Graph>* orig)
  458. {
  459. if(&g != orig ) {
  460. // add local edge only if u_global and v_global are in subgraph g
  461. Vertex u_local, v_local;
  462. bool u_in_subgraph, v_in_subgraph;
  463. boost::tie(u_local, u_in_subgraph) = g.find_vertex(u_global);
  464. boost::tie(v_local, v_in_subgraph) = g.find_vertex(v_global);
  465. if(u_in_subgraph && v_in_subgraph) {
  466. g.local_add_edge(u_local, v_local, e_global);
  467. }
  468. }
  469. children_add_edge(u_global, v_global, e_global, g.m_children, orig);
  470. }
  471. template <typename Vertex, typename Graph>
  472. std::pair<typename subgraph<Graph>::edge_descriptor, bool>
  473. add_edge_recur_up(Vertex u_global, Vertex v_global,
  474. const typename Graph::edge_property_type& ep,
  475. subgraph<Graph>& g, subgraph<Graph>* orig)
  476. {
  477. if(g.is_root()) {
  478. typename subgraph<Graph>::edge_descriptor e_global;
  479. bool inserted;
  480. boost::tie(e_global, inserted) = add_edge(u_global, v_global, ep, g.m_graph);
  481. put(edge_index, g.m_graph, e_global, g.m_edge_counter++);
  482. g.m_global_edge.push_back(e_global);
  483. children_add_edge(u_global, v_global, e_global, g.m_children, orig);
  484. return std::make_pair(e_global, inserted);
  485. } else {
  486. return add_edge_recur_up(u_global, v_global, ep, *g.m_parent, orig);
  487. }
  488. }
  489. } // namespace detail
  490. // Add an edge to the subgraph g, specified by the local vertex descriptors u
  491. // and v. In addition, the edge will be added to any (all) other subgraphs that
  492. // contain vertex descriptors u and v.
  493. template <typename G>
  494. std::pair<typename subgraph<G>::edge_descriptor, bool>
  495. add_edge(typename subgraph<G>::vertex_descriptor u,
  496. typename subgraph<G>::vertex_descriptor v,
  497. const typename G::edge_property_type& ep,
  498. subgraph<G>& g)
  499. {
  500. if (g.is_root()) {
  501. // u and v are really global
  502. return detail::add_edge_recur_up(u, v, ep, g, &g);
  503. } else {
  504. typename subgraph<G>::edge_descriptor e_local, e_global;
  505. bool inserted;
  506. boost::tie(e_global, inserted) =
  507. detail::add_edge_recur_up(g.local_to_global(u),
  508. g.local_to_global(v),
  509. ep, g, &g);
  510. e_local = g.local_add_edge(u, v, e_global);
  511. return std::make_pair(e_local, inserted);
  512. }
  513. }
  514. template <typename G>
  515. std::pair<typename subgraph<G>::edge_descriptor, bool>
  516. add_edge(typename subgraph<G>::vertex_descriptor u,
  517. typename subgraph<G>::vertex_descriptor v,
  518. subgraph<G>& g)
  519. { return add_edge(u, v, typename G::edge_property_type(), g); }
  520. namespace detail {
  521. //-------------------------------------------------------------------------
  522. // implementation of remove_edge(u,v,g)
  523. template <typename Vertex, typename Graph>
  524. void remove_edge_recur_down(Vertex u_global, Vertex v_global,
  525. subgraph<Graph>& g);
  526. template <typename Vertex, typename Children>
  527. void children_remove_edge(Vertex u_global, Vertex v_global,
  528. Children& c)
  529. {
  530. for(typename Children::iterator i = c.begin(); i != c.end(); ++i) {
  531. if((*i)->find_vertex(u_global).second &&
  532. (*i)->find_vertex(v_global).second)
  533. {
  534. remove_edge_recur_down(u_global, v_global, **i);
  535. }
  536. }
  537. }
  538. template <typename Vertex, typename Graph>
  539. void remove_edge_recur_down(Vertex u_global, Vertex v_global,
  540. subgraph<Graph>& g)
  541. {
  542. Vertex u_local, v_local;
  543. u_local = g.m_local_vertex[u_global];
  544. v_local = g.m_local_vertex[v_global];
  545. remove_edge(u_local, v_local, g.m_graph);
  546. children_remove_edge(u_global, v_global, g.m_children);
  547. }
  548. template <typename Vertex, typename Graph>
  549. void remove_edge_recur_up(Vertex u_global, Vertex v_global,
  550. subgraph<Graph>& g)
  551. {
  552. if(g.is_root()) {
  553. remove_edge(u_global, v_global, g.m_graph);
  554. children_remove_edge(u_global, v_global, g.m_children);
  555. } else {
  556. remove_edge_recur_up(u_global, v_global, *g.m_parent);
  557. }
  558. }
  559. //-------------------------------------------------------------------------
  560. // implementation of remove_edge(e,g)
  561. template <typename G, typename Edge, typename Children>
  562. void children_remove_edge(Edge e_global, Children& c)
  563. {
  564. for(typename Children::iterator i = c.begin(); i != c.end(); ++i) {
  565. std::pair<typename subgraph<G>::edge_descriptor, bool> found =
  566. (*i)->find_edge(e_global);
  567. if (!found.second) {
  568. continue;
  569. }
  570. children_remove_edge<G>(e_global, (*i)->m_children);
  571. remove_edge(found.first, (*i)->m_graph);
  572. }
  573. }
  574. } // namespace detail
  575. template <typename G>
  576. void
  577. remove_edge(typename subgraph<G>::vertex_descriptor u,
  578. typename subgraph<G>::vertex_descriptor v,
  579. subgraph<G>& g)
  580. {
  581. if(g.is_root()) {
  582. detail::remove_edge_recur_up(u, v, g);
  583. } else {
  584. detail::remove_edge_recur_up(g.local_to_global(u),
  585. g.local_to_global(v), g);
  586. }
  587. }
  588. template <typename G>
  589. void
  590. remove_edge(typename subgraph<G>::edge_descriptor e, subgraph<G>& g)
  591. {
  592. typename subgraph<G>::edge_descriptor e_global = g.local_to_global(e);
  593. #ifndef NDEBUG
  594. std::pair<typename subgraph<G>::edge_descriptor, bool> fe = g.find_edge(e_global);
  595. BOOST_ASSERT(fe.second && fe.first == e);
  596. #endif //NDEBUG
  597. subgraph<G> &root = g.root(); // chase to root
  598. detail::children_remove_edge<G>(e_global, root.m_children);
  599. remove_edge(e_global, root.m_graph); // kick edge from root
  600. }
  601. // This is slow, but there may not be a good way to do it safely otherwise
  602. template <typename Predicate, typename G>
  603. void
  604. remove_edge_if(Predicate p, subgraph<G>& g) {
  605. while (true) {
  606. bool any_removed = false;
  607. typedef typename subgraph<G>::edge_iterator ei_type;
  608. for (std::pair<ei_type, ei_type> ep = edges(g);
  609. ep.first != ep.second; ++ep.first) {
  610. if (p(*ep.first)) {
  611. any_removed = true;
  612. remove_edge(*ep.first, g);
  613. break; /* Since iterators may be invalidated */
  614. }
  615. }
  616. if (!any_removed) break;
  617. }
  618. }
  619. template <typename G>
  620. void
  621. clear_vertex(typename subgraph<G>::vertex_descriptor v, subgraph<G>& g) {
  622. while (true) {
  623. typedef typename subgraph<G>::out_edge_iterator oei_type;
  624. std::pair<oei_type, oei_type> p = out_edges(v, g);
  625. if (p.first == p.second) break;
  626. remove_edge(*p.first, g);
  627. }
  628. }
  629. namespace detail {
  630. template <typename G>
  631. typename subgraph<G>::vertex_descriptor
  632. add_vertex_recur_up(subgraph<G>& g)
  633. {
  634. typename subgraph<G>::vertex_descriptor u_local, u_global;
  635. if (g.is_root()) {
  636. u_global = add_vertex(g.m_graph);
  637. g.m_global_vertex.push_back(u_global);
  638. } else {
  639. u_global = add_vertex_recur_up(*g.m_parent);
  640. u_local = add_vertex(g.m_graph);
  641. g.m_global_vertex.push_back(u_global);
  642. g.m_local_vertex[u_global] = u_local;
  643. }
  644. return u_global;
  645. }
  646. } // namespace detail
  647. template <typename G>
  648. typename subgraph<G>::vertex_descriptor
  649. add_vertex(subgraph<G>& g)
  650. {
  651. typename subgraph<G>::vertex_descriptor u_local, u_global;
  652. if(g.is_root()) {
  653. u_global = add_vertex(g.m_graph);
  654. g.m_global_vertex.push_back(u_global);
  655. u_local = u_global;
  656. } else {
  657. u_global = detail::add_vertex_recur_up(g.parent());
  658. u_local = add_vertex(g.m_graph);
  659. g.m_global_vertex.push_back(u_global);
  660. g.m_local_vertex[u_global] = u_local;
  661. }
  662. return u_local;
  663. }
  664. #if 0
  665. // TODO: Under Construction
  666. template <typename G>
  667. void remove_vertex(typename subgraph<G>::vertex_descriptor u, subgraph<G>& g)
  668. { BOOST_ASSERT(false); }
  669. #endif
  670. //===========================================================================
  671. // Functions required by the PropertyGraph concept
  672. /**
  673. * The global property map returns the global properties associated with local
  674. * descriptors.
  675. */
  676. template <typename GraphPtr, typename PropertyMap, typename Tag>
  677. class subgraph_global_property_map
  678. : public put_get_helper<
  679. typename property_traits<PropertyMap>::reference,
  680. subgraph_global_property_map<GraphPtr, PropertyMap, Tag>
  681. >
  682. {
  683. typedef property_traits<PropertyMap> Traits;
  684. public:
  685. typedef typename mpl::if_<is_const<typename remove_pointer<GraphPtr>::type>,
  686. readable_property_map_tag,
  687. typename Traits::category>::type
  688. category;
  689. typedef typename Traits::value_type value_type;
  690. typedef typename Traits::key_type key_type;
  691. typedef typename Traits::reference reference;
  692. subgraph_global_property_map()
  693. { }
  694. subgraph_global_property_map(GraphPtr g, Tag tag)
  695. : m_g(g), m_tag(tag)
  696. { }
  697. reference operator[](key_type e) const {
  698. PropertyMap pmap = get(m_tag, m_g->root().m_graph);
  699. return m_g->is_root()
  700. ? pmap[e]
  701. : pmap[m_g->local_to_global(e)];
  702. }
  703. GraphPtr m_g;
  704. Tag m_tag;
  705. };
  706. /**
  707. * The local property map returns the local property associated with the local
  708. * descriptors.
  709. */
  710. template <typename GraphPtr, typename PropertyMap, typename Tag>
  711. class subgraph_local_property_map
  712. : public put_get_helper<
  713. typename property_traits<PropertyMap>::reference,
  714. subgraph_local_property_map<GraphPtr, PropertyMap, Tag>
  715. >
  716. {
  717. typedef property_traits<PropertyMap> Traits;
  718. public:
  719. typedef typename mpl::if_<is_const<typename remove_pointer<GraphPtr>::type>,
  720. readable_property_map_tag,
  721. typename Traits::category>::type
  722. category;
  723. typedef typename Traits::value_type value_type;
  724. typedef typename Traits::key_type key_type;
  725. typedef typename Traits::reference reference;
  726. typedef Tag tag;
  727. typedef PropertyMap pmap;
  728. subgraph_local_property_map()
  729. { }
  730. subgraph_local_property_map(GraphPtr g, Tag tag)
  731. : m_g(g), m_tag(tag)
  732. { }
  733. reference operator[](key_type e) const {
  734. // Get property map on the underlying graph.
  735. PropertyMap pmap = get(m_tag, m_g->m_graph);
  736. return pmap[e];
  737. }
  738. GraphPtr m_g;
  739. Tag m_tag;
  740. };
  741. namespace detail {
  742. // Extract the actual tags from local or global property maps so we don't
  743. // try to find non-properties.
  744. template <typename P> struct extract_lg_tag { typedef P type; };
  745. template <typename P> struct extract_lg_tag< local_property<P> > {
  746. typedef P type;
  747. };
  748. template <typename P> struct extract_lg_tag< global_property<P> > {
  749. typedef P type;
  750. };
  751. // NOTE: Mysterious Property template parameter unused in both metafunction
  752. // classes.
  753. struct subgraph_global_pmap {
  754. template <class Tag, class SubGraph, class Property>
  755. struct bind_ {
  756. typedef typename SubGraph::graph_type Graph;
  757. typedef SubGraph* SubGraphPtr;
  758. typedef const SubGraph* const_SubGraphPtr;
  759. typedef typename extract_lg_tag<Tag>::type TagType;
  760. typedef typename property_map<Graph, TagType>::type PMap;
  761. typedef typename property_map<Graph, TagType>::const_type const_PMap;
  762. public:
  763. typedef subgraph_global_property_map<SubGraphPtr, PMap, TagType> type;
  764. typedef subgraph_global_property_map<const_SubGraphPtr, const_PMap, TagType>
  765. const_type;
  766. };
  767. };
  768. struct subgraph_local_pmap {
  769. template <class Tag, class SubGraph, class Property>
  770. struct bind_ {
  771. typedef typename SubGraph::graph_type Graph;
  772. typedef SubGraph* SubGraphPtr;
  773. typedef const SubGraph* const_SubGraphPtr;
  774. typedef typename extract_lg_tag<Tag>::type TagType;
  775. typedef typename property_map<Graph, TagType>::type PMap;
  776. typedef typename property_map<Graph, TagType>::const_type const_PMap;
  777. public:
  778. typedef subgraph_local_property_map<SubGraphPtr, PMap, TagType> type;
  779. typedef subgraph_local_property_map<const_SubGraphPtr, const_PMap, TagType>
  780. const_type;
  781. };
  782. };
  783. // These metafunctions select the corresponding metafunctions above, and
  784. // are used by the choose_pmap metafunction below to specialize the choice
  785. // of local/global property map. By default, we defer to the global
  786. // property.
  787. template <class Tag>
  788. struct subgraph_choose_pmap_helper {
  789. typedef subgraph_global_pmap type;
  790. };
  791. template <class Tag>
  792. struct subgraph_choose_pmap_helper< local_property<Tag> > {
  793. typedef subgraph_local_pmap type;
  794. };
  795. template <class Tag>
  796. struct subgraph_choose_pmap_helper< global_property<Tag> > {
  797. typedef subgraph_global_pmap type;
  798. };
  799. // As above, unless we're requesting vertex_index_t. Then it's always a
  800. // local property map. This enables the correct translation of descriptors
  801. // between local and global layers.
  802. template <>
  803. struct subgraph_choose_pmap_helper<vertex_index_t> {
  804. typedef subgraph_local_pmap type;
  805. };
  806. template <>
  807. struct subgraph_choose_pmap_helper< local_property<vertex_index_t> > {
  808. typedef subgraph_local_pmap type;
  809. };
  810. template <>
  811. struct subgraph_choose_pmap_helper< global_property<vertex_index_t> > {
  812. typedef subgraph_local_pmap type;
  813. };
  814. // Determine the kind of property. If SameType<Tag, vertex_index_t>, then
  815. // the property lookup is always local. Otherwise, the lookup is global.
  816. // NOTE: Property parameter is basically unused.
  817. template <class Tag, class Graph, class Property>
  818. struct subgraph_choose_pmap {
  819. typedef typename subgraph_choose_pmap_helper<Tag>::type Helper;
  820. typedef typename Helper::template bind_<Tag, Graph, Property> Bind;
  821. typedef typename Bind::type type;
  822. typedef typename Bind::const_type const_type;
  823. };
  824. // Used by the vertex/edge property selectors to determine the kind(s) of
  825. // property maps used by the property_map type generator.
  826. struct subgraph_property_generator {
  827. template <class SubGraph, class Property, class Tag>
  828. struct bind_ {
  829. typedef subgraph_choose_pmap<Tag, SubGraph, Property> Choice;
  830. typedef typename Choice::type type;
  831. typedef typename Choice::const_type const_type;
  832. };
  833. };
  834. } // namespace detail
  835. template <>
  836. struct vertex_property_selector<subgraph_tag> {
  837. typedef detail::subgraph_property_generator type;
  838. };
  839. template <>
  840. struct edge_property_selector<subgraph_tag> {
  841. typedef detail::subgraph_property_generator type;
  842. };
  843. // ==================================================
  844. // get(p, g), get(p, g, k), and put(p, g, k, v)
  845. // ==================================================
  846. template <typename G, typename Property>
  847. typename property_map<subgraph<G>, Property>::type
  848. get(Property p, subgraph<G>& g) {
  849. typedef typename property_map< subgraph<G>, Property>::type PMap;
  850. return PMap(&g, p);
  851. }
  852. template <typename G, typename Property>
  853. typename property_map<subgraph<G>, Property>::const_type
  854. get(Property p, const subgraph<G>& g) {
  855. typedef typename property_map< subgraph<G>, Property>::const_type PMap;
  856. return PMap(&g, p);
  857. }
  858. template <typename G, typename Property, typename Key>
  859. typename property_traits<
  860. typename property_map<subgraph<G>, Property>::const_type
  861. >::value_type
  862. get(Property p, const subgraph<G>& g, const Key& k) {
  863. typedef typename property_map< subgraph<G>, Property>::const_type PMap;
  864. PMap pmap(&g, p);
  865. return pmap[k];
  866. }
  867. template <typename G, typename Property, typename Key, typename Value>
  868. void put(Property p, subgraph<G>& g, const Key& k, const Value& val) {
  869. typedef typename property_map< subgraph<G>, Property>::type PMap;
  870. PMap pmap(&g, p);
  871. pmap[k] = val;
  872. }
  873. // ==================================================
  874. // get(global(p), g)
  875. // NOTE: get(global(p), g, k) and put(global(p), g, k, v) not supported
  876. // ==================================================
  877. template <typename G, typename Property>
  878. typename property_map<subgraph<G>, global_property<Property> >::type
  879. get(global_property<Property> p, subgraph<G>& g) {
  880. typedef typename property_map<
  881. subgraph<G>, global_property<Property>
  882. >::type Map;
  883. return Map(&g, p.value);
  884. }
  885. template <typename G, typename Property>
  886. typename property_map<subgraph<G>, global_property<Property> >::const_type
  887. get(global_property<Property> p, const subgraph<G>& g) {
  888. typedef typename property_map<
  889. subgraph<G>, global_property<Property>
  890. >::const_type Map;
  891. return Map(&g, p.value);
  892. }
  893. // ==================================================
  894. // get(local(p), g)
  895. // NOTE: get(local(p), g, k) and put(local(p), g, k, v) not supported
  896. // ==================================================
  897. template <typename G, typename Property>
  898. typename property_map<subgraph<G>, local_property<Property> >::type
  899. get(local_property<Property> p, subgraph<G>& g) {
  900. typedef typename property_map<
  901. subgraph<G>, local_property<Property>
  902. >::type Map;
  903. return Map(&g, p.value);
  904. }
  905. template <typename G, typename Property>
  906. typename property_map<subgraph<G>, local_property<Property> >::const_type
  907. get(local_property<Property> p, const subgraph<G>& g) {
  908. typedef typename property_map<
  909. subgraph<G>, local_property<Property>
  910. >::const_type Map;
  911. return Map(&g, p.value);
  912. }
  913. template <typename G, typename Tag>
  914. inline typename graph_property<G, Tag>::type&
  915. get_property(subgraph<G>& g, Tag tag) {
  916. return get_property(g.m_graph, tag);
  917. }
  918. template <typename G, typename Tag>
  919. inline const typename graph_property<G, Tag>::type&
  920. get_property(const subgraph<G>& g, Tag tag) {
  921. return get_property(g.m_graph, tag);
  922. }
  923. //===========================================================================
  924. // Miscellaneous Functions
  925. template <typename G>
  926. typename subgraph<G>::vertex_descriptor
  927. vertex(typename subgraph<G>::vertices_size_type n, const subgraph<G>& g)
  928. { return vertex(n, g.m_graph); }
  929. //===========================================================================
  930. // Mutability Traits
  931. // Just pull the mutability traits form the underlying graph. Note that this
  932. // will probably fail (badly) for labeled graphs.
  933. template <typename G>
  934. struct graph_mutability_traits< subgraph<G> > {
  935. typedef typename graph_mutability_traits<G>::category category;
  936. };
  937. } // namespace boost
  938. #endif // BOOST_SUBGRAPH_HPP