adjacency_matrix_test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /* adjacency_matrix_test.cpp source file
  2. *
  3. * Copyright Cromwell D. Enage 2004
  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. /*
  10. * Defines the std::ios class and std::cout, its global output instance.
  11. */
  12. #include <iostream>
  13. /*
  14. * Defines the boost::property_map class template and the boost::get and
  15. * boost::put function templates.
  16. */
  17. #include <boost/property_map/property_map.hpp>
  18. /*
  19. * Defines the boost::graph_traits class template.
  20. */
  21. #include <boost/graph/graph_traits.hpp>
  22. /*
  23. * Defines the vertex and edge property tags.
  24. */
  25. #include <boost/graph/properties.hpp>
  26. /*
  27. * Defines the boost::adjacency_list class template and its associated
  28. * non-member function templates.
  29. */
  30. #include <boost/graph/adjacency_list.hpp>
  31. /*
  32. * Defines the boost::adjacency_matrix class template and its associated
  33. * non-member function templates.
  34. */
  35. #include <boost/graph/adjacency_matrix.hpp>
  36. #include <boost/test/minimal.hpp>
  37. #include <vector>
  38. #include <algorithm> // For std::sort
  39. #include <boost/type_traits/is_convertible.hpp>
  40. #include <boost/graph/iteration_macros.hpp>
  41. template<typename Graph1, typename Graph2>
  42. void run_test()
  43. {
  44. typedef typename boost::property_map<Graph1, boost::vertex_index_t>::type
  45. IndexMap1;
  46. typedef typename boost::property_map<Graph2, boost::vertex_index_t>::type
  47. IndexMap2;
  48. Graph1 g1(24);
  49. Graph2 g2(24);
  50. boost::add_edge(boost::vertex(1, g1), boost::vertex(2, g1), g1);
  51. boost::add_edge(boost::vertex(1, g2), boost::vertex(2, g2), g2);
  52. boost::add_edge(boost::vertex(2, g1), boost::vertex(10, g1), g1);
  53. boost::add_edge(boost::vertex(2, g2), boost::vertex(10, g2), g2);
  54. boost::add_edge(boost::vertex(2, g1), boost::vertex(5, g1), g1);
  55. boost::add_edge(boost::vertex(2, g2), boost::vertex(5, g2), g2);
  56. boost::add_edge(boost::vertex(3, g1), boost::vertex(10, g1), g1);
  57. boost::add_edge(boost::vertex(3, g2), boost::vertex(10, g2), g2);
  58. boost::add_edge(boost::vertex(3, g1), boost::vertex(0, g1), g1);
  59. boost::add_edge(boost::vertex(3, g2), boost::vertex(0, g2), g2);
  60. boost::add_edge(boost::vertex(4, g1), boost::vertex(5, g1), g1);
  61. boost::add_edge(boost::vertex(4, g2), boost::vertex(5, g2), g2);
  62. boost::add_edge(boost::vertex(4, g1), boost::vertex(0, g1), g1);
  63. boost::add_edge(boost::vertex(4, g2), boost::vertex(0, g2), g2);
  64. boost::add_edge(boost::vertex(5, g1), boost::vertex(14, g1), g1);
  65. boost::add_edge(boost::vertex(5, g2), boost::vertex(14, g2), g2);
  66. boost::add_edge(boost::vertex(6, g1), boost::vertex(3, g1), g1);
  67. boost::add_edge(boost::vertex(6, g2), boost::vertex(3, g2), g2);
  68. boost::add_edge(boost::vertex(7, g1), boost::vertex(17, g1), g1);
  69. boost::add_edge(boost::vertex(7, g2), boost::vertex(17, g2), g2);
  70. boost::add_edge(boost::vertex(7, g1), boost::vertex(11, g1), g1);
  71. boost::add_edge(boost::vertex(7, g2), boost::vertex(11, g2), g2);
  72. boost::add_edge(boost::vertex(8, g1), boost::vertex(17, g1), g1);
  73. boost::add_edge(boost::vertex(8, g2), boost::vertex(17, g2), g2);
  74. boost::add_edge(boost::vertex(8, g1), boost::vertex(1, g1), g1);
  75. boost::add_edge(boost::vertex(8, g2), boost::vertex(1, g2), g2);
  76. boost::add_edge(boost::vertex(9, g1), boost::vertex(11, g1), g1);
  77. boost::add_edge(boost::vertex(9, g2), boost::vertex(11, g2), g2);
  78. boost::add_edge(boost::vertex(9, g1), boost::vertex(1, g1), g1);
  79. boost::add_edge(boost::vertex(9, g2), boost::vertex(1, g2), g2);
  80. boost::add_edge(boost::vertex(10, g1), boost::vertex(19, g1), g1);
  81. boost::add_edge(boost::vertex(10, g2), boost::vertex(19, g2), g2);
  82. boost::add_edge(boost::vertex(10, g1), boost::vertex(15, g1), g1);
  83. boost::add_edge(boost::vertex(10, g2), boost::vertex(15, g2), g2);
  84. boost::add_edge(boost::vertex(10, g1), boost::vertex(8, g1), g1);
  85. boost::add_edge(boost::vertex(10, g2), boost::vertex(8, g2), g2);
  86. boost::add_edge(boost::vertex(11, g1), boost::vertex(19, g1), g1);
  87. boost::add_edge(boost::vertex(11, g2), boost::vertex(19, g2), g2);
  88. boost::add_edge(boost::vertex(11, g1), boost::vertex(15, g1), g1);
  89. boost::add_edge(boost::vertex(11, g2), boost::vertex(15, g2), g2);
  90. boost::add_edge(boost::vertex(11, g1), boost::vertex(4, g1), g1);
  91. boost::add_edge(boost::vertex(11, g2), boost::vertex(4, g2), g2);
  92. boost::add_edge(boost::vertex(12, g1), boost::vertex(19, g1), g1);
  93. boost::add_edge(boost::vertex(12, g2), boost::vertex(19, g2), g2);
  94. boost::add_edge(boost::vertex(12, g1), boost::vertex(8, g1), g1);
  95. boost::add_edge(boost::vertex(12, g2), boost::vertex(8, g2), g2);
  96. boost::add_edge(boost::vertex(12, g1), boost::vertex(4, g1), g1);
  97. boost::add_edge(boost::vertex(12, g2), boost::vertex(4, g2), g2);
  98. boost::add_edge(boost::vertex(13, g1), boost::vertex(15, g1), g1);
  99. boost::add_edge(boost::vertex(13, g2), boost::vertex(15, g2), g2);
  100. boost::add_edge(boost::vertex(13, g1), boost::vertex(8, g1), g1);
  101. boost::add_edge(boost::vertex(13, g2), boost::vertex(8, g2), g2);
  102. boost::add_edge(boost::vertex(13, g1), boost::vertex(4, g1), g1);
  103. boost::add_edge(boost::vertex(13, g2), boost::vertex(4, g2), g2);
  104. boost::add_edge(boost::vertex(14, g1), boost::vertex(22, g1), g1);
  105. boost::add_edge(boost::vertex(14, g2), boost::vertex(22, g2), g2);
  106. boost::add_edge(boost::vertex(14, g1), boost::vertex(12, g1), g1);
  107. boost::add_edge(boost::vertex(14, g2), boost::vertex(12, g2), g2);
  108. boost::add_edge(boost::vertex(15, g1), boost::vertex(22, g1), g1);
  109. boost::add_edge(boost::vertex(15, g2), boost::vertex(22, g2), g2);
  110. boost::add_edge(boost::vertex(15, g1), boost::vertex(6, g1), g1);
  111. boost::add_edge(boost::vertex(15, g2), boost::vertex(6, g2), g2);
  112. boost::add_edge(boost::vertex(16, g1), boost::vertex(12, g1), g1);
  113. boost::add_edge(boost::vertex(16, g2), boost::vertex(12, g2), g2);
  114. boost::add_edge(boost::vertex(16, g1), boost::vertex(6, g1), g1);
  115. boost::add_edge(boost::vertex(16, g2), boost::vertex(6, g2), g2);
  116. boost::add_edge(boost::vertex(17, g1), boost::vertex(20, g1), g1);
  117. boost::add_edge(boost::vertex(17, g2), boost::vertex(20, g2), g2);
  118. boost::add_edge(boost::vertex(18, g1), boost::vertex(9, g1), g1);
  119. boost::add_edge(boost::vertex(18, g2), boost::vertex(9, g2), g2);
  120. boost::add_edge(boost::vertex(19, g1), boost::vertex(23, g1), g1);
  121. boost::add_edge(boost::vertex(19, g2), boost::vertex(23, g2), g2);
  122. boost::add_edge(boost::vertex(19, g1), boost::vertex(18, g1), g1);
  123. boost::add_edge(boost::vertex(19, g2), boost::vertex(18, g2), g2);
  124. boost::add_edge(boost::vertex(20, g1), boost::vertex(23, g1), g1);
  125. boost::add_edge(boost::vertex(20, g2), boost::vertex(23, g2), g2);
  126. boost::add_edge(boost::vertex(20, g1), boost::vertex(13, g1), g1);
  127. boost::add_edge(boost::vertex(20, g2), boost::vertex(13, g2), g2);
  128. boost::add_edge(boost::vertex(21, g1), boost::vertex(18, g1), g1);
  129. boost::add_edge(boost::vertex(21, g2), boost::vertex(18, g2), g2);
  130. boost::add_edge(boost::vertex(21, g1), boost::vertex(13, g1), g1);
  131. boost::add_edge(boost::vertex(21, g2), boost::vertex(13, g2), g2);
  132. boost::add_edge(boost::vertex(22, g1), boost::vertex(21, g1), g1);
  133. boost::add_edge(boost::vertex(22, g2), boost::vertex(21, g2), g2);
  134. boost::add_edge(boost::vertex(23, g1), boost::vertex(16, g1), g1);
  135. boost::add_edge(boost::vertex(23, g2), boost::vertex(16, g2), g2);
  136. IndexMap1 index_map1 = boost::get(boost::vertex_index_t(), g1);
  137. IndexMap2 index_map2 = boost::get(boost::vertex_index_t(), g2);
  138. typename boost::graph_traits<Graph1>::vertex_iterator vi1, vend1;
  139. typename boost::graph_traits<Graph2>::vertex_iterator vi2, vend2;
  140. typename boost::graph_traits<Graph1>::adjacency_iterator ai1, aend1;
  141. typename boost::graph_traits<Graph2>::adjacency_iterator ai2, aend2;
  142. for (boost::tie(vi1, vend1) = boost::vertices(g1), boost::tie(vi2, vend2) =boost::vertices(g2); vi1 != vend1; ++vi1, ++vi2)
  143. {
  144. BOOST_CHECK(boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2));
  145. for (boost::tie(ai1, aend1) = boost::adjacent_vertices(*vi1, g1),
  146. boost::tie(ai2, aend2) = boost::adjacent_vertices(*vi2, g2);
  147. ai1 != aend1;
  148. ++ai1, ++ai2)
  149. {
  150. BOOST_CHECK(boost::get(index_map1, *ai1) == boost::get(index_map2, *ai2));
  151. }
  152. }
  153. typename boost::graph_traits<Graph1>::out_edge_iterator ei1, eend1;
  154. typename boost::graph_traits<Graph2>::out_edge_iterator ei2, eend2;
  155. for (boost::tie(vi1, vend1) = boost::vertices(g1),
  156. boost::tie(vi2, vend2) = boost::vertices(g2); vi1 != vend1; ++vi1, ++vi2)
  157. {
  158. BOOST_CHECK(boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2));
  159. for (boost::tie(ei1, eend1) = boost::out_edges(*vi1, g1),
  160. boost::tie(ei2, eend2) = boost::out_edges(*vi2, g2);
  161. ei1 != eend1;
  162. ++ei1, ++ei2)
  163. {
  164. BOOST_CHECK(boost::get(index_map1, boost::target(*ei1, g1)) == boost::get(index_map2, boost::target(*ei2, g2)));
  165. }
  166. }
  167. typename boost::graph_traits<Graph1>::in_edge_iterator iei1, ieend1;
  168. typename boost::graph_traits<Graph2>::in_edge_iterator iei2, ieend2;
  169. for (boost::tie(vi1, vend1) = boost::vertices(g1),
  170. boost::tie(vi2, vend2) = boost::vertices(g2); vi1 != vend1; ++vi1, ++vi2)
  171. {
  172. BOOST_CHECK(boost::get(index_map1, *vi1) == boost::get(index_map2, *vi2));
  173. for (boost::tie(iei1, ieend1) = boost::in_edges(*vi1, g1),
  174. boost::tie(iei2, ieend2) = boost::in_edges(*vi2, g2);
  175. iei1 != ieend1;
  176. ++iei1, ++iei2)
  177. {
  178. BOOST_CHECK(boost::get(index_map1, boost::target(*iei1, g1)) == boost::get(index_map2, boost::target(*iei2, g2)));
  179. }
  180. }
  181. // Test construction from a range of pairs
  182. std::vector<std::pair<int, int> > edge_pairs_g1;
  183. BGL_FORALL_EDGES_T(e, g1, Graph1) {
  184. edge_pairs_g1.push_back(
  185. std::make_pair(get(index_map1, source(e, g1)),
  186. get(index_map1, target(e, g1))));
  187. }
  188. Graph2 g3(edge_pairs_g1.begin(), edge_pairs_g1.end(), num_vertices(g1));
  189. BOOST_CHECK(num_vertices(g1) == num_vertices(g3));
  190. std::vector<std::pair<int, int> > edge_pairs_g3;
  191. IndexMap2 index_map3 = boost::get(boost::vertex_index_t(), g3);
  192. BGL_FORALL_EDGES_T(e, g3, Graph2) {
  193. edge_pairs_g3.push_back(
  194. std::make_pair(get(index_map3, source(e, g3)),
  195. get(index_map3, target(e, g3))));
  196. }
  197. // Normalize the edge pairs for comparison
  198. if (boost::is_convertible<typename boost::graph_traits<Graph1>::directed_category*, boost::undirected_tag*>::value || boost::is_convertible<typename boost::graph_traits<Graph2>::directed_category*, boost::undirected_tag*>::value) {
  199. for (size_t i = 0; i < edge_pairs_g1.size(); ++i) {
  200. if (edge_pairs_g1[i].first < edge_pairs_g1[i].second) {
  201. std::swap(edge_pairs_g1[i].first, edge_pairs_g1[i].second);
  202. }
  203. }
  204. for (size_t i = 0; i < edge_pairs_g3.size(); ++i) {
  205. if (edge_pairs_g3[i].first < edge_pairs_g3[i].second) {
  206. std::swap(edge_pairs_g3[i].first, edge_pairs_g3[i].second);
  207. }
  208. }
  209. }
  210. std::sort(edge_pairs_g1.begin(), edge_pairs_g1.end());
  211. std::sort(edge_pairs_g3.begin(), edge_pairs_g3.end());
  212. edge_pairs_g1.erase(std::unique(edge_pairs_g1.begin(), edge_pairs_g1.end()), edge_pairs_g1.end());
  213. edge_pairs_g3.erase(std::unique(edge_pairs_g3.begin(), edge_pairs_g3.end()), edge_pairs_g3.end());
  214. BOOST_CHECK(edge_pairs_g1 == edge_pairs_g3);
  215. }
  216. template <typename Graph>
  217. void test_remove_edges()
  218. {
  219. using namespace boost;
  220. // Build a 2-vertex graph
  221. Graph g(2);
  222. add_edge(vertex(0, g), vertex(1, g), g);
  223. BOOST_CHECK(num_vertices(g) == 2);
  224. BOOST_CHECK(num_edges(g) == 1);
  225. remove_edge(vertex(0, g), vertex(1, g), g);
  226. BOOST_CHECK(num_edges(g) == 0);
  227. // Make sure we don't decrement the edge count if the edge doesn't actually
  228. // exist.
  229. remove_edge(vertex(0, g), vertex(1, g), g);
  230. BOOST_CHECK(num_edges(g) == 0);
  231. }
  232. int test_main(int, char*[])
  233. {
  234. // Use setS to keep out edges in order, so they match the adjacency_matrix.
  235. typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>
  236. UGraph1;
  237. typedef boost::adjacency_matrix<boost::undirectedS>
  238. UGraph2;
  239. run_test<UGraph1, UGraph2>();
  240. // Use setS to keep out edges in order, so they match the adjacency_matrix.
  241. typedef boost::adjacency_list<boost::setS, boost::vecS,
  242. boost::bidirectionalS>
  243. BGraph1;
  244. typedef boost::adjacency_matrix<boost::directedS>
  245. BGraph2;
  246. run_test<BGraph1, BGraph2>();
  247. test_remove_edges<UGraph2>();
  248. test_remove_edges<BGraph2>();
  249. return 0;
  250. }