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