graph_utility.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. //
  2. //=======================================================================
  3. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  4. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //=======================================================================
  10. //
  11. #ifndef BOOST_GRAPH_UTILITY_HPP
  12. #define BOOST_GRAPH_UTILITY_HPP
  13. #include <stdlib.h>
  14. #include <iostream>
  15. #include <algorithm>
  16. #include <assert.h>
  17. #include <boost/config.hpp>
  18. #include <boost/tuple/tuple.hpp>
  19. #if !defined BOOST_NO_SLIST
  20. # ifdef BOOST_SLIST_HEADER
  21. # include BOOST_SLIST_HEADER
  22. # else
  23. # include <slist>
  24. # endif
  25. #endif
  26. #include <boost/graph/graph_traits.hpp>
  27. #include <boost/graph/properties.hpp>
  28. #include <boost/pending/container_traits.hpp>
  29. #include <boost/graph/depth_first_search.hpp>
  30. // iota moved to detail/algorithm.hpp
  31. #include <boost/detail/algorithm.hpp>
  32. namespace boost {
  33. // Provide an undirected graph interface alternative to the
  34. // the source() and target() edge functions.
  35. template <class UndirectedGraph>
  36. inline
  37. std::pair<typename graph_traits<UndirectedGraph>::vertex_descriptor,
  38. typename graph_traits<UndirectedGraph>::vertex_descriptor>
  39. incident(typename graph_traits<UndirectedGraph>::edge_descriptor e,
  40. UndirectedGraph& g)
  41. {
  42. return std::make_pair(source(e,g), target(e,g));
  43. }
  44. // Provide an undirected graph interface alternative
  45. // to the out_edges() function.
  46. template <class Graph>
  47. inline
  48. std::pair<typename graph_traits<Graph>::out_edge_iterator,
  49. typename graph_traits<Graph>::out_edge_iterator>
  50. incident_edges(typename graph_traits<Graph>::vertex_descriptor u,
  51. Graph& g)
  52. {
  53. return out_edges(u, g);
  54. }
  55. template <class Graph>
  56. inline typename graph_traits<Graph>::vertex_descriptor
  57. opposite(typename graph_traits<Graph>::edge_descriptor e,
  58. typename graph_traits<Graph>::vertex_descriptor v,
  59. const Graph& g)
  60. {
  61. typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  62. if (v == source(e, g))
  63. return target(e, g);
  64. else if (v == target(e, g))
  65. return source(e, g);
  66. else
  67. return vertex_descriptor();
  68. }
  69. //===========================================================================
  70. // Some handy predicates
  71. template <typename Vertex, typename Graph>
  72. struct incident_from_predicate {
  73. incident_from_predicate(Vertex u, const Graph& g)
  74. : m_u(u), m_g(g) { }
  75. template <class Edge>
  76. bool operator()(const Edge& e) const {
  77. return source(e, m_g) == m_u;
  78. }
  79. Vertex m_u;
  80. const Graph& m_g;
  81. };
  82. template <typename Vertex, typename Graph>
  83. inline incident_from_predicate<Vertex, Graph>
  84. incident_from(Vertex u, const Graph& g) {
  85. return incident_from_predicate<Vertex, Graph>(u, g);
  86. }
  87. template <typename Vertex, typename Graph>
  88. struct incident_to_predicate {
  89. incident_to_predicate(Vertex u, const Graph& g)
  90. : m_u(u), m_g(g) { }
  91. template <class Edge>
  92. bool operator()(const Edge& e) const {
  93. return target(e, m_g) == m_u;
  94. }
  95. Vertex m_u;
  96. const Graph& m_g;
  97. };
  98. template <typename Vertex, typename Graph>
  99. inline incident_to_predicate<Vertex, Graph>
  100. incident_to(Vertex u, const Graph& g) {
  101. return incident_to_predicate<Vertex, Graph>(u, g);
  102. }
  103. template <typename Vertex, typename Graph>
  104. struct incident_on_predicate {
  105. incident_on_predicate(Vertex u, const Graph& g)
  106. : m_u(u), m_g(g) { }
  107. template <class Edge>
  108. bool operator()(const Edge& e) const {
  109. return source(e, m_g) == m_u || target(e, m_g) == m_u;
  110. }
  111. Vertex m_u;
  112. const Graph& m_g;
  113. };
  114. template <typename Vertex, typename Graph>
  115. inline incident_on_predicate<Vertex, Graph>
  116. incident_on(Vertex u, const Graph& g) {
  117. return incident_on_predicate<Vertex, Graph>(u, g);
  118. }
  119. template <typename Vertex, typename Graph>
  120. struct connects_predicate {
  121. connects_predicate(Vertex u, Vertex v, const Graph& g)
  122. : m_u(u), m_v(v), m_g(g) { }
  123. template <class Edge>
  124. bool operator()(const Edge& e) const {
  125. if (is_directed(m_g))
  126. return source(e, m_g) == m_u && target(e, m_g) == m_v;
  127. else
  128. return (source(e, m_g) == m_u && target(e, m_g) == m_v)
  129. || (source(e, m_g) == m_v && target(e, m_g) == m_u);
  130. }
  131. Vertex m_u, m_v;
  132. const Graph& m_g;
  133. };
  134. template <typename Vertex, typename Graph>
  135. inline connects_predicate<Vertex, Graph>
  136. connects(Vertex u, Vertex v, const Graph& g) {
  137. return connects_predicate<Vertex, Graph>(u, v, g);
  138. }
  139. // Need to convert all of these printing functions to take an ostream object
  140. // -JGS
  141. template <class IncidenceGraph, class Name>
  142. void print_in_edges(const IncidenceGraph& G, Name name)
  143. {
  144. typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
  145. for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
  146. std::cout << get(name,*ui) << " <-- ";
  147. typename graph_traits<IncidenceGraph>
  148. ::in_edge_iterator ei, ei_end;
  149. for(boost::tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei)
  150. std::cout << get(name,source(*ei,G)) << " ";
  151. std::cout << std::endl;
  152. }
  153. }
  154. template <class IncidenceGraph, class Name>
  155. void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag)
  156. {
  157. typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
  158. for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
  159. std::cout << get(name,*ui) << " --> ";
  160. typename graph_traits<IncidenceGraph>
  161. ::out_edge_iterator ei, ei_end;
  162. for(boost::tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
  163. std::cout << get(name,target(*ei,G)) << " ";
  164. std::cout << std::endl;
  165. }
  166. }
  167. template <class IncidenceGraph, class Name>
  168. void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag)
  169. {
  170. typename graph_traits<IncidenceGraph>::vertex_iterator ui,ui_end;
  171. for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) {
  172. std::cout << get(name,*ui) << " <--> ";
  173. typename graph_traits<IncidenceGraph>
  174. ::out_edge_iterator ei, ei_end;
  175. for(boost::tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei)
  176. std::cout << get(name,target(*ei,G)) << " ";
  177. std::cout << std::endl;
  178. }
  179. }
  180. template <class IncidenceGraph, class Name>
  181. void print_graph(const IncidenceGraph& G, Name name)
  182. {
  183. typedef typename graph_traits<IncidenceGraph>
  184. ::directed_category Cat;
  185. print_graph_dispatch(G, name, Cat());
  186. }
  187. template <class IncidenceGraph>
  188. void print_graph(const IncidenceGraph& G) {
  189. print_graph(G, get(vertex_index, G));
  190. }
  191. template <class EdgeListGraph, class Name>
  192. void print_edges(const EdgeListGraph& G, Name name)
  193. {
  194. typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
  195. for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
  196. std::cout << "(" << get(name, source(*ei, G))
  197. << "," << get(name, target(*ei, G)) << ") ";
  198. std::cout << std::endl;
  199. }
  200. template <class EdgeListGraph, class VertexName, class EdgeName>
  201. void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename)
  202. {
  203. typename graph_traits<EdgeListGraph>::edge_iterator ei, ei_end;
  204. for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei)
  205. std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G))
  206. << "," << get(vname, target(*ei, G)) << ") ";
  207. std::cout << std::endl;
  208. }
  209. template <class VertexListGraph, class Name>
  210. void print_vertices(const VertexListGraph& G, Name name)
  211. {
  212. typename graph_traits<VertexListGraph>::vertex_iterator vi,vi_end;
  213. for (boost::tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi)
  214. std::cout << get(name,*vi) << " ";
  215. std::cout << std::endl;
  216. }
  217. template <class Graph, class Vertex>
  218. bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, bidirectional_tag)
  219. {
  220. typename graph_traits<Graph>::adjacency_iterator vi, viend,
  221. adj_found;
  222. boost::tie(vi, viend) = adjacent_vertices(a, g);
  223. adj_found = std::find(vi, viend, b);
  224. if (adj_found == viend)
  225. return false;
  226. typename graph_traits<Graph>::out_edge_iterator oi, oiend,
  227. out_found;
  228. boost::tie(oi, oiend) = out_edges(a, g);
  229. out_found = std::find_if(oi, oiend, incident_to(b, g));
  230. if (out_found == oiend)
  231. return false;
  232. typename graph_traits<Graph>::in_edge_iterator ii, iiend,
  233. in_found;
  234. boost::tie(ii, iiend) = in_edges(b, g);
  235. in_found = std::find_if(ii, iiend, incident_from(a, g));
  236. if (in_found == iiend)
  237. return false;
  238. return true;
  239. }
  240. template <class Graph, class Vertex>
  241. bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, directed_tag)
  242. {
  243. typename graph_traits<Graph>::adjacency_iterator vi, viend, found;
  244. boost::tie(vi, viend) = adjacent_vertices(a, g);
  245. #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
  246. // Getting internal compiler error with std::find()
  247. found = viend;
  248. for (; vi != viend; ++vi)
  249. if (*vi == b) {
  250. found = vi;
  251. break;
  252. }
  253. #else
  254. found = std::find(vi, viend, b);
  255. #endif
  256. if ( found == viend )
  257. return false;
  258. typename graph_traits<Graph>::out_edge_iterator oi, oiend,
  259. out_found;
  260. boost::tie(oi, oiend) = out_edges(a, g);
  261. #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 && defined(__SGI_STL_PORT)
  262. // Getting internal compiler error with std::find()
  263. out_found = oiend;
  264. for (; oi != oiend; ++oi)
  265. if (target(*oi, g) == b) {
  266. out_found = oi;
  267. break;
  268. }
  269. #else
  270. out_found = std::find_if(oi, oiend, incident_to(b, g));
  271. #endif
  272. if (out_found == oiend)
  273. return false;
  274. return true;
  275. }
  276. template <class Graph, class Vertex>
  277. bool is_adj_dispatch(Graph& g, Vertex a, Vertex b, undirected_tag)
  278. {
  279. return is_adj_dispatch(g, a, b, directed_tag());
  280. }
  281. template <class Graph, class Vertex>
  282. bool is_adjacent(Graph& g, Vertex a, Vertex b) {
  283. typedef typename graph_traits<Graph>::directed_category Cat;
  284. return is_adj_dispatch(g, a, b, Cat());
  285. }
  286. template <class Graph, class Edge>
  287. bool in_edge_set(Graph& g, Edge e)
  288. {
  289. typename Graph::edge_iterator ei, ei_end, found;
  290. boost::tie(ei, ei_end) = edges(g);
  291. found = std::find(ei, ei_end, e);
  292. return found != ei_end;
  293. }
  294. template <class Graph, class Vertex>
  295. bool in_vertex_set(Graph& g, Vertex v)
  296. {
  297. typename Graph::vertex_iterator vi, vi_end, found;
  298. boost::tie(vi, vi_end) = vertices(g);
  299. found = std::find(vi, vi_end, v);
  300. return found != vi_end;
  301. }
  302. template <class Graph, class Vertex>
  303. bool in_edge_set(Graph& g, Vertex u, Vertex v)
  304. {
  305. typename Graph::edge_iterator ei, ei_end;
  306. for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
  307. if (source(*ei,g) == u && target(*ei,g) == v)
  308. return true;
  309. return false;
  310. }
  311. // is x a descendant of y?
  312. template <typename ParentMap>
  313. inline bool is_descendant
  314. (typename property_traits<ParentMap>::value_type x,
  315. typename property_traits<ParentMap>::value_type y,
  316. ParentMap parent)
  317. {
  318. if (get(parent, x) == x) // x is the root of the tree
  319. return false;
  320. else if (get(parent, x) == y)
  321. return true;
  322. else
  323. return is_descendant(get(parent, x), y, parent);
  324. }
  325. // is y reachable from x?
  326. template <typename IncidenceGraph, typename VertexColorMap>
  327. inline bool is_reachable
  328. (typename graph_traits<IncidenceGraph>::vertex_descriptor x,
  329. typename graph_traits<IncidenceGraph>::vertex_descriptor y,
  330. const IncidenceGraph& g,
  331. VertexColorMap color) // should start out white for every vertex
  332. {
  333. typedef typename property_traits<VertexColorMap>::value_type ColorValue;
  334. dfs_visitor<> vis;
  335. depth_first_visit(g, x, vis, color);
  336. return get(color, y) != color_traits<ColorValue>::white();
  337. }
  338. // Is the undirected graph connected?
  339. // Is the directed graph strongly connected?
  340. template <typename VertexListGraph, typename VertexColorMap>
  341. inline bool is_connected(const VertexListGraph& g, VertexColorMap color)
  342. {
  343. typedef typename property_traits<VertexColorMap>::value_type ColorValue;
  344. typedef color_traits<ColorValue> Color;
  345. typename graph_traits<VertexListGraph>::vertex_iterator
  346. ui, ui_end, vi, vi_end, ci, ci_end;
  347. for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui)
  348. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  349. if (*ui != *vi) {
  350. for (boost::tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci)
  351. put(color, *ci, Color::white());
  352. if (! is_reachable(*ui, *vi, g, color))
  353. return false;
  354. }
  355. return true;
  356. }
  357. template <typename Graph>
  358. bool is_self_loop
  359. (typename graph_traits<Graph>::edge_descriptor e,
  360. const Graph& g)
  361. {
  362. return source(e, g) == target(e, g);
  363. }
  364. template <class T1, class T2>
  365. std::pair<T1,T2>
  366. make_list(const T1& t1, const T2& t2)
  367. { return std::make_pair(t1, t2); }
  368. template <class T1, class T2, class T3>
  369. std::pair<T1,std::pair<T2,T3> >
  370. make_list(const T1& t1, const T2& t2, const T3& t3)
  371. { return std::make_pair(t1, std::make_pair(t2, t3)); }
  372. template <class T1, class T2, class T3, class T4>
  373. std::pair<T1,std::pair<T2,std::pair<T3,T4> > >
  374. make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  375. { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, t4))); }
  376. template <class T1, class T2, class T3, class T4, class T5>
  377. std::pair<T1,std::pair<T2,std::pair<T3,std::pair<T4,T5> > > >
  378. make_list(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
  379. { return std::make_pair(t1, std::make_pair(t2, std::make_pair(t3, std::make_pair(t4, t5)))); }
  380. namespace graph {
  381. // Functor for remove_parallel_edges: edge property of the removed edge is added to the remaining
  382. template <typename EdgeProperty>
  383. struct add_removed_edge_property
  384. {
  385. add_removed_edge_property(EdgeProperty ep) : ep(ep) {}
  386. template <typename Edge>
  387. void operator() (Edge stay, Edge away)
  388. {
  389. put(ep, stay, get(ep, stay) + get(ep, away));
  390. }
  391. EdgeProperty ep;
  392. };
  393. // Same as above: edge property is capacity here
  394. template <typename Graph>
  395. struct add_removed_edge_capacity
  396. : add_removed_edge_property<typename property_map<Graph, edge_capacity_t>::type>
  397. {
  398. typedef add_removed_edge_property<typename property_map<Graph, edge_capacity_t>::type> base;
  399. add_removed_edge_capacity(Graph& g) : base(get(edge_capacity, g)) {}
  400. };
  401. template <typename Graph>
  402. bool has_no_vertices(const Graph& g) {
  403. typedef typename boost::graph_traits<Graph>::vertex_iterator vi;
  404. std::pair<vi, vi> p = vertices(g);
  405. return (p.first == p.second);
  406. }
  407. template <typename Graph>
  408. bool has_no_edges(const Graph& g) {
  409. typedef typename boost::graph_traits<Graph>::edge_iterator ei;
  410. std::pair<ei, ei> p = edges(g);
  411. return (p.first == p.second);
  412. }
  413. template <typename Graph>
  414. bool has_no_out_edges(const typename boost::graph_traits<Graph>::vertex_descriptor& v, const Graph& g) {
  415. typedef typename boost::graph_traits<Graph>::out_edge_iterator ei;
  416. std::pair<ei, ei> p = out_edges(v, g);
  417. return (p.first == p.second);
  418. }
  419. } // namespace graph
  420. #include <boost/graph/iteration_macros.hpp>
  421. template <class PropertyIn, class PropertyOut, class Graph>
  422. void copy_vertex_property(PropertyIn p_in, PropertyOut p_out, Graph& g)
  423. {
  424. BGL_FORALL_VERTICES_T(u, g, Graph)
  425. put(p_out, u, get(p_in, g));
  426. }
  427. template <class PropertyIn, class PropertyOut, class Graph>
  428. void copy_edge_property(PropertyIn p_in, PropertyOut p_out, Graph& g)
  429. {
  430. BGL_FORALL_EDGES_T(e, g, Graph)
  431. put(p_out, e, get(p_in, g));
  432. }
  433. // Return true if property_map1 and property_map2 differ
  434. // for any of the vertices in graph.
  435. template <typename PropertyMapFirst,
  436. typename PropertyMapSecond,
  437. typename Graph>
  438. bool are_property_maps_different
  439. (const PropertyMapFirst property_map1,
  440. const PropertyMapSecond property_map2,
  441. const Graph& graph) {
  442. BGL_FORALL_VERTICES_T(vertex, graph, Graph) {
  443. if (get(property_map1, vertex) !=
  444. get(property_map2, vertex)) {
  445. return (true);
  446. }
  447. }
  448. return (false);
  449. }
  450. } /* namespace boost */
  451. #endif /* BOOST_GRAPH_UTILITY_HPP*/