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