mas_test.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Copyright Fernando Vilas 2012.
  2. // Based on stoer_wagner_test.cpp by Daniel Trebbien.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or the copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include <fstream>
  7. #include <iostream>
  8. #include <map>
  9. #include <vector>
  10. #include <string>
  11. #include <boost/graph/adjacency_list.hpp>
  12. #include <boost/graph/connected_components.hpp>
  13. #include <boost/graph/exception.hpp>
  14. #include <boost/graph/graph_traits.hpp>
  15. #include <boost/graph/read_dimacs.hpp>
  16. #include <boost/graph/maximum_adjacency_search.hpp>
  17. #include <boost/graph/visitors.hpp>
  18. #include <boost/graph/property_maps/constant_property_map.hpp>
  19. #include <boost/property_map/property_map.hpp>
  20. #include <boost/test/unit_test.hpp>
  21. #include <boost/tuple/tuple.hpp>
  22. #include <boost/tuple/tuple_comparison.hpp>
  23. #include <boost/tuple/tuple_io.hpp>
  24. #include <boost/graph/iteration_macros.hpp>
  25. typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, boost::property<boost::edge_weight_t, int> > undirected_graph;
  26. typedef boost::property_map<undirected_graph, boost::edge_weight_t>::type weight_map_type;
  27. typedef boost::property_traits<weight_map_type>::value_type weight_type;
  28. typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS> undirected_unweighted_graph;
  29. std::string test_dir;
  30. boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ) {
  31. if (argc != 2) {
  32. std::cerr << "Usage: " << argv[0] << " path-to-libs-graph-test" << std::endl;
  33. throw boost::unit_test::framework::setup_error("Invalid command line arguments");
  34. }
  35. test_dir = argv[1];
  36. return 0;
  37. }
  38. struct edge_t
  39. {
  40. unsigned long first;
  41. unsigned long second;
  42. };
  43. template <typename Graph, typename KeyedUpdatablePriorityQueue>
  44. class mas_edge_connectivity_visitor : public boost::default_mas_visitor {
  45. public:
  46. typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
  47. typedef typename KeyedUpdatablePriorityQueue::key_type weight_type;
  48. #if 0
  49. mas_edge_connectivity_visitor(const mas_edge_connectivity_visitor<Graph, KeyedUpdatablePriorityQueue>& r)
  50. : m_pq(r.m_pq), m_curr(r.m_curr), m_prev(r.m_prev),
  51. m_reach_weight(r.m_reach_weight) {
  52. BOOST_TEST_MESSAGE( "COPY CTOR" );
  53. }
  54. #endif
  55. explicit mas_edge_connectivity_visitor(KeyedUpdatablePriorityQueue& pq)
  56. : m_pq(pq),
  57. m_curr(new vertex_descriptor(0)), m_prev(new vertex_descriptor(0)),
  58. m_reach_weight(new weight_type(0)) {
  59. // BOOST_TEST_MESSAGE( "CTOR" );
  60. }
  61. void clear() {
  62. *m_curr = 0;
  63. *m_prev = 0;
  64. *m_reach_weight = 0;
  65. }
  66. //template <typename Vertex> //, typename Graph>
  67. //void start_vertex(Vertex u, const Graph& g) {
  68. void start_vertex(vertex_descriptor u, const Graph& g) {
  69. *m_prev = *m_curr;
  70. *m_curr = u;
  71. //BOOST_TEST_MESSAGE( "Initializing Vertex(weight): " << u << "(" << *m_reach_weight << ")" );
  72. *m_reach_weight = get(m_pq.keys(), u);
  73. }
  74. vertex_descriptor curr() const { return *m_curr; }
  75. vertex_descriptor prev() const { return *m_prev; }
  76. weight_type reach_weight() const { return *m_reach_weight; }
  77. private:
  78. const KeyedUpdatablePriorityQueue& m_pq;
  79. boost::shared_ptr<vertex_descriptor> m_curr, m_prev;
  80. boost::shared_ptr<weight_type> m_reach_weight;
  81. };
  82. // the example from Stoer & Wagner (1997)
  83. // Check various implementations of the ArgPack where
  84. // the weights are provided in it, and one case where
  85. // they are not.
  86. BOOST_AUTO_TEST_CASE(test0)
  87. {
  88. typedef boost::graph_traits<undirected_graph>::vertex_descriptor vertex_descriptor;
  89. typedef boost::graph_traits<undirected_graph>::edge_descriptor edge_descriptor;
  90. edge_t edges[] = {{0, 1}, {1, 2}, {2, 3},
  91. {0, 4}, {1, 4}, {1, 5}, {2, 6}, {3, 6}, {3, 7}, {4, 5}, {5, 6}, {6, 7}};
  92. weight_type ws[] = {2, 3, 4, 3, 2, 2, 2, 2, 2, 3, 1, 3};
  93. undirected_graph g(edges, edges + 12, ws, 8, 12);
  94. weight_map_type weights = get(boost::edge_weight, g);
  95. std::map<vertex_descriptor, vertex_descriptor> assignment;
  96. boost::associative_property_map<std::map<vertex_descriptor, vertex_descriptor> > assignments(assignment);
  97. typedef boost::shared_array_property_map<weight_type, boost::property_map<undirected_graph, boost::vertex_index_t>::const_type> distances_type;
  98. distances_type distances = boost::make_shared_array_property_map(num_vertices(g), weight_type(0), get(boost::vertex_index, g));
  99. typedef std::vector<vertex_descriptor>::size_type index_in_heap_type;
  100. typedef boost::shared_array_property_map<index_in_heap_type, boost::property_map<undirected_graph, boost::vertex_index_t>::const_type> indicesInHeap_type;
  101. indicesInHeap_type indicesInHeap = boost::make_shared_array_property_map(num_vertices(g), index_in_heap_type(-1), get(boost::vertex_index, g));
  102. boost::d_ary_heap_indirect<vertex_descriptor, 22, indicesInHeap_type, distances_type, std::greater<weight_type> > pq(distances, indicesInHeap);
  103. mas_edge_connectivity_visitor<undirected_graph,boost::d_ary_heap_indirect<vertex_descriptor, 22, indicesInHeap_type, distances_type, std::greater<weight_type> > > test_vis(pq);
  104. boost::maximum_adjacency_search(g,
  105. boost::weight_map(weights).
  106. visitor(test_vis).
  107. root_vertex(*vertices(g).first).
  108. vertex_assignment_map(assignments).
  109. max_priority_queue(pq));
  110. BOOST_CHECK_EQUAL(test_vis.curr(), vertex_descriptor(7));
  111. BOOST_CHECK_EQUAL(test_vis.prev(), vertex_descriptor(6));
  112. BOOST_CHECK_EQUAL(test_vis.reach_weight(), 5);
  113. test_vis.clear();
  114. boost::maximum_adjacency_search(g,
  115. boost::weight_map(weights).
  116. visitor(test_vis).
  117. root_vertex(*vertices(g).first).
  118. max_priority_queue(pq));
  119. BOOST_CHECK_EQUAL(test_vis.curr(), vertex_descriptor(7));
  120. BOOST_CHECK_EQUAL(test_vis.prev(), vertex_descriptor(6));
  121. BOOST_CHECK_EQUAL(test_vis.reach_weight(), 5);
  122. test_vis.clear();
  123. boost::maximum_adjacency_search(g,
  124. boost::weight_map(weights).
  125. visitor(test_vis).
  126. max_priority_queue(pq));
  127. BOOST_CHECK_EQUAL(test_vis.curr(), vertex_descriptor(7));
  128. BOOST_CHECK_EQUAL(test_vis.prev(), vertex_descriptor(6));
  129. BOOST_CHECK_EQUAL(test_vis.reach_weight(), 5);
  130. boost::maximum_adjacency_search(g,
  131. boost::weight_map(weights).
  132. visitor(boost::make_mas_visitor(boost::null_visitor())));
  133. boost::maximum_adjacency_search(g,
  134. boost::weight_map(weights));
  135. boost::maximum_adjacency_search(g,
  136. boost::root_vertex(*vertices(g).first));
  137. test_vis.clear();
  138. boost::maximum_adjacency_search(g,
  139. boost::weight_map(boost::make_constant_property<edge_descriptor>(weight_type(1))).
  140. visitor(test_vis).
  141. max_priority_queue(pq));
  142. BOOST_CHECK_EQUAL(test_vis.curr(), vertex_descriptor(7));
  143. BOOST_CHECK_EQUAL(test_vis.prev(), vertex_descriptor(3));
  144. BOOST_CHECK_EQUAL(test_vis.reach_weight(), 2);
  145. }
  146. // Check the unweighted case
  147. // with and without providing a weight_map
  148. BOOST_AUTO_TEST_CASE(test1)
  149. {
  150. typedef boost::graph_traits<undirected_unweighted_graph>::vertex_descriptor vertex_descriptor;
  151. typedef boost::graph_traits<undirected_unweighted_graph>::edge_descriptor edge_descriptor;
  152. edge_t edge_list[] = {{0, 1}, {1, 2}, {2, 3},
  153. {0, 4}, {1, 4}, {1, 5}, {2, 6}, {3, 6}, {3, 7}, {4, 5}, {5, 6}, {6, 7}};
  154. undirected_unweighted_graph g(edge_list, edge_list + 12, 8);
  155. std::map<vertex_descriptor, vertex_descriptor> assignment;
  156. boost::associative_property_map<std::map<vertex_descriptor, vertex_descriptor> > assignments(assignment);
  157. typedef unsigned weight_type;
  158. typedef boost::shared_array_property_map<weight_type, boost::property_map<undirected_graph, boost::vertex_index_t>::const_type> distances_type;
  159. distances_type distances = boost::make_shared_array_property_map(num_vertices(g), weight_type(0), get(boost::vertex_index, g));
  160. typedef std::vector<vertex_descriptor>::size_type index_in_heap_type;
  161. typedef boost::shared_array_property_map<index_in_heap_type, boost::property_map<undirected_graph, boost::vertex_index_t>::const_type> indicesInHeap_type;
  162. indicesInHeap_type indicesInHeap = boost::make_shared_array_property_map(num_vertices(g), index_in_heap_type(-1), get(boost::vertex_index, g));
  163. boost::d_ary_heap_indirect<vertex_descriptor, 22, indicesInHeap_type, distances_type, std::greater<weight_type> > pq(distances, indicesInHeap);
  164. mas_edge_connectivity_visitor<undirected_unweighted_graph,boost::d_ary_heap_indirect<vertex_descriptor, 22, indicesInHeap_type, distances_type, std::greater<weight_type> > > test_vis(pq);
  165. boost::maximum_adjacency_search(g,
  166. boost::weight_map(boost::make_constant_property<edge_descriptor>(weight_type(1))).visitor(test_vis).max_priority_queue(pq));
  167. BOOST_CHECK_EQUAL(test_vis.curr(), vertex_descriptor(7));
  168. BOOST_CHECK_EQUAL(test_vis.prev(), vertex_descriptor(3));
  169. BOOST_CHECK_EQUAL(test_vis.reach_weight(), weight_type(2));
  170. weight_type ws[] = {2, 3, 4, 3, 2, 2, 2, 2, 2, 3, 1, 3};
  171. std::map<edge_descriptor, weight_type> wm;
  172. weight_type i = 0;
  173. BGL_FORALL_EDGES(e, g, undirected_unweighted_graph) {
  174. wm[e] = ws[i];
  175. ++i;
  176. }
  177. boost::associative_property_map<std::map<edge_descriptor, weight_type> > ws_map(wm);
  178. boost::maximum_adjacency_search(g, boost::weight_map(ws_map).visitor(test_vis).max_priority_queue(pq));
  179. BOOST_CHECK_EQUAL(test_vis.curr(), vertex_descriptor(7));
  180. BOOST_CHECK_EQUAL(test_vis.prev(), vertex_descriptor(6));
  181. BOOST_CHECK_EQUAL(test_vis.reach_weight(), weight_type(5));
  182. }
  183. #include <boost/graph/iteration_macros_undef.hpp>