3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
23 #include <lemon/smart_graph.h>
25 #include <lemon/bpugraph_adaptor.h>
26 #include <lemon/bipartite_matching.h>
27 #include <lemon/pr_bipartite_matching.h>
29 #include <lemon/graph_utils.h>
31 #include <lemon/maps.h>
33 #include "test_tools.h"
36 using namespace lemon;
38 typedef SmartBpUGraph Graph;
39 BPUGRAPH_TYPEDEFS(Graph);
46 const int sa[E] = { 6, 5, 6, 4, 1, 0, 9, 5, 2, 4, 4, 3, 5,
47 2, 3, 8, 3, 4, 9, 6, 9, 4, 3, 1, 5, 8,
48 4, 8, 9, 2, 2, 3, 0, 5, 2, 3, 6, 3, 8,
49 8, 4, 0, 9, 9, 6, 2, 1, 2, 7, 1, 9, 4};
51 const int ta[E] = { 2, 7, 4, 8, 6, 3, 4, 1, 7, 7, 0, 1, 6,
52 3, 2, 6, 8, 3, 5, 6, 3, 1, 8, 7, 2, 0,
53 6, 9, 6, 7, 8, 3, 3, 4, 5, 8, 6, 4, 1,
54 4, 3, 3, 8, 7, 7, 3, 7, 7, 3, 5, 1, 6};
56 const int wa[E] = { 3, 99, 85, 16, 79, 52, 83, 99, 62, 6, 42, 6, 95,
57 13, 34, 9, 5, 38, 39, 75, 99, 12, 73, 35, 93, 43,
58 54, 91, 45, 26, 77, 47, 11, 22, 50, 74, 37, 64, 91,
59 60, 6, 92, 29, 46, 34, 84, 67, 34, 45, 0, 39, 47};
67 Graph::UEdgeMap<int> weight(graph);
71 int max_cardinality_max_weight;
72 int min_cost_matching;
74 for (int i = 0; i < N; ++i) {
75 Node node = graph.addANode();
76 aNodes.push_back(node);
78 for (int i = 0; i < M; ++i) {
79 Node node = graph.addBNode();
80 bNodes.push_back(node);
82 for (int i = 0; i < E; ++i) {
83 Node aNode = aNodes[sa[i]];
84 Node bNode = bNodes[ta[i]];
85 UEdge uedge = graph.addEdge(aNode, bNode);
86 weight[uedge] = wa[i];
91 MaxBipartiteMatching<Graph> bpmatch(graph);
95 Graph::UEdgeMap<bool> mm(graph);
96 Graph::NodeMap<bool> cs(graph);
98 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
100 for (UEdgeIt it(graph); it != INVALID; ++it) {
101 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
104 for (ANodeIt it(graph); it != INVALID; ++it) {
106 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
109 check(num <= 1, "INVALID PRIMAL");
111 max_cardinality = bpmatch.matchingSize();
115 PrBipartiteMatching<Graph> bpmatch(graph);
119 Graph::UEdgeMap<bool> mm(graph);
120 Graph::NodeMap<bool> cs(graph);
122 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
124 for (UEdgeIt it(graph); it != INVALID; ++it) {
125 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
128 for (ANodeIt it(graph); it != INVALID; ++it) {
130 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
133 check(num <= 1, "INVALID PRIMAL");
135 max_cardinality = bpmatch.matchingSize();
139 Graph::UEdgeMap<bool> mm(graph);
141 check(max_cardinality == maxBipartiteMatching(graph, mm),
144 for (ANodeIt it(graph); it != INVALID; ++it) {
146 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
149 check(num <= 1, "INVALID PRIMAL");
154 MaxBipartiteMatching<Graph> bpmatch(graph);
156 bpmatch.greedyInit();
159 Graph::UEdgeMap<bool> mm(graph);
160 Graph::NodeMap<bool> cs(graph);
162 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
164 for (UEdgeIt it(graph); it != INVALID; ++it) {
165 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
168 for (ANodeIt it(graph); it != INVALID; ++it) {
170 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
173 check(num <= 1, "INVALID PRIMAL");
178 MaxBipartiteMatching<Graph> bpmatch(graph);
180 bpmatch.greedyInit();
181 while (bpmatch.simpleAugment());
183 Graph::UEdgeMap<bool> mm(graph);
184 Graph::NodeMap<bool> cs(graph);
186 check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
188 for (UEdgeIt it(graph); it != INVALID; ++it) {
189 check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
192 for (ANodeIt it(graph); it != INVALID; ++it) {
194 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
197 check(num <= 1, "INVALID PRIMAL");
202 MaxWeightedBipartiteMatching<Graph> bpmatch(graph, weight);
207 while (bpmatch.augment(true)) {
209 Graph::UEdgeMap<bool> mm(graph);
210 Graph::NodeMap<int> pm(graph);
212 bpmatch.matching(mm);
213 bpmatch.potential(pm);
215 for (UEdgeIt it(graph); it != INVALID; ++it) {
217 check(pm[graph.aNode(it)] + pm[graph.bNode(it)] - weight[it] == 0,
220 check(pm[graph.aNode(it)] + pm[graph.bNode(it)] - weight[it] >= 0,
225 for (ANodeIt it(graph); it != INVALID; ++it) {
227 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
230 check(num <= 1, "INVALID PRIMAL");
232 if (bpmatch.matchingValue() > max_weight) {
233 max_weight = bpmatch.matchingValue();
239 Graph::UEdgeMap<bool> mm(graph);
241 check(max_weight == maxWeightedBipartiteMatching(graph, weight, mm),
244 for (ANodeIt it(graph); it != INVALID; ++it) {
246 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
249 check(num <= 1, "INVALID PRIMAL");
254 MaxWeightedBipartiteMatching<Graph> bpmatch(graph, weight);
258 Graph::UEdgeMap<bool> mm(graph);
259 Graph::NodeMap<int> pm(graph);
261 bpmatch.matching(mm);
262 bpmatch.potential(pm);
264 for (UEdgeIt it(graph); it != INVALID; ++it) {
266 check(pm[graph.aNode(it)] + pm[graph.bNode(it)] - weight[it] == 0,
269 check(pm[graph.aNode(it)] + pm[graph.bNode(it)] - weight[it] >= 0,
274 for (ANodeIt it(graph); it != INVALID; ++it) {
276 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
279 check(num <= 1, "INVALID PRIMAL");
281 check(max_weight == bpmatch.matchingValue(), "WRONG WEIGHT");
285 MaxWeightedBipartiteMatching<Graph> bpmatch(graph, weight);
289 Graph::UEdgeMap<bool> mm(graph);
290 Graph::NodeMap<int> pm(graph);
292 bpmatch.matching(mm);
293 bpmatch.potential(pm);
295 for (UEdgeIt it(graph); it != INVALID; ++it) {
297 check(pm[graph.aNode(it)] + pm[graph.bNode(it)] - weight[it] == 0,
300 check(pm[graph.aNode(it)] + pm[graph.bNode(it)] - weight[it] >= 0,
305 for (ANodeIt it(graph); it != INVALID; ++it) {
307 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
310 check(num <= 1, "INVALID PRIMAL");
312 check(max_cardinality == bpmatch.matchingSize(), "WRONG SIZE");
313 max_cardinality_max_weight = bpmatch.matchingValue();
318 Graph::UEdgeMap<bool> mm(graph);
320 check(max_cardinality_max_weight ==
321 maxWeightedMaxBipartiteMatching(graph, weight, mm),
324 for (ANodeIt it(graph); it != INVALID; ++it) {
326 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
329 check(num <= 1, "INVALID PRIMAL");
333 Graph::UEdgeMap<int> cost(graph);
334 cost = subMap(constMap<UEdge>(C), weight);
337 MinCostMaxBipartiteMatching<Graph> bpmatch(graph, cost);
341 Graph::UEdgeMap<bool> mm(graph);
342 Graph::NodeMap<int> pm(graph);
344 bpmatch.matching(mm);
345 bpmatch.potential(pm);
347 min_cost_matching = bpmatch.matchingCost();
348 check(max_cardinality == bpmatch.matchingSize(), "WRONG SIZE");
349 check(max_cardinality * C - max_cardinality_max_weight
350 == bpmatch.matchingCost(), "WRONG SIZE");
352 for (UEdgeIt it(graph); it != INVALID; ++it) {
354 check(pm[graph.aNode(it)] + cost[it] - pm[graph.bNode(it)] == 0,
357 check(pm[graph.aNode(it)] + cost[it] - pm[graph.bNode(it)] >= 0,
362 for (ANodeIt it(graph); it != INVALID; ++it) {
364 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
367 check(num <= 1, "INVALID PRIMAL");
370 min_cost_matching = bpmatch.matchingCost();
371 check(max_cardinality == bpmatch.matchingSize(), "WRONG SIZE");
372 check(max_cardinality * C - max_cardinality_max_weight
373 == bpmatch.matchingCost(), "WRONG SIZE");
378 Graph::UEdgeMap<bool> mm(graph);
380 check(min_cost_matching ==
381 minCostMaxBipartiteMatching(graph, cost, mm),
384 for (ANodeIt it(graph); it != INVALID; ++it) {
386 for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
389 check(num <= 1, "INVALID PRIMAL");