subgraph.hpp 39 KB

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