graph_utility.hpp 16 KB

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