matching_example.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //=======================================================================
  2. // Copyright (c) 2005 Aaron Windsor
  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 <string>
  10. #include <iostream>
  11. #include <boost/graph/adjacency_list.hpp>
  12. #include <cassert>
  13. #include <boost/graph/max_cardinality_matching.hpp>
  14. using namespace boost;
  15. typedef adjacency_list<vecS, vecS, undirectedS> my_graph;
  16. int main()
  17. {
  18. // Create the following graph: (it'll look better when output
  19. // to the terminal in a fixed width font...)
  20. const int n_vertices = 18;
  21. std::vector<std::string> ascii_graph;
  22. ascii_graph.push_back(" 0 1---2 3 ");
  23. ascii_graph.push_back(" \\ / \\ / ");
  24. ascii_graph.push_back(" 4---5 6---7 ");
  25. ascii_graph.push_back(" | | | | ");
  26. ascii_graph.push_back(" 8---9 10---11 ");
  27. ascii_graph.push_back(" / \\ / \\ ");
  28. ascii_graph.push_back(" 12 13 14---15 16 17 ");
  29. // It has a perfect matching of size 8. There are two isolated
  30. // vertices that we'll use later...
  31. my_graph g(n_vertices);
  32. // our vertices are stored in a vector, so we can refer to vertices
  33. // by integers in the range 0..15
  34. add_edge(1,2,g);
  35. add_edge(0,4,g);
  36. add_edge(1,5,g);
  37. add_edge(2,6,g);
  38. add_edge(3,7,g);
  39. add_edge(4,5,g);
  40. add_edge(6,7,g);
  41. add_edge(4,8,g);
  42. add_edge(5,9,g);
  43. add_edge(6,10,g);
  44. add_edge(7,11,g);
  45. add_edge(8,9,g);
  46. add_edge(10,11,g);
  47. add_edge(8,13,g);
  48. add_edge(9,14,g);
  49. add_edge(10,15,g);
  50. add_edge(11,16,g);
  51. add_edge(14,15,g);
  52. std::vector<graph_traits<my_graph>::vertex_descriptor> mate(n_vertices);
  53. // find the maximum cardinality matching. we'll use a checked version
  54. // of the algorithm, which takes a little longer than the unchecked
  55. // version, but has the advantage that it will return "false" if the
  56. // matching returned is not actually a maximum cardinality matching
  57. // in the graph.
  58. bool success = checked_edmonds_maximum_cardinality_matching(g, &mate[0]);
  59. assert(success);
  60. std::cout << "In the following graph:" << std::endl << std::endl;
  61. for(std::vector<std::string>::iterator itr = ascii_graph.begin(); itr != ascii_graph.end(); ++itr)
  62. std::cout << *itr << std::endl;
  63. std::cout << std::endl << "Found a matching of size " << matching_size(g, &mate[0]) << std::endl;
  64. std::cout << "The matching is:" << std::endl;
  65. graph_traits<my_graph>::vertex_iterator vi, vi_end;
  66. for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  67. if (mate[*vi] != graph_traits<my_graph>::null_vertex() && *vi < mate[*vi])
  68. std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl;
  69. std::cout << std::endl;
  70. //now we'll add two edges, and the perfect matching has size 9
  71. ascii_graph.pop_back();
  72. ascii_graph.push_back(" 12---13 14---15 16---17 ");
  73. add_edge(12,13,g);
  74. add_edge(16,17,g);
  75. success = checked_edmonds_maximum_cardinality_matching(g, &mate[0]);
  76. assert(success);
  77. std::cout << "In the following graph:" << std::endl << std::endl;
  78. for(std::vector<std::string>::iterator itr = ascii_graph.begin(); itr != ascii_graph.end(); ++itr)
  79. std::cout << *itr << std::endl;
  80. std::cout << std::endl << "Found a matching of size " << matching_size(g, &mate[0]) << std::endl;
  81. std::cout << "The matching is:" << std::endl;
  82. for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
  83. if (mate[*vi] != graph_traits<my_graph>::null_vertex() && *vi < mate[*vi])
  84. std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl;
  85. return 0;
  86. }