weighted_matching_test.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //=======================================================================
  2. // Copyright (c) 2018 Yi Ji
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. //=======================================================================
  9. #include <boost/graph/max_cardinality_matching.hpp>
  10. #include <boost/graph/maximum_weighted_matching.hpp>
  11. #include <iostream>
  12. #include <fstream>
  13. #include <sstream>
  14. #include <boost/graph/adjacency_list.hpp>
  15. #include <boost/graph/adjacency_matrix.hpp>
  16. #include <boost/test/minimal.hpp>
  17. using namespace boost;
  18. typedef property<edge_weight_t, float, property<edge_index_t, int> > EdgeProperty;
  19. typedef adjacency_list<vecS, vecS, undirectedS, property<vertex_index_t,int>, EdgeProperty> undirected_graph;
  20. typedef adjacency_list<listS, listS, undirectedS, property<vertex_index_t,int>, EdgeProperty> undirected_list_graph;
  21. typedef adjacency_matrix<undirectedS, property<vertex_index_t,int>, EdgeProperty> undirected_adjacency_matrix_graph;
  22. template <typename Graph>
  23. struct vertex_index_installer
  24. {
  25. static void install(Graph&) {}
  26. };
  27. template <>
  28. struct vertex_index_installer<undirected_list_graph>
  29. {
  30. static void install(undirected_list_graph& g)
  31. {
  32. typedef graph_traits<undirected_list_graph>::vertex_iterator vertex_iterator_t;
  33. typedef graph_traits<undirected_list_graph>::vertices_size_type v_size_t;
  34. vertex_iterator_t vi, vi_end;
  35. v_size_t i = 0;
  36. for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi, ++i)
  37. put(vertex_index, g, *vi, i);
  38. }
  39. };
  40. template <typename Graph>
  41. void print_graph(const Graph& g)
  42. {
  43. typedef typename graph_traits<Graph>::edge_iterator edge_iterator_t;
  44. edge_iterator_t ei, ei_end;
  45. std::cout << std::endl << "The graph is: " << std::endl;
  46. for (boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
  47. std::cout << "add_edge(" << source(*ei, g) << ", " << target(*ei, g) << ", EdgeProperty(" << get(edge_weight, g, *ei) << "), );" << std::endl;
  48. }
  49. template <typename Graph>
  50. void weighted_matching_test(const Graph& g,
  51. typename property_traits<typename property_map<Graph, edge_weight_t>::type>::value_type answer)
  52. {
  53. typedef typename property_map<Graph,vertex_index_t>::type vertex_index_map_t;
  54. typedef vector_property_map< typename graph_traits<Graph>::vertex_descriptor, vertex_index_map_t > mate_t;
  55. mate_t mate(num_vertices(g));
  56. maximum_weighted_matching(g, mate);
  57. bool same_result = (matching_weight_sum(g, mate) == answer);
  58. BOOST_CHECK(same_result);
  59. if (!same_result)
  60. {
  61. mate_t max_mate(num_vertices(g));
  62. brute_force_maximum_weighted_matching(g, max_mate);
  63. std::cout << std::endl << "Found a weighted matching of weight sum " << matching_weight_sum(g, mate) << std::endl
  64. << "While brute-force search found a weighted matching of weight sum " << matching_weight_sum(g, max_mate) << std::endl;
  65. typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
  66. vertex_iterator_t vi, vi_end;
  67. print_graph(g);
  68. std::cout << std::endl << "The algorithmic matching is:" << std::endl;
  69. for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  70. if (mate[*vi] != graph_traits<Graph>::null_vertex() && *vi < mate[*vi])
  71. std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl;
  72. std::cout << std::endl << "The brute-force matching is:" << std::endl;
  73. for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  74. if (max_mate[*vi] != graph_traits<Graph>::null_vertex() && *vi < max_mate[*vi])
  75. std::cout << "{" << *vi << ", " << max_mate[*vi] << "}" << std::endl;
  76. std::cout << std::endl;
  77. }
  78. }
  79. template <typename Graph>
  80. Graph make_graph(typename graph_traits<Graph>::vertices_size_type num_v,
  81. typename graph_traits<Graph>::edges_size_type num_e,
  82. std::deque<std::size_t> input_edges)
  83. {
  84. Graph g(num_v);
  85. vertex_index_installer<Graph>::install(g);
  86. for (std::size_t i = 0; i < num_e; ++i)
  87. {
  88. std::size_t src_v, tgt_v, edge_weight;
  89. src_v = input_edges.front();
  90. input_edges.pop_front();
  91. tgt_v = input_edges.front();
  92. input_edges.pop_front();
  93. edge_weight = input_edges.front();
  94. input_edges.pop_front();
  95. add_edge(vertex(src_v, g), vertex(tgt_v, g), EdgeProperty(edge_weight), g);
  96. }
  97. return g;
  98. }
  99. int test_main(int, char*[])
  100. {
  101. std::ifstream in_file("weighted_matching.dat");
  102. std::string line;
  103. while (std::getline(in_file, line))
  104. {
  105. std::istringstream in_graph(line);
  106. std::size_t answer, num_v, num_e;
  107. in_graph >> answer >> num_v >> num_e;
  108. std::deque<std::size_t> input_edges;
  109. std::size_t i;
  110. while (in_graph >> i)
  111. input_edges.push_back(i);
  112. weighted_matching_test(make_graph<undirected_graph>(num_v, num_e, input_edges), answer);
  113. weighted_matching_test(make_graph<undirected_list_graph>(num_v, num_e, input_edges), answer);
  114. weighted_matching_test(make_graph<undirected_adjacency_matrix_graph>(num_v, num_e, input_edges), answer);
  115. }
  116. return 0;
  117. }