5 #include <lemon/list_graph.h>
7 #include <lemon/bpugraph_adaptor.h>
8 #include <lemon/bipartite_matching.h>
10 #include <lemon/graph_utils.h>
12 #include <lemon/maps.h>
14 #include "test_tools.h"
17 using namespace lemon;
19 typedef ListBpUGraph Graph;
20 BPUGRAPH_TYPEDEFS(Graph);
22 int main(int argc, const char *argv[]) {
26 int n = argc > 1 ? atoi(argv[1]) : 100;
27 int m = argc > 2 ? atoi(argv[2]) : 100;
28 int e = argc > 3 ? atoi(argv[3]) : (int)((n+m) * log(n+m));
29 int c = argc > 4 ? atoi(argv[4]) : 100;
31 Graph::UEdgeMap<int> weight(graph);
35 int max_cardinality_max_weight;
37 for (int i = 0; i < n; ++i) {
38 Node node = graph.addANode();
39 aNodes.push_back(node);
41 for (int i = 0; i < m; ++i) {
42 Node node = graph.addBNode();
43 bNodes.push_back(node);
45 for (int i = 0; i < e; ++i) {
46 Node aNode = aNodes[urandom(n)];
47 Node bNode = bNodes[urandom(m)];
48 UEdge uedge = graph.addEdge(aNode, bNode);
49 weight[uedge] = urandom(c);
53 MaxBipartiteMatching<Graph> bpmatch(graph);
57 Graph::UEdgeMap<bool> mm(graph);
58 Graph::NodeMap<bool> cs(graph);
60 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
62 for (UEdgeIt it(graph); it != INVALID; ++it) {
63 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
66 for (ANodeIt it(graph); it != INVALID; ++it) {
68 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
71 check(num <= 1, "INVALID PRIMAL");
73 max_cardinality = bpmatch.matchingSize();
77 MaxBipartiteMatching<Graph> bpmatch(graph);
82 Graph::UEdgeMap<bool> mm(graph);
83 Graph::NodeMap<bool> cs(graph);
85 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
87 for (UEdgeIt it(graph); it != INVALID; ++it) {
88 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
91 for (ANodeIt it(graph); it != INVALID; ++it) {
93 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
96 check(num <= 1, "INVALID PRIMAL");
101 MaxBipartiteMatching<Graph> bpmatch(graph);
103 bpmatch.greedyInit();
104 while (bpmatch.simpleAugment());
106 Graph::UEdgeMap<bool> mm(graph);
107 Graph::NodeMap<bool> cs(graph);
109 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
111 for (UEdgeIt it(graph); it != INVALID; ++it) {
112 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
115 for (ANodeIt it(graph); it != INVALID; ++it) {
117 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
120 check(num <= 1, "INVALID PRIMAL");
125 MaxWeightedBipartiteMatching<Graph> bpmatch(graph, weight);
130 while (bpmatch.augment(true)) {
132 Graph::UEdgeMap<bool> mm(graph);
133 Graph::NodeMap<int> pm(graph);
135 bpmatch.matching(mm);
136 bpmatch.potential(pm);
138 for (UEdgeIt it(graph); it != INVALID; ++it) {
140 check(pm[graph.aNode(it)] - weight[it] - pm[graph.bNode(it)] == 0,
143 check(pm[graph.aNode(it)] - weight[it] - pm[graph.bNode(it)] >= 0,
148 for (ANodeIt it(graph); it != INVALID; ++it) {
150 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
153 check(num <= 1, "INVALID PRIMAL");
155 if (bpmatch.matchingValue() > max_weight) {
156 max_weight = bpmatch.matchingValue();
162 MaxWeightedBipartiteMatching<Graph> bpmatch(graph, weight);
166 Graph::UEdgeMap<bool> mm(graph);
167 Graph::NodeMap<int> pm(graph);
169 bpmatch.matching(mm);
170 bpmatch.potential(pm);
172 for (UEdgeIt it(graph); it != INVALID; ++it) {
174 check(pm[graph.aNode(it)] - weight[it] - pm[graph.bNode(it)] == 0,
177 check(pm[graph.aNode(it)] - weight[it] - pm[graph.bNode(it)] >= 0,
182 for (ANodeIt it(graph); it != INVALID; ++it) {
184 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
187 check(num <= 1, "INVALID PRIMAL");
189 check(max_weight == bpmatch.matchingValue(), "WRONG WEIGHT");
193 MaxWeightedBipartiteMatching<Graph> bpmatch(graph, weight);
197 Graph::UEdgeMap<bool> mm(graph);
198 Graph::NodeMap<int> pm(graph);
200 bpmatch.matching(mm);
201 bpmatch.potential(pm);
203 for (UEdgeIt it(graph); it != INVALID; ++it) {
205 check(pm[graph.aNode(it)] - weight[it] - pm[graph.bNode(it)] == 0,
208 check(pm[graph.aNode(it)] - weight[it] - pm[graph.bNode(it)] >= 0,
213 for (ANodeIt it(graph); it != INVALID; ++it) {
215 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
218 check(num <= 1, "INVALID PRIMAL");
220 check(max_cardinality == bpmatch.matchingSize(), "WRONG SIZE");
221 max_cardinality_max_weight = bpmatch.matchingValue();
226 Graph::UEdgeMap<int> cost(graph);
228 cost = subMap(constMap<UEdge>(c), weight);
230 MinCostMaxBipartiteMatching<Graph> bpmatch(graph, cost);
234 Graph::UEdgeMap<bool> mm(graph);
235 Graph::NodeMap<int> pm(graph);
237 bpmatch.matching(mm);
238 bpmatch.potential(pm);
240 for (UEdgeIt it(graph); it != INVALID; ++it) {
242 check(pm[graph.aNode(it)] + cost[it] - pm[graph.bNode(it)] == 0,
245 check(pm[graph.aNode(it)] + cost[it] - pm[graph.bNode(it)] >= 0,
250 for (ANodeIt it(graph); it != INVALID; ++it) {
252 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
255 check(num <= 1, "INVALID PRIMAL");
258 check(max_cardinality == bpmatch.matchingSize(), "WRONG SIZE");
259 check(max_cardinality * c - max_cardinality_max_weight
260 == bpmatch.matchingCost(), "WRONG SIZE");