weighted_matching_example.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 <iostream>
  10. #include <vector>
  11. #include <string>
  12. #include <boost/graph/adjacency_list.hpp>
  13. #include <boost/graph/maximum_weighted_matching.hpp>
  14. using namespace boost;
  15. typedef property<edge_weight_t, float, property<edge_index_t, int> > EdgeProperty;
  16. typedef adjacency_list<vecS, vecS, undirectedS, no_property, EdgeProperty> my_graph;
  17. int main(int argc, const char * argv[])
  18. {
  19. graph_traits<my_graph>::vertex_iterator vi, vi_end;
  20. const int n_vertices = 18;
  21. my_graph g(n_vertices);
  22. // vertices can be refered by integers because my_graph use vector to store them
  23. add_edge(1, 2, EdgeProperty(5), g);
  24. add_edge(0, 4, EdgeProperty(1), g);
  25. add_edge(1, 5, EdgeProperty(4), g);
  26. add_edge(2, 6, EdgeProperty(1), g);
  27. add_edge(3, 7, EdgeProperty(4), g);
  28. add_edge(4, 5, EdgeProperty(7), g);
  29. add_edge(6, 7, EdgeProperty(5), g);
  30. add_edge(4, 8, EdgeProperty(2), g);
  31. add_edge(5, 9, EdgeProperty(5), g);
  32. add_edge(6, 10, EdgeProperty(6), g);
  33. add_edge(7, 11, EdgeProperty(5), g);
  34. add_edge(10, 11, EdgeProperty(4), g);
  35. add_edge(8, 13, EdgeProperty(4), g);
  36. add_edge(9, 14, EdgeProperty(4), g);
  37. add_edge(10, 15, EdgeProperty(7), g);
  38. add_edge(11, 16, EdgeProperty(6), g);
  39. add_edge(14, 15, EdgeProperty(6), g);
  40. add_edge(12, 13, EdgeProperty(2), g);
  41. add_edge(16, 17, EdgeProperty(5), g);
  42. // print the ascii graph into terminal (better to use fixed-width font)
  43. // this graph has a maximum cardinality matching of size 8
  44. // but maximum weighted matching is of size 7
  45. std::vector<std::string> ascii_graph_weighted;
  46. ascii_graph_weighted.push_back(" 5 ");
  47. ascii_graph_weighted.push_back(" A B---C D ");
  48. ascii_graph_weighted.push_back(" 1\\ 7 /4 1\\ 5 /4 ");
  49. ascii_graph_weighted.push_back(" E---F G---H ");
  50. ascii_graph_weighted.push_back(" 2| |5 6| |5 ");
  51. ascii_graph_weighted.push_back(" I J K---L ");
  52. ascii_graph_weighted.push_back(" 4/ 3\\ 7/ 4 \\6 ");
  53. ascii_graph_weighted.push_back(" M---N O---P Q---R ");
  54. ascii_graph_weighted.push_back(" 2 6 5 ");
  55. // our maximum weighted matching and result
  56. std::cout << "In the following graph:" << std::endl << std::endl;
  57. for(std::vector<std::string>::iterator itr = ascii_graph_weighted.begin(); itr != ascii_graph_weighted.end(); ++itr)
  58. std::cout << *itr << std::endl;
  59. std::cout << std::endl;
  60. std::vector<graph_traits<my_graph>::vertex_descriptor> mate1(n_vertices), mate2(n_vertices);
  61. maximum_weighted_matching(g, &mate1[0]);
  62. std::cout << "Found a weighted matching:" << std::endl;
  63. std::cout << "Matching size is " << matching_size(g, &mate1[0]) << ", total weight is " << matching_weight_sum(g, &mate1[0]) << std::endl;
  64. std::cout << std::endl;
  65. std::cout << "The matching is:" << std::endl;
  66. for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  67. if (mate1[*vi] != graph_traits<my_graph>::null_vertex() && *vi < mate1[*vi])
  68. std::cout << "{" << *vi << ", " << mate1[*vi] << "}" << std::endl;
  69. std::cout << std::endl;
  70. // now we check the correctness by compare the weight sum to a brute-force matching result
  71. // note that two matchings may be different because of multiple optimal solutions
  72. brute_force_maximum_weighted_matching(g, &mate2[0]);
  73. std::cout << "Found a weighted matching by brute-force searching:" << std::endl;
  74. std::cout << "Matching size is " << matching_size(g, &mate2[0]) << ", total weight is " << matching_weight_sum(g, &mate2[0]) << std::endl;
  75. std::cout << std::endl;
  76. std::cout << "The brute-force matching is:" << std::endl;
  77. for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  78. if (mate2[*vi] != graph_traits<my_graph>::null_vertex() && *vi < mate2[*vi])
  79. std::cout << "{" << *vi << ", " << mate2[*vi] << "}" << std::endl;
  80. std::cout << std::endl;
  81. assert(matching_weight_sum(g, &mate1[0]) == matching_weight_sum(g, &mate2[0]));
  82. return 0;
  83. }