gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Extend and modify the interface of matching algorithms (#265) - Rename decomposition() to status() in MaxMatching. - Add a new query function statusMap() to MaxMatching. - Add a new query function matchingMap() to all the three classes. - Rename matchingValue() to matchingWeight() in the weighted matching classes.
0 2 0
default
2 files changed with 70 insertions and 23 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_MAX_MATCHING_H
20 20
#define LEMON_MAX_MATCHING_H
21 21

	
22 22
#include <vector>
23 23
#include <queue>
24 24
#include <set>
25 25
#include <limits>
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/unionfind.h>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/maps.h>
31 31

	
32 32
///\ingroup matching
33 33
///\file
34 34
///\brief Maximum matching algorithms in general graphs.
35 35

	
36 36
namespace lemon {
37 37

	
38 38
  /// \ingroup matching
39 39
  ///
40 40
  /// \brief Maximum cardinality matching in general graphs
41 41
  ///
42 42
  /// This class implements Edmonds' alternating forest matching algorithm
43
  /// for finding a maximum cardinality matching in a general graph. 
43
  /// for finding a maximum cardinality matching in a general undirected graph.
44 44
  /// It can be started from an arbitrary initial matching 
45 45
  /// (the default is the empty one).
46 46
  ///
47 47
  /// The dual solution of the problem is a map of the nodes to
48 48
  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
49 49
  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
50 50
  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
51 51
  /// with factor-critical components, the nodes in \c ODD/A form the
52 52
  /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
53 53
  /// a perfect matching. The number of the factor-critical components
54 54
  /// minus the number of barrier nodes is a lower bound on the
55 55
  /// unmatched nodes, and the matching is optimal if and only if this bound is
56
  /// tight. This decomposition can be obtained by calling \c
57
  /// decomposition() after running the algorithm.
56
  /// tight. This decomposition can be obtained using \ref status() or
57
  /// \ref statusMap() after running the algorithm.
58 58
  ///
59
  /// \tparam GR The graph type the algorithm runs on.
59
  /// \tparam GR The undirected graph type the algorithm runs on.
60 60
  template <typename GR>
61 61
  class MaxMatching {
62 62
  public:
63 63

	
64 64
    /// The graph type of the algorithm
65 65
    typedef GR Graph;
66
    /// The type of the matching map
66 67
    typedef typename Graph::template NodeMap<typename Graph::Arc>
67 68
    MatchingMap;
68 69

	
69 70
    ///\brief Status constants for Gallai-Edmonds decomposition.
70 71
    ///
71 72
    ///These constants are used for indicating the Gallai-Edmonds 
72 73
    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
73 74
    ///induce a subgraph with factor-critical components, the nodes with
74 75
    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
75 76
    ///with status \c MATCHED (or \c C) induce a subgraph having a 
76 77
    ///perfect matching.
77 78
    enum Status {
78 79
      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
79 80
      D = 1,
80 81
      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
81 82
      C = 0,
82 83
      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
83 84
      A = -1,
84 85
      UNMATCHED = -2  ///< = -2.
85 86
    };
86 87

	
88
    /// The type of the status map
87 89
    typedef typename Graph::template NodeMap<Status> StatusMap;
88 90

	
89 91
  private:
90 92

	
91 93
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
92 94

	
93 95
    typedef UnionFindEnum<IntNodeMap> BlossomSet;
94 96
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
95 97
    typedef RangeMap<Node> NodeIntMap;
96 98
    typedef MatchingMap EarMap;
97 99
    typedef std::vector<Node> NodeQueue;
98 100

	
99 101
    const Graph& _graph;
100 102
    MatchingMap* _matching;
101 103
    StatusMap* _status;
102 104

	
103 105
    EarMap* _ear;
104 106

	
105 107
    IntNodeMap* _blossom_set_index;
106 108
    BlossomSet* _blossom_set;
107 109
    NodeIntMap* _blossom_rep;
108 110

	
109 111
    IntNodeMap* _tree_set_index;
110 112
    TreeSet* _tree_set;
111 113

	
112 114
    NodeQueue _node_queue;
113 115
    int _process, _postpone, _last;
114 116

	
115 117
    int _node_num;
116 118

	
117 119
  private:
118 120

	
119 121
    void createStructures() {
120 122
      _node_num = countNodes(_graph);
121 123
      if (!_matching) {
122 124
        _matching = new MatchingMap(_graph);
123 125
      }
124 126
      if (!_status) {
125 127
        _status = new StatusMap(_graph);
126 128
      }
127 129
      if (!_ear) {
128 130
        _ear = new EarMap(_graph);
129 131
      }
130 132
      if (!_blossom_set) {
131 133
        _blossom_set_index = new IntNodeMap(_graph);
132 134
        _blossom_set = new BlossomSet(*_blossom_set_index);
133 135
      }
134 136
      if (!_blossom_rep) {
135 137
        _blossom_rep = new NodeIntMap(_node_num);
136 138
      }
137 139
      if (!_tree_set) {
138 140
        _tree_set_index = new IntNodeMap(_graph);
139 141
        _tree_set = new TreeSet(*_tree_set_index);
140 142
      }
141 143
      _node_queue.resize(_node_num);
142 144
    }
143 145

	
144 146
    void destroyStructures() {
145 147
      if (_matching) {
146 148
        delete _matching;
147 149
      }
148 150
      if (_status) {
149 151
        delete _status;
150 152
      }
151 153
      if (_ear) {
152 154
        delete _ear;
153 155
      }
154 156
      if (_blossom_set) {
155 157
        delete _blossom_set;
156 158
        delete _blossom_set_index;
157 159
      }
158 160
      if (_blossom_rep) {
159 161
        delete _blossom_rep;
160 162
      }
161 163
      if (_tree_set) {
162 164
        delete _tree_set_index;
163 165
        delete _tree_set;
164 166
      }
165 167
    }
166 168

	
167 169
    void processDense(const Node& n) {
168 170
      _process = _postpone = _last = 0;
169 171
      _node_queue[_last++] = n;
170 172

	
171 173
      while (_process != _last) {
172 174
        Node u = _node_queue[_process++];
173 175
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
174 176
          Node v = _graph.target(a);
175 177
          if ((*_status)[v] == MATCHED) {
176 178
            extendOnArc(a);
177 179
          } else if ((*_status)[v] == UNMATCHED) {
178 180
            augmentOnArc(a);
179 181
            return;
180 182
          }
181 183
        }
182 184
      }
183 185

	
184 186
      while (_postpone != _last) {
185 187
        Node u = _node_queue[_postpone++];
186 188

	
187 189
        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
188 190
          Node v = _graph.target(a);
189 191

	
190 192
          if ((*_status)[v] == EVEN) {
191 193
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
192 194
              shrinkOnEdge(a);
193 195
            }
194 196
          }
195 197

	
196 198
          while (_process != _last) {
197 199
            Node w = _node_queue[_process++];
198 200
            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
199 201
              Node x = _graph.target(b);
200 202
              if ((*_status)[x] == MATCHED) {
201 203
                extendOnArc(b);
202 204
              } else if ((*_status)[x] == UNMATCHED) {
203 205
                augmentOnArc(b);
204 206
                return;
205 207
              }
206 208
            }
207 209
          }
208 210
        }
209 211
      }
210 212
    }
211 213

	
212 214
    void processSparse(const Node& n) {
213 215
      _process = _last = 0;
214 216
      _node_queue[_last++] = n;
215 217
      while (_process != _last) {
216 218
        Node u = _node_queue[_process++];
217 219
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
218 220
          Node v = _graph.target(a);
219 221

	
220 222
          if ((*_status)[v] == EVEN) {
221 223
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
222 224
              shrinkOnEdge(a);
223 225
            }
224 226
          } else if ((*_status)[v] == MATCHED) {
225 227
            extendOnArc(a);
226 228
          } else if ((*_status)[v] == UNMATCHED) {
227 229
            augmentOnArc(a);
228 230
            return;
229 231
          }
230 232
        }
231 233
      }
232 234
    }
233 235

	
234 236
    void shrinkOnEdge(const Edge& e) {
235 237
      Node nca = INVALID;
236 238

	
237 239
      {
238 240
        std::set<Node> left_set, right_set;
239 241

	
240 242
        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
241 243
        left_set.insert(left);
242 244

	
243 245
        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
244 246
        right_set.insert(right);
245 247

	
246 248
        while (true) {
247 249
          if ((*_matching)[left] == INVALID) break;
248 250
          left = _graph.target((*_matching)[left]);
249 251
          left = (*_blossom_rep)[_blossom_set->
250 252
                                 find(_graph.target((*_ear)[left]))];
251 253
          if (right_set.find(left) != right_set.end()) {
252 254
            nca = left;
253 255
            break;
254 256
          }
255 257
          left_set.insert(left);
256 258

	
257 259
          if ((*_matching)[right] == INVALID) break;
258 260
          right = _graph.target((*_matching)[right]);
259 261
          right = (*_blossom_rep)[_blossom_set->
260 262
                                  find(_graph.target((*_ear)[right]))];
261 263
          if (left_set.find(right) != left_set.end()) {
262 264
            nca = right;
263 265
            break;
264 266
          }
265 267
          right_set.insert(right);
266 268
        }
267 269

	
268 270
        if (nca == INVALID) {
269 271
          if ((*_matching)[left] == INVALID) {
270 272
            nca = right;
271 273
            while (left_set.find(nca) == left_set.end()) {
272 274
              nca = _graph.target((*_matching)[nca]);
273 275
              nca =(*_blossom_rep)[_blossom_set->
274 276
                                   find(_graph.target((*_ear)[nca]))];
275 277
            }
276 278
          } else {
277 279
            nca = left;
278 280
            while (right_set.find(nca) == right_set.end()) {
279 281
              nca = _graph.target((*_matching)[nca]);
280 282
              nca = (*_blossom_rep)[_blossom_set->
281 283
                                   find(_graph.target((*_ear)[nca]))];
282 284
            }
283 285
          }
284 286
        }
285 287
      }
286 288

	
287 289
      {
288 290

	
289 291
        Node node = _graph.u(e);
290 292
        Arc arc = _graph.direct(e, true);
291 293
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
292 294

	
293 295
        while (base != nca) {
294 296
          (*_ear)[node] = arc;
295 297

	
296 298
          Node n = node;
297 299
          while (n != base) {
298 300
            n = _graph.target((*_matching)[n]);
299 301
            Arc a = (*_ear)[n];
300 302
            n = _graph.target(a);
301 303
            (*_ear)[n] = _graph.oppositeArc(a);
302 304
          }
303 305
          node = _graph.target((*_matching)[base]);
304 306
          _tree_set->erase(base);
305 307
          _tree_set->erase(node);
306 308
          _blossom_set->insert(node, _blossom_set->find(base));
307 309
          (*_status)[node] = EVEN;
308 310
          _node_queue[_last++] = node;
309 311
          arc = _graph.oppositeArc((*_ear)[node]);
310 312
          node = _graph.target((*_ear)[node]);
311 313
          base = (*_blossom_rep)[_blossom_set->find(node)];
312 314
          _blossom_set->join(_graph.target(arc), base);
313 315
        }
314 316
      }
315 317

	
316 318
      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
317 319

	
318 320
      {
319 321

	
320 322
        Node node = _graph.v(e);
321 323
        Arc arc = _graph.direct(e, false);
322 324
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
323 325

	
324 326
        while (base != nca) {
325 327
          (*_ear)[node] = arc;
326 328

	
327 329
          Node n = node;
328 330
          while (n != base) {
329 331
            n = _graph.target((*_matching)[n]);
330 332
            Arc a = (*_ear)[n];
331 333
            n = _graph.target(a);
332 334
            (*_ear)[n] = _graph.oppositeArc(a);
333 335
          }
334 336
          node = _graph.target((*_matching)[base]);
335 337
          _tree_set->erase(base);
336 338
          _tree_set->erase(node);
337 339
          _blossom_set->insert(node, _blossom_set->find(base));
338 340
          (*_status)[node] = EVEN;
339 341
          _node_queue[_last++] = node;
340 342
          arc = _graph.oppositeArc((*_ear)[node]);
341 343
          node = _graph.target((*_ear)[node]);
342 344
          base = (*_blossom_rep)[_blossom_set->find(node)];
343 345
          _blossom_set->join(_graph.target(arc), base);
344 346
        }
345 347
      }
346 348

	
347 349
      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
348 350
    }
349 351

	
350 352
    void extendOnArc(const Arc& a) {
351 353
      Node base = _graph.source(a);
352 354
      Node odd = _graph.target(a);
353 355

	
354 356
      (*_ear)[odd] = _graph.oppositeArc(a);
355 357
      Node even = _graph.target((*_matching)[odd]);
356 358
      (*_blossom_rep)[_blossom_set->insert(even)] = even;
357 359
      (*_status)[odd] = ODD;
358 360
      (*_status)[even] = EVEN;
359 361
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
360 362
      _tree_set->insert(odd, tree);
361 363
      _tree_set->insert(even, tree);
362 364
      _node_queue[_last++] = even;
363 365

	
364 366
    }
365 367

	
366 368
    void augmentOnArc(const Arc& a) {
367 369
      Node even = _graph.source(a);
368 370
      Node odd = _graph.target(a);
369 371

	
370 372
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
371 373

	
372 374
      (*_matching)[odd] = _graph.oppositeArc(a);
373 375
      (*_status)[odd] = MATCHED;
374 376

	
375 377
      Arc arc = (*_matching)[even];
376 378
      (*_matching)[even] = a;
377 379

	
378 380
      while (arc != INVALID) {
379 381
        odd = _graph.target(arc);
380 382
        arc = (*_ear)[odd];
381 383
        even = _graph.target(arc);
382 384
        (*_matching)[odd] = arc;
383 385
        arc = (*_matching)[even];
384 386
        (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
385 387
      }
386 388

	
387 389
      for (typename TreeSet::ItemIt it(*_tree_set, tree);
388 390
           it != INVALID; ++it) {
389 391
        if ((*_status)[it] == ODD) {
390 392
          (*_status)[it] = MATCHED;
391 393
        } else {
392 394
          int blossom = _blossom_set->find(it);
393 395
          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
394 396
               jt != INVALID; ++jt) {
395 397
            (*_status)[jt] = MATCHED;
396 398
          }
397 399
          _blossom_set->eraseClass(blossom);
398 400
        }
399 401
      }
400 402
      _tree_set->eraseClass(tree);
401 403

	
402 404
    }
403 405

	
404 406
  public:
405 407

	
406 408
    /// \brief Constructor
407 409
    ///
408 410
    /// Constructor.
409 411
    MaxMatching(const Graph& graph)
410 412
      : _graph(graph), _matching(0), _status(0), _ear(0),
411 413
        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
412 414
        _tree_set_index(0), _tree_set(0) {}
413 415

	
414 416
    ~MaxMatching() {
415 417
      destroyStructures();
416 418
    }
417 419

	
418 420
    /// \name Execution Control
419 421
    /// The simplest way to execute the algorithm is to use the
420 422
    /// \c run() member function.\n
421 423
    /// If you need better control on the execution, you have to call
422 424
    /// one of the functions \ref init(), \ref greedyInit() or
423 425
    /// \ref matchingInit() first, then you can start the algorithm with
424 426
    /// \ref startSparse() or \ref startDense().
425 427

	
426 428
    ///@{
427 429

	
428 430
    /// \brief Set the initial matching to the empty matching.
429 431
    ///
430 432
    /// This function sets the initial matching to the empty matching.
431 433
    void init() {
432 434
      createStructures();
433 435
      for(NodeIt n(_graph); n != INVALID; ++n) {
434 436
        (*_matching)[n] = INVALID;
435 437
        (*_status)[n] = UNMATCHED;
436 438
      }
437 439
    }
438 440

	
439 441
    /// \brief Find an initial matching in a greedy way.
440 442
    ///
441 443
    /// This function finds an initial matching in a greedy way.
442 444
    void greedyInit() {
443 445
      createStructures();
444 446
      for (NodeIt n(_graph); n != INVALID; ++n) {
445 447
        (*_matching)[n] = INVALID;
446 448
        (*_status)[n] = UNMATCHED;
447 449
      }
448 450
      for (NodeIt n(_graph); n != INVALID; ++n) {
449 451
        if ((*_matching)[n] == INVALID) {
450 452
          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
451 453
            Node v = _graph.target(a);
452 454
            if ((*_matching)[v] == INVALID && v != n) {
453 455
              (*_matching)[n] = a;
454 456
              (*_status)[n] = MATCHED;
455 457
              (*_matching)[v] = _graph.oppositeArc(a);
456 458
              (*_status)[v] = MATCHED;
457 459
              break;
458 460
            }
459 461
          }
460 462
        }
461 463
      }
462 464
    }
463 465

	
464 466

	
465 467
    /// \brief Initialize the matching from a map.
466 468
    ///
467 469
    /// This function initializes the matching from a \c bool valued edge
468 470
    /// map. This map should have the property that there are no two incident
469 471
    /// edges with \c true value, i.e. it really contains a matching.
470 472
    /// \return \c true if the map contains a matching.
471 473
    template <typename MatchingMap>
472 474
    bool matchingInit(const MatchingMap& matching) {
473 475
      createStructures();
474 476

	
475 477
      for (NodeIt n(_graph); n != INVALID; ++n) {
476 478
        (*_matching)[n] = INVALID;
477 479
        (*_status)[n] = UNMATCHED;
478 480
      }
479 481
      for(EdgeIt e(_graph); e!=INVALID; ++e) {
480 482
        if (matching[e]) {
481 483

	
482 484
          Node u = _graph.u(e);
483 485
          if ((*_matching)[u] != INVALID) return false;
484 486
          (*_matching)[u] = _graph.direct(e, true);
485 487
          (*_status)[u] = MATCHED;
486 488

	
487 489
          Node v = _graph.v(e);
488 490
          if ((*_matching)[v] != INVALID) return false;
489 491
          (*_matching)[v] = _graph.direct(e, false);
490 492
          (*_status)[v] = MATCHED;
491 493
        }
492 494
      }
493 495
      return true;
494 496
    }
495 497

	
496 498
    /// \brief Start Edmonds' algorithm
497 499
    ///
498 500
    /// This function runs the original Edmonds' algorithm.
499 501
    ///
500 502
    /// \pre \ref Init(), \ref greedyInit() or \ref matchingInit() must be
501 503
    /// called before using this function.
502 504
    void startSparse() {
503 505
      for(NodeIt n(_graph); n != INVALID; ++n) {
504 506
        if ((*_status)[n] == UNMATCHED) {
505 507
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
506 508
          _tree_set->insert(n);
507 509
          (*_status)[n] = EVEN;
508 510
          processSparse(n);
509 511
        }
510 512
      }
511 513
    }
512 514

	
513 515
    /// \brief Start Edmonds' algorithm with a heuristic improvement 
514 516
    /// for dense graphs
515 517
    ///
516 518
    /// This function runs Edmonds' algorithm with a heuristic of postponing
517 519
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
518 520
    ///
519 521
    /// \pre \ref Init(), \ref greedyInit() or \ref matchingInit() must be
520 522
    /// called before using this function.
521 523
    void startDense() {
522 524
      for(NodeIt n(_graph); n != INVALID; ++n) {
523 525
        if ((*_status)[n] == UNMATCHED) {
524 526
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
525 527
          _tree_set->insert(n);
526 528
          (*_status)[n] = EVEN;
527 529
          processDense(n);
528 530
        }
529 531
      }
530 532
    }
531 533

	
532 534

	
533 535
    /// \brief Run Edmonds' algorithm
534 536
    ///
535 537
    /// This function runs Edmonds' algorithm. An additional heuristic of 
536 538
    /// postponing shrinks is used for relatively dense graphs 
537 539
    /// (for which <tt>m>=2*n</tt> holds).
538 540
    void run() {
539 541
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
540 542
        greedyInit();
541 543
        startSparse();
542 544
      } else {
543 545
        init();
544 546
        startDense();
545 547
      }
546 548
    }
547 549

	
548 550
    /// @}
549 551

	
550 552
    /// \name Primal Solution
551 553
    /// Functions to get the primal solution, i.e. the maximum matching.
552 554

	
553 555
    /// @{
554 556

	
555 557
    /// \brief Return the size (cardinality) of the matching.
556 558
    ///
557 559
    /// This function returns the size (cardinality) of the current matching. 
558 560
    /// After run() it returns the size of the maximum matching in the graph.
559 561
    int matchingSize() const {
560 562
      int size = 0;
561 563
      for (NodeIt n(_graph); n != INVALID; ++n) {
562 564
        if ((*_matching)[n] != INVALID) {
563 565
          ++size;
564 566
        }
565 567
      }
566 568
      return size / 2;
567 569
    }
568 570

	
569 571
    /// \brief Return \c true if the given edge is in the matching.
570 572
    ///
571 573
    /// This function returns \c true if the given edge is in the current 
572 574
    /// matching.
573 575
    bool matching(const Edge& edge) const {
574 576
      return edge == (*_matching)[_graph.u(edge)];
575 577
    }
576 578

	
577 579
    /// \brief Return the matching arc (or edge) incident to the given node.
578 580
    ///
579 581
    /// This function returns the matching arc (or edge) incident to the
580 582
    /// given node in the current matching or \c INVALID if the node is 
581 583
    /// not covered by the matching.
582 584
    Arc matching(const Node& n) const {
583 585
      return (*_matching)[n];
584 586
    }
585 587

	
588
    /// \brief Return a const reference to the matching map.
589
    ///
590
    /// This function returns a const reference to a node map that stores
591
    /// the matching arc (or edge) incident to each node.
592
    const MatchingMap& matchingMap() const {
593
      return *_matching;
594
    }
595

	
586 596
    /// \brief Return the mate of the given node.
587 597
    ///
588 598
    /// This function returns the mate of the given node in the current 
589 599
    /// matching or \c INVALID if the node is not covered by the matching.
590 600
    Node mate(const Node& n) const {
591 601
      return (*_matching)[n] != INVALID ?
592 602
        _graph.target((*_matching)[n]) : INVALID;
593 603
    }
594 604

	
595 605
    /// @}
596 606

	
597 607
    /// \name Dual Solution
598 608
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
599 609
    /// decomposition.
600 610

	
601 611
    /// @{
602 612

	
603 613
    /// \brief Return the status of the given node in the Edmonds-Gallai
604 614
    /// decomposition.
605 615
    ///
606 616
    /// This function returns the \ref Status "status" of the given node
607 617
    /// in the Edmonds-Gallai decomposition.
608
    Status decomposition(const Node& n) const {
618
    Status status(const Node& n) const {
609 619
      return (*_status)[n];
610 620
    }
611 621

	
622
    /// \brief Return a const reference to the status map, which stores
623
    /// the Edmonds-Gallai decomposition.
624
    ///
625
    /// This function returns a const reference to a node map that stores the
626
    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
627
    const StatusMap& statusMap() const {
628
      return *_status;
629
    }
630

	
612 631
    /// \brief Return \c true if the given node is in the barrier.
613 632
    ///
614 633
    /// This function returns \c true if the given node is in the barrier.
615 634
    bool barrier(const Node& n) const {
616 635
      return (*_status)[n] == ODD;
617 636
    }
618 637

	
619 638
    /// @}
620 639

	
621 640
  };
622 641

	
623 642
  /// \ingroup matching
624 643
  ///
625 644
  /// \brief Weighted matching in general graphs
626 645
  ///
627 646
  /// This class provides an efficient implementation of Edmond's
628 647
  /// maximum weighted matching algorithm. The implementation is based
629 648
  /// on extensive use of priority queues and provides
630 649
  /// \f$O(nm\log n)\f$ time complexity.
631 650
  ///
632 651
  /// The maximum weighted matching problem is to find a subset of the 
633 652
  /// edges in an undirected graph with maximum overall weight for which 
634 653
  /// each node has at most one incident edge.
635 654
  /// It can be formulated with the following linear program.
636 655
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
637 656
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
638 657
      \quad \forall B\in\mathcal{O}\f] */
639 658
  /// \f[x_e \ge 0\quad \forall e\in E\f]
640 659
  /// \f[\max \sum_{e\in E}x_ew_e\f]
641 660
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
642 661
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
643 662
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
644 663
  /// subsets of the nodes.
645 664
  ///
646 665
  /// The algorithm calculates an optimal matching and a proof of the
647 666
  /// optimality. The solution of the dual problem can be used to check
648 667
  /// the result of the algorithm. The dual linear problem is the
649 668
  /// following.
650 669
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
651 670
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
652 671
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
653 672
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
654 673
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
655 674
      \frac{\vert B \vert - 1}{2}z_B\f] */
656 675
  ///
657 676
  /// The algorithm can be executed with the run() function. 
658 677
  /// After it the matching (the primal solution) and the dual solution
659 678
  /// can be obtained using the query functions and the 
660 679
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
661 680
  /// which is able to iterate on the nodes of a blossom. 
662 681
  /// If the value type is integer, then the dual solution is multiplied
663 682
  /// by \ref MaxWeightedMatching::dualScale "4".
664 683
  ///
665
  /// \tparam GR The graph type the algorithm runs on.
684
  /// \tparam GR The undirected graph type the algorithm runs on.
666 685
  /// \tparam WM The type edge weight map. The default type is 
667 686
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
668 687
#ifdef DOXYGEN
669 688
  template <typename GR, typename WM>
670 689
#else
671 690
  template <typename GR,
672 691
            typename WM = typename GR::template EdgeMap<int> >
673 692
#endif
674 693
  class MaxWeightedMatching {
675 694
  public:
676 695

	
677 696
    /// The graph type of the algorithm
678 697
    typedef GR Graph;
679 698
    /// The type of the edge weight map
680 699
    typedef WM WeightMap;
681 700
    /// The value type of the edge weights
682 701
    typedef typename WeightMap::Value Value;
683 702

	
703
    /// The type of the matching map
684 704
    typedef typename Graph::template NodeMap<typename Graph::Arc>
685 705
    MatchingMap;
686 706

	
687 707
    /// \brief Scaling factor for dual solution
688 708
    ///
689 709
    /// Scaling factor for dual solution. It is equal to 4 or 1
690 710
    /// according to the value type.
691 711
    static const int dualScale =
692 712
      std::numeric_limits<Value>::is_integer ? 4 : 1;
693 713

	
694 714
  private:
695 715

	
696 716
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
697 717

	
698 718
    typedef typename Graph::template NodeMap<Value> NodePotential;
699 719
    typedef std::vector<Node> BlossomNodeList;
700 720

	
701 721
    struct BlossomVariable {
702 722
      int begin, end;
703 723
      Value value;
704 724

	
705 725
      BlossomVariable(int _begin, int _end, Value _value)
706 726
        : begin(_begin), end(_end), value(_value) {}
707 727

	
708 728
    };
709 729

	
710 730
    typedef std::vector<BlossomVariable> BlossomPotential;
711 731

	
712 732
    const Graph& _graph;
713 733
    const WeightMap& _weight;
714 734

	
715 735
    MatchingMap* _matching;
716 736

	
717 737
    NodePotential* _node_potential;
718 738

	
719 739
    BlossomPotential _blossom_potential;
720 740
    BlossomNodeList _blossom_node_list;
721 741

	
722 742
    int _node_num;
723 743
    int _blossom_num;
724 744

	
725 745
    typedef RangeMap<int> IntIntMap;
726 746

	
727 747
    enum Status {
728 748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
729 749
    };
730 750

	
731 751
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
732 752
    struct BlossomData {
733 753
      int tree;
734 754
      Status status;
735 755
      Arc pred, next;
736 756
      Value pot, offset;
737 757
      Node base;
738 758
    };
739 759

	
740 760
    IntNodeMap *_blossom_index;
741 761
    BlossomSet *_blossom_set;
742 762
    RangeMap<BlossomData>* _blossom_data;
743 763

	
744 764
    IntNodeMap *_node_index;
745 765
    IntArcMap *_node_heap_index;
746 766

	
747 767
    struct NodeData {
748 768

	
749 769
      NodeData(IntArcMap& node_heap_index)
750 770
        : heap(node_heap_index) {}
751 771

	
752 772
      int blossom;
753 773
      Value pot;
754 774
      BinHeap<Value, IntArcMap> heap;
755 775
      std::map<int, Arc> heap_index;
756 776

	
757 777
      int tree;
758 778
    };
759 779

	
760 780
    RangeMap<NodeData>* _node_data;
761 781

	
762 782
    typedef ExtendFindEnum<IntIntMap> TreeSet;
763 783

	
764 784
    IntIntMap *_tree_set_index;
765 785
    TreeSet *_tree_set;
766 786

	
767 787
    IntNodeMap *_delta1_index;
768 788
    BinHeap<Value, IntNodeMap> *_delta1;
769 789

	
770 790
    IntIntMap *_delta2_index;
771 791
    BinHeap<Value, IntIntMap> *_delta2;
772 792

	
773 793
    IntEdgeMap *_delta3_index;
774 794
    BinHeap<Value, IntEdgeMap> *_delta3;
775 795

	
776 796
    IntIntMap *_delta4_index;
777 797
    BinHeap<Value, IntIntMap> *_delta4;
778 798

	
779 799
    Value _delta_sum;
780 800

	
781 801
    void createStructures() {
782 802
      _node_num = countNodes(_graph);
783 803
      _blossom_num = _node_num * 3 / 2;
784 804

	
785 805
      if (!_matching) {
786 806
        _matching = new MatchingMap(_graph);
787 807
      }
788 808
      if (!_node_potential) {
789 809
        _node_potential = new NodePotential(_graph);
790 810
      }
791 811
      if (!_blossom_set) {
792 812
        _blossom_index = new IntNodeMap(_graph);
793 813
        _blossom_set = new BlossomSet(*_blossom_index);
794 814
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
795 815
      }
796 816

	
797 817
      if (!_node_index) {
798 818
        _node_index = new IntNodeMap(_graph);
799 819
        _node_heap_index = new IntArcMap(_graph);
800 820
        _node_data = new RangeMap<NodeData>(_node_num,
801 821
                                              NodeData(*_node_heap_index));
802 822
      }
803 823

	
804 824
      if (!_tree_set) {
805 825
        _tree_set_index = new IntIntMap(_blossom_num);
806 826
        _tree_set = new TreeSet(*_tree_set_index);
807 827
      }
808 828
      if (!_delta1) {
809 829
        _delta1_index = new IntNodeMap(_graph);
810 830
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
811 831
      }
812 832
      if (!_delta2) {
813 833
        _delta2_index = new IntIntMap(_blossom_num);
814 834
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
815 835
      }
816 836
      if (!_delta3) {
817 837
        _delta3_index = new IntEdgeMap(_graph);
818 838
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
819 839
      }
820 840
      if (!_delta4) {
821 841
        _delta4_index = new IntIntMap(_blossom_num);
822 842
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
823 843
      }
824 844
    }
825 845

	
826 846
    void destroyStructures() {
827 847
      _node_num = countNodes(_graph);
828 848
      _blossom_num = _node_num * 3 / 2;
829 849

	
830 850
      if (_matching) {
831 851
        delete _matching;
832 852
      }
833 853
      if (_node_potential) {
834 854
        delete _node_potential;
835 855
      }
836 856
      if (_blossom_set) {
837 857
        delete _blossom_index;
838 858
        delete _blossom_set;
839 859
        delete _blossom_data;
840 860
      }
841 861

	
842 862
      if (_node_index) {
843 863
        delete _node_index;
844 864
        delete _node_heap_index;
845 865
        delete _node_data;
846 866
      }
847 867

	
848 868
      if (_tree_set) {
849 869
        delete _tree_set_index;
850 870
        delete _tree_set;
851 871
      }
852 872
      if (_delta1) {
853 873
        delete _delta1_index;
854 874
        delete _delta1;
855 875
      }
856 876
      if (_delta2) {
857 877
        delete _delta2_index;
858 878
        delete _delta2;
859 879
      }
860 880
      if (_delta3) {
861 881
        delete _delta3_index;
862 882
        delete _delta3;
863 883
      }
864 884
      if (_delta4) {
865 885
        delete _delta4_index;
866 886
        delete _delta4;
867 887
      }
868 888
    }
869 889

	
870 890
    void matchedToEven(int blossom, int tree) {
871 891
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
872 892
        _delta2->erase(blossom);
873 893
      }
874 894

	
875 895
      if (!_blossom_set->trivial(blossom)) {
876 896
        (*_blossom_data)[blossom].pot -=
877 897
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
878 898
      }
879 899

	
880 900
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
881 901
           n != INVALID; ++n) {
882 902

	
883 903
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
884 904
        int ni = (*_node_index)[n];
885 905

	
886 906
        (*_node_data)[ni].heap.clear();
887 907
        (*_node_data)[ni].heap_index.clear();
888 908

	
889 909
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
890 910

	
891 911
        _delta1->push(n, (*_node_data)[ni].pot);
892 912

	
893 913
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
894 914
          Node v = _graph.source(e);
895 915
          int vb = _blossom_set->find(v);
896 916
          int vi = (*_node_index)[v];
897 917

	
898 918
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
899 919
            dualScale * _weight[e];
900 920

	
901 921
          if ((*_blossom_data)[vb].status == EVEN) {
902 922
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
903 923
              _delta3->push(e, rw / 2);
904 924
            }
905 925
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
906 926
            if (_delta3->state(e) != _delta3->IN_HEAP) {
907 927
              _delta3->push(e, rw);
908 928
            }
909 929
          } else {
910 930
            typename std::map<int, Arc>::iterator it =
911 931
              (*_node_data)[vi].heap_index.find(tree);
912 932

	
913 933
            if (it != (*_node_data)[vi].heap_index.end()) {
914 934
              if ((*_node_data)[vi].heap[it->second] > rw) {
915 935
                (*_node_data)[vi].heap.replace(it->second, e);
916 936
                (*_node_data)[vi].heap.decrease(e, rw);
917 937
                it->second = e;
918 938
              }
919 939
            } else {
920 940
              (*_node_data)[vi].heap.push(e, rw);
921 941
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
922 942
            }
923 943

	
924 944
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
925 945
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
926 946

	
927 947
              if ((*_blossom_data)[vb].status == MATCHED) {
928 948
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
929 949
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
930 950
                               (*_blossom_data)[vb].offset);
931 951
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
932 952
                           (*_blossom_data)[vb].offset){
933 953
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
934 954
                                   (*_blossom_data)[vb].offset);
935 955
                }
936 956
              }
937 957
            }
938 958
          }
939 959
        }
... ...
@@ -1576,759 +1596,768 @@
1576 1596
      } else {
1577 1597

	
1578 1598
        Value pot = (*_blossom_data)[blossom].pot;
1579 1599
        int bn = _blossom_node_list.size();
1580 1600

	
1581 1601
        std::vector<int> subblossoms;
1582 1602
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1583 1603
        int b = _blossom_set->find(base);
1584 1604
        int ib = -1;
1585 1605
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1586 1606
          if (subblossoms[i] == b) { ib = i; break; }
1587 1607
        }
1588 1608

	
1589 1609
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1590 1610
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1591 1611
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1592 1612

	
1593 1613
          Arc m = (*_blossom_data)[tb].next;
1594 1614
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1595 1615
          extractBlossom(tb, _graph.source(m), m);
1596 1616
        }
1597 1617
        extractBlossom(subblossoms[ib], base, matching);
1598 1618

	
1599 1619
        int en = _blossom_node_list.size();
1600 1620

	
1601 1621
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1602 1622
      }
1603 1623
    }
1604 1624

	
1605 1625
    void extractMatching() {
1606 1626
      std::vector<int> blossoms;
1607 1627
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1608 1628
        blossoms.push_back(c);
1609 1629
      }
1610 1630

	
1611 1631
      for (int i = 0; i < int(blossoms.size()); ++i) {
1612 1632
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1613 1633

	
1614 1634
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1615 1635
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1616 1636
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1617 1637
               n != INVALID; ++n) {
1618 1638
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1619 1639
          }
1620 1640

	
1621 1641
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1622 1642
          Node base = _graph.source(matching);
1623 1643
          extractBlossom(blossoms[i], base, matching);
1624 1644
        } else {
1625 1645
          Node base = (*_blossom_data)[blossoms[i]].base;
1626 1646
          extractBlossom(blossoms[i], base, INVALID);
1627 1647
        }
1628 1648
      }
1629 1649
    }
1630 1650

	
1631 1651
  public:
1632 1652

	
1633 1653
    /// \brief Constructor
1634 1654
    ///
1635 1655
    /// Constructor.
1636 1656
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1637 1657
      : _graph(graph), _weight(weight), _matching(0),
1638 1658
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1639 1659
        _node_num(0), _blossom_num(0),
1640 1660

	
1641 1661
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1642 1662
        _node_index(0), _node_heap_index(0), _node_data(0),
1643 1663
        _tree_set_index(0), _tree_set(0),
1644 1664

	
1645 1665
        _delta1_index(0), _delta1(0),
1646 1666
        _delta2_index(0), _delta2(0),
1647 1667
        _delta3_index(0), _delta3(0),
1648 1668
        _delta4_index(0), _delta4(0),
1649 1669

	
1650 1670
        _delta_sum() {}
1651 1671

	
1652 1672
    ~MaxWeightedMatching() {
1653 1673
      destroyStructures();
1654 1674
    }
1655 1675

	
1656 1676
    /// \name Execution Control
1657 1677
    /// The simplest way to execute the algorithm is to use the
1658 1678
    /// \ref run() member function.
1659 1679

	
1660 1680
    ///@{
1661 1681

	
1662 1682
    /// \brief Initialize the algorithm
1663 1683
    ///
1664 1684
    /// This function initializes the algorithm.
1665 1685
    void init() {
1666 1686
      createStructures();
1667 1687

	
1668 1688
      for (ArcIt e(_graph); e != INVALID; ++e) {
1669 1689
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1670 1690
      }
1671 1691
      for (NodeIt n(_graph); n != INVALID; ++n) {
1672 1692
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1673 1693
      }
1674 1694
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1675 1695
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1676 1696
      }
1677 1697
      for (int i = 0; i < _blossom_num; ++i) {
1678 1698
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1679 1699
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1680 1700
      }
1681 1701

	
1682 1702
      int index = 0;
1683 1703
      for (NodeIt n(_graph); n != INVALID; ++n) {
1684 1704
        Value max = 0;
1685 1705
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1686 1706
          if (_graph.target(e) == n) continue;
1687 1707
          if ((dualScale * _weight[e]) / 2 > max) {
1688 1708
            max = (dualScale * _weight[e]) / 2;
1689 1709
          }
1690 1710
        }
1691 1711
        (*_node_index)[n] = index;
1692 1712
        (*_node_data)[index].pot = max;
1693 1713
        _delta1->push(n, max);
1694 1714
        int blossom =
1695 1715
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1696 1716

	
1697 1717
        _tree_set->insert(blossom);
1698 1718

	
1699 1719
        (*_blossom_data)[blossom].status = EVEN;
1700 1720
        (*_blossom_data)[blossom].pred = INVALID;
1701 1721
        (*_blossom_data)[blossom].next = INVALID;
1702 1722
        (*_blossom_data)[blossom].pot = 0;
1703 1723
        (*_blossom_data)[blossom].offset = 0;
1704 1724
        ++index;
1705 1725
      }
1706 1726
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1707 1727
        int si = (*_node_index)[_graph.u(e)];
1708 1728
        int ti = (*_node_index)[_graph.v(e)];
1709 1729
        if (_graph.u(e) != _graph.v(e)) {
1710 1730
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1711 1731
                            dualScale * _weight[e]) / 2);
1712 1732
        }
1713 1733
      }
1714 1734
    }
1715 1735

	
1716 1736
    /// \brief Start the algorithm
1717 1737
    ///
1718 1738
    /// This function starts the algorithm.
1719 1739
    ///
1720 1740
    /// \pre \ref init() must be called before using this function.
1721 1741
    void start() {
1722 1742
      enum OpType {
1723 1743
        D1, D2, D3, D4
1724 1744
      };
1725 1745

	
1726 1746
      int unmatched = _node_num;
1727 1747
      while (unmatched > 0) {
1728 1748
        Value d1 = !_delta1->empty() ?
1729 1749
          _delta1->prio() : std::numeric_limits<Value>::max();
1730 1750

	
1731 1751
        Value d2 = !_delta2->empty() ?
1732 1752
          _delta2->prio() : std::numeric_limits<Value>::max();
1733 1753

	
1734 1754
        Value d3 = !_delta3->empty() ?
1735 1755
          _delta3->prio() : std::numeric_limits<Value>::max();
1736 1756

	
1737 1757
        Value d4 = !_delta4->empty() ?
1738 1758
          _delta4->prio() : std::numeric_limits<Value>::max();
1739 1759

	
1740 1760
        _delta_sum = d1; OpType ot = D1;
1741 1761
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1742 1762
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1743 1763
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1744 1764

	
1745 1765

	
1746 1766
        switch (ot) {
1747 1767
        case D1:
1748 1768
          {
1749 1769
            Node n = _delta1->top();
1750 1770
            unmatchNode(n);
1751 1771
            --unmatched;
1752 1772
          }
1753 1773
          break;
1754 1774
        case D2:
1755 1775
          {
1756 1776
            int blossom = _delta2->top();
1757 1777
            Node n = _blossom_set->classTop(blossom);
1758 1778
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1759 1779
            extendOnArc(e);
1760 1780
          }
1761 1781
          break;
1762 1782
        case D3:
1763 1783
          {
1764 1784
            Edge e = _delta3->top();
1765 1785

	
1766 1786
            int left_blossom = _blossom_set->find(_graph.u(e));
1767 1787
            int right_blossom = _blossom_set->find(_graph.v(e));
1768 1788

	
1769 1789
            if (left_blossom == right_blossom) {
1770 1790
              _delta3->pop();
1771 1791
            } else {
1772 1792
              int left_tree;
1773 1793
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1774 1794
                left_tree = _tree_set->find(left_blossom);
1775 1795
              } else {
1776 1796
                left_tree = -1;
1777 1797
                ++unmatched;
1778 1798
              }
1779 1799
              int right_tree;
1780 1800
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1781 1801
                right_tree = _tree_set->find(right_blossom);
1782 1802
              } else {
1783 1803
                right_tree = -1;
1784 1804
                ++unmatched;
1785 1805
              }
1786 1806

	
1787 1807
              if (left_tree == right_tree) {
1788 1808
                shrinkOnEdge(e, left_tree);
1789 1809
              } else {
1790 1810
                augmentOnEdge(e);
1791 1811
                unmatched -= 2;
1792 1812
              }
1793 1813
            }
1794 1814
          } break;
1795 1815
        case D4:
1796 1816
          splitBlossom(_delta4->top());
1797 1817
          break;
1798 1818
        }
1799 1819
      }
1800 1820
      extractMatching();
1801 1821
    }
1802 1822

	
1803 1823
    /// \brief Run the algorithm.
1804 1824
    ///
1805 1825
    /// This method runs the \c %MaxWeightedMatching algorithm.
1806 1826
    ///
1807 1827
    /// \note mwm.run() is just a shortcut of the following code.
1808 1828
    /// \code
1809 1829
    ///   mwm.init();
1810 1830
    ///   mwm.start();
1811 1831
    /// \endcode
1812 1832
    void run() {
1813 1833
      init();
1814 1834
      start();
1815 1835
    }
1816 1836

	
1817 1837
    /// @}
1818 1838

	
1819 1839
    /// \name Primal Solution
1820 1840
    /// Functions to get the primal solution, i.e. the maximum weighted 
1821 1841
    /// matching.\n
1822 1842
    /// Either \ref run() or \ref start() function should be called before
1823 1843
    /// using them.
1824 1844

	
1825 1845
    /// @{
1826 1846

	
1827 1847
    /// \brief Return the weight of the matching.
1828 1848
    ///
1829 1849
    /// This function returns the weight of the found matching.
1830 1850
    ///
1831 1851
    /// \pre Either run() or start() must be called before using this function.
1832
    Value matchingValue() const {
1852
    Value matchingWeight() const {
1833 1853
      Value sum = 0;
1834 1854
      for (NodeIt n(_graph); n != INVALID; ++n) {
1835 1855
        if ((*_matching)[n] != INVALID) {
1836 1856
          sum += _weight[(*_matching)[n]];
1837 1857
        }
1838 1858
      }
1839 1859
      return sum /= 2;
1840 1860
    }
1841 1861

	
1842 1862
    /// \brief Return the size (cardinality) of the matching.
1843 1863
    ///
1844 1864
    /// This function returns the size (cardinality) of the found matching.
1845 1865
    ///
1846 1866
    /// \pre Either run() or start() must be called before using this function.
1847 1867
    int matchingSize() const {
1848 1868
      int num = 0;
1849 1869
      for (NodeIt n(_graph); n != INVALID; ++n) {
1850 1870
        if ((*_matching)[n] != INVALID) {
1851 1871
          ++num;
1852 1872
        }
1853 1873
      }
1854 1874
      return num /= 2;
1855 1875
    }
1856 1876

	
1857 1877
    /// \brief Return \c true if the given edge is in the matching.
1858 1878
    ///
1859 1879
    /// This function returns \c true if the given edge is in the found 
1860 1880
    /// matching.
1861 1881
    ///
1862 1882
    /// \pre Either run() or start() must be called before using this function.
1863 1883
    bool matching(const Edge& edge) const {
1864 1884
      return edge == (*_matching)[_graph.u(edge)];
1865 1885
    }
1866 1886

	
1867 1887
    /// \brief Return the matching arc (or edge) incident to the given node.
1868 1888
    ///
1869 1889
    /// This function returns the matching arc (or edge) incident to the
1870 1890
    /// given node in the found matching or \c INVALID if the node is 
1871 1891
    /// not covered by the matching.
1872 1892
    ///
1873 1893
    /// \pre Either run() or start() must be called before using this function.
1874 1894
    Arc matching(const Node& node) const {
1875 1895
      return (*_matching)[node];
1876 1896
    }
1877 1897

	
1898
    /// \brief Return a const reference to the matching map.
1899
    ///
1900
    /// This function returns a const reference to a node map that stores
1901
    /// the matching arc (or edge) incident to each node.
1902
    const MatchingMap& matchingMap() const {
1903
      return *_matching;
1904
    }
1905

	
1878 1906
    /// \brief Return the mate of the given node.
1879 1907
    ///
1880 1908
    /// This function returns the mate of the given node in the found 
1881 1909
    /// matching or \c INVALID if the node is not covered by the matching.
1882 1910
    ///
1883 1911
    /// \pre Either run() or start() must be called before using this function.
1884 1912
    Node mate(const Node& node) const {
1885 1913
      return (*_matching)[node] != INVALID ?
1886 1914
        _graph.target((*_matching)[node]) : INVALID;
1887 1915
    }
1888 1916

	
1889 1917
    /// @}
1890 1918

	
1891 1919
    /// \name Dual Solution
1892 1920
    /// Functions to get the dual solution.\n
1893 1921
    /// Either \ref run() or \ref start() function should be called before
1894 1922
    /// using them.
1895 1923

	
1896 1924
    /// @{
1897 1925

	
1898 1926
    /// \brief Return the value of the dual solution.
1899 1927
    ///
1900 1928
    /// This function returns the value of the dual solution. 
1901 1929
    /// It should be equal to the primal value scaled by \ref dualScale 
1902 1930
    /// "dual scale".
1903 1931
    ///
1904 1932
    /// \pre Either run() or start() must be called before using this function.
1905 1933
    Value dualValue() const {
1906 1934
      Value sum = 0;
1907 1935
      for (NodeIt n(_graph); n != INVALID; ++n) {
1908 1936
        sum += nodeValue(n);
1909 1937
      }
1910 1938
      for (int i = 0; i < blossomNum(); ++i) {
1911 1939
        sum += blossomValue(i) * (blossomSize(i) / 2);
1912 1940
      }
1913 1941
      return sum;
1914 1942
    }
1915 1943

	
1916 1944
    /// \brief Return the dual value (potential) of the given node.
1917 1945
    ///
1918 1946
    /// This function returns the dual value (potential) of the given node.
1919 1947
    ///
1920 1948
    /// \pre Either run() or start() must be called before using this function.
1921 1949
    Value nodeValue(const Node& n) const {
1922 1950
      return (*_node_potential)[n];
1923 1951
    }
1924 1952

	
1925 1953
    /// \brief Return the number of the blossoms in the basis.
1926 1954
    ///
1927 1955
    /// This function returns the number of the blossoms in the basis.
1928 1956
    ///
1929 1957
    /// \pre Either run() or start() must be called before using this function.
1930 1958
    /// \see BlossomIt
1931 1959
    int blossomNum() const {
1932 1960
      return _blossom_potential.size();
1933 1961
    }
1934 1962

	
1935 1963
    /// \brief Return the number of the nodes in the given blossom.
1936 1964
    ///
1937 1965
    /// This function returns the number of the nodes in the given blossom.
1938 1966
    ///
1939 1967
    /// \pre Either run() or start() must be called before using this function.
1940 1968
    /// \see BlossomIt
1941 1969
    int blossomSize(int k) const {
1942 1970
      return _blossom_potential[k].end - _blossom_potential[k].begin;
1943 1971
    }
1944 1972

	
1945 1973
    /// \brief Return the dual value (ptential) of the given blossom.
1946 1974
    ///
1947 1975
    /// This function returns the dual value (ptential) of the given blossom.
1948 1976
    ///
1949 1977
    /// \pre Either run() or start() must be called before using this function.
1950 1978
    Value blossomValue(int k) const {
1951 1979
      return _blossom_potential[k].value;
1952 1980
    }
1953 1981

	
1954 1982
    /// \brief Iterator for obtaining the nodes of a blossom.
1955 1983
    ///
1956 1984
    /// This class provides an iterator for obtaining the nodes of the 
1957 1985
    /// given blossom. It lists a subset of the nodes.
1958 1986
    /// Before using this iterator, you must allocate a 
1959 1987
    /// MaxWeightedMatching class and execute it.
1960 1988
    class BlossomIt {
1961 1989
    public:
1962 1990

	
1963 1991
      /// \brief Constructor.
1964 1992
      ///
1965 1993
      /// Constructor to get the nodes of the given variable.
1966 1994
      ///
1967 1995
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
1968 1996
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
1969 1997
      /// called before initializing this iterator.
1970 1998
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
1971 1999
        : _algorithm(&algorithm)
1972 2000
      {
1973 2001
        _index = _algorithm->_blossom_potential[variable].begin;
1974 2002
        _last = _algorithm->_blossom_potential[variable].end;
1975 2003
      }
1976 2004

	
1977 2005
      /// \brief Conversion to \c Node.
1978 2006
      ///
1979 2007
      /// Conversion to \c Node.
1980 2008
      operator Node() const {
1981 2009
        return _algorithm->_blossom_node_list[_index];
1982 2010
      }
1983 2011

	
1984 2012
      /// \brief Increment operator.
1985 2013
      ///
1986 2014
      /// Increment operator.
1987 2015
      BlossomIt& operator++() {
1988 2016
        ++_index;
1989 2017
        return *this;
1990 2018
      }
1991 2019

	
1992 2020
      /// \brief Validity checking
1993 2021
      ///
1994 2022
      /// Checks whether the iterator is invalid.
1995 2023
      bool operator==(Invalid) const { return _index == _last; }
1996 2024

	
1997 2025
      /// \brief Validity checking
1998 2026
      ///
1999 2027
      /// Checks whether the iterator is valid.
2000 2028
      bool operator!=(Invalid) const { return _index != _last; }
2001 2029

	
2002 2030
    private:
2003 2031
      const MaxWeightedMatching* _algorithm;
2004 2032
      int _last;
2005 2033
      int _index;
2006 2034
    };
2007 2035

	
2008 2036
    /// @}
2009 2037

	
2010 2038
  };
2011 2039

	
2012 2040
  /// \ingroup matching
2013 2041
  ///
2014 2042
  /// \brief Weighted perfect matching in general graphs
2015 2043
  ///
2016 2044
  /// This class provides an efficient implementation of Edmond's
2017 2045
  /// maximum weighted perfect matching algorithm. The implementation
2018 2046
  /// is based on extensive use of priority queues and provides
2019 2047
  /// \f$O(nm\log n)\f$ time complexity.
2020 2048
  ///
2021 2049
  /// The maximum weighted perfect matching problem is to find a subset of 
2022 2050
  /// the edges in an undirected graph with maximum overall weight for which 
2023 2051
  /// each node has exactly one incident edge.
2024 2052
  /// It can be formulated with the following linear program.
2025 2053
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2026 2054
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2027 2055
      \quad \forall B\in\mathcal{O}\f] */
2028 2056
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2029 2057
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2030 2058
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2031 2059
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2032 2060
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2033 2061
  /// subsets of the nodes.
2034 2062
  ///
2035 2063
  /// The algorithm calculates an optimal matching and a proof of the
2036 2064
  /// optimality. The solution of the dual problem can be used to check
2037 2065
  /// the result of the algorithm. The dual linear problem is the
2038 2066
  /// following.
2039 2067
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2040 2068
      w_{uv} \quad \forall uv\in E\f] */
2041 2069
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2042 2070
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2043 2071
      \frac{\vert B \vert - 1}{2}z_B\f] */
2044 2072
  ///
2045 2073
  /// The algorithm can be executed with the run() function. 
2046 2074
  /// After it the matching (the primal solution) and the dual solution
2047 2075
  /// can be obtained using the query functions and the 
2048 2076
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2049 2077
  /// which is able to iterate on the nodes of a blossom. 
2050 2078
  /// If the value type is integer, then the dual solution is multiplied
2051 2079
  /// by \ref MaxWeightedMatching::dualScale "4".
2052 2080
  ///
2053
  /// \tparam GR The graph type the algorithm runs on.
2081
  /// \tparam GR The undirected graph type the algorithm runs on.
2054 2082
  /// \tparam WM The type edge weight map. The default type is 
2055 2083
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2056 2084
#ifdef DOXYGEN
2057 2085
  template <typename GR, typename WM>
2058 2086
#else
2059 2087
  template <typename GR,
2060 2088
            typename WM = typename GR::template EdgeMap<int> >
2061 2089
#endif
2062 2090
  class MaxWeightedPerfectMatching {
2063 2091
  public:
2064 2092

	
2065 2093
    /// The graph type of the algorithm
2066 2094
    typedef GR Graph;
2067 2095
    /// The type of the edge weight map
2068 2096
    typedef WM WeightMap;
2069 2097
    /// The value type of the edge weights
2070 2098
    typedef typename WeightMap::Value Value;
2071 2099

	
2072 2100
    /// \brief Scaling factor for dual solution
2073 2101
    ///
2074 2102
    /// Scaling factor for dual solution, it is equal to 4 or 1
2075 2103
    /// according to the value type.
2076 2104
    static const int dualScale =
2077 2105
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2078 2106

	
2107
    /// The type of the matching map
2079 2108
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2080 2109
    MatchingMap;
2081 2110

	
2082 2111
  private:
2083 2112

	
2084 2113
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2085 2114

	
2086 2115
    typedef typename Graph::template NodeMap<Value> NodePotential;
2087 2116
    typedef std::vector<Node> BlossomNodeList;
2088 2117

	
2089 2118
    struct BlossomVariable {
2090 2119
      int begin, end;
2091 2120
      Value value;
2092 2121

	
2093 2122
      BlossomVariable(int _begin, int _end, Value _value)
2094 2123
        : begin(_begin), end(_end), value(_value) {}
2095 2124

	
2096 2125
    };
2097 2126

	
2098 2127
    typedef std::vector<BlossomVariable> BlossomPotential;
2099 2128

	
2100 2129
    const Graph& _graph;
2101 2130
    const WeightMap& _weight;
2102 2131

	
2103 2132
    MatchingMap* _matching;
2104 2133

	
2105 2134
    NodePotential* _node_potential;
2106 2135

	
2107 2136
    BlossomPotential _blossom_potential;
2108 2137
    BlossomNodeList _blossom_node_list;
2109 2138

	
2110 2139
    int _node_num;
2111 2140
    int _blossom_num;
2112 2141

	
2113 2142
    typedef RangeMap<int> IntIntMap;
2114 2143

	
2115 2144
    enum Status {
2116 2145
      EVEN = -1, MATCHED = 0, ODD = 1
2117 2146
    };
2118 2147

	
2119 2148
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2120 2149
    struct BlossomData {
2121 2150
      int tree;
2122 2151
      Status status;
2123 2152
      Arc pred, next;
2124 2153
      Value pot, offset;
2125 2154
    };
2126 2155

	
2127 2156
    IntNodeMap *_blossom_index;
2128 2157
    BlossomSet *_blossom_set;
2129 2158
    RangeMap<BlossomData>* _blossom_data;
2130 2159

	
2131 2160
    IntNodeMap *_node_index;
2132 2161
    IntArcMap *_node_heap_index;
2133 2162

	
2134 2163
    struct NodeData {
2135 2164

	
2136 2165
      NodeData(IntArcMap& node_heap_index)
2137 2166
        : heap(node_heap_index) {}
2138 2167

	
2139 2168
      int blossom;
2140 2169
      Value pot;
2141 2170
      BinHeap<Value, IntArcMap> heap;
2142 2171
      std::map<int, Arc> heap_index;
2143 2172

	
2144 2173
      int tree;
2145 2174
    };
2146 2175

	
2147 2176
    RangeMap<NodeData>* _node_data;
2148 2177

	
2149 2178
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2150 2179

	
2151 2180
    IntIntMap *_tree_set_index;
2152 2181
    TreeSet *_tree_set;
2153 2182

	
2154 2183
    IntIntMap *_delta2_index;
2155 2184
    BinHeap<Value, IntIntMap> *_delta2;
2156 2185

	
2157 2186
    IntEdgeMap *_delta3_index;
2158 2187
    BinHeap<Value, IntEdgeMap> *_delta3;
2159 2188

	
2160 2189
    IntIntMap *_delta4_index;
2161 2190
    BinHeap<Value, IntIntMap> *_delta4;
2162 2191

	
2163 2192
    Value _delta_sum;
2164 2193

	
2165 2194
    void createStructures() {
2166 2195
      _node_num = countNodes(_graph);
2167 2196
      _blossom_num = _node_num * 3 / 2;
2168 2197

	
2169 2198
      if (!_matching) {
2170 2199
        _matching = new MatchingMap(_graph);
2171 2200
      }
2172 2201
      if (!_node_potential) {
2173 2202
        _node_potential = new NodePotential(_graph);
2174 2203
      }
2175 2204
      if (!_blossom_set) {
2176 2205
        _blossom_index = new IntNodeMap(_graph);
2177 2206
        _blossom_set = new BlossomSet(*_blossom_index);
2178 2207
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2179 2208
      }
2180 2209

	
2181 2210
      if (!_node_index) {
2182 2211
        _node_index = new IntNodeMap(_graph);
2183 2212
        _node_heap_index = new IntArcMap(_graph);
2184 2213
        _node_data = new RangeMap<NodeData>(_node_num,
2185 2214
                                            NodeData(*_node_heap_index));
2186 2215
      }
2187 2216

	
2188 2217
      if (!_tree_set) {
2189 2218
        _tree_set_index = new IntIntMap(_blossom_num);
2190 2219
        _tree_set = new TreeSet(*_tree_set_index);
2191 2220
      }
2192 2221
      if (!_delta2) {
2193 2222
        _delta2_index = new IntIntMap(_blossom_num);
2194 2223
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2195 2224
      }
2196 2225
      if (!_delta3) {
2197 2226
        _delta3_index = new IntEdgeMap(_graph);
2198 2227
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2199 2228
      }
2200 2229
      if (!_delta4) {
2201 2230
        _delta4_index = new IntIntMap(_blossom_num);
2202 2231
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2203 2232
      }
2204 2233
    }
2205 2234

	
2206 2235
    void destroyStructures() {
2207 2236
      _node_num = countNodes(_graph);
2208 2237
      _blossom_num = _node_num * 3 / 2;
2209 2238

	
2210 2239
      if (_matching) {
2211 2240
        delete _matching;
2212 2241
      }
2213 2242
      if (_node_potential) {
2214 2243
        delete _node_potential;
2215 2244
      }
2216 2245
      if (_blossom_set) {
2217 2246
        delete _blossom_index;
2218 2247
        delete _blossom_set;
2219 2248
        delete _blossom_data;
2220 2249
      }
2221 2250

	
2222 2251
      if (_node_index) {
2223 2252
        delete _node_index;
2224 2253
        delete _node_heap_index;
2225 2254
        delete _node_data;
2226 2255
      }
2227 2256

	
2228 2257
      if (_tree_set) {
2229 2258
        delete _tree_set_index;
2230 2259
        delete _tree_set;
2231 2260
      }
2232 2261
      if (_delta2) {
2233 2262
        delete _delta2_index;
2234 2263
        delete _delta2;
2235 2264
      }
2236 2265
      if (_delta3) {
2237 2266
        delete _delta3_index;
2238 2267
        delete _delta3;
2239 2268
      }
2240 2269
      if (_delta4) {
2241 2270
        delete _delta4_index;
2242 2271
        delete _delta4;
2243 2272
      }
2244 2273
    }
2245 2274

	
2246 2275
    void matchedToEven(int blossom, int tree) {
2247 2276
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2248 2277
        _delta2->erase(blossom);
2249 2278
      }
2250 2279

	
2251 2280
      if (!_blossom_set->trivial(blossom)) {
2252 2281
        (*_blossom_data)[blossom].pot -=
2253 2282
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2254 2283
      }
2255 2284

	
2256 2285
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2257 2286
           n != INVALID; ++n) {
2258 2287

	
2259 2288
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2260 2289
        int ni = (*_node_index)[n];
2261 2290

	
2262 2291
        (*_node_data)[ni].heap.clear();
2263 2292
        (*_node_data)[ni].heap_index.clear();
2264 2293

	
2265 2294
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
2266 2295

	
2267 2296
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2268 2297
          Node v = _graph.source(e);
2269 2298
          int vb = _blossom_set->find(v);
2270 2299
          int vi = (*_node_index)[v];
2271 2300

	
2272 2301
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2273 2302
            dualScale * _weight[e];
2274 2303

	
2275 2304
          if ((*_blossom_data)[vb].status == EVEN) {
2276 2305
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2277 2306
              _delta3->push(e, rw / 2);
2278 2307
            }
2279 2308
          } else {
2280 2309
            typename std::map<int, Arc>::iterator it =
2281 2310
              (*_node_data)[vi].heap_index.find(tree);
2282 2311

	
2283 2312
            if (it != (*_node_data)[vi].heap_index.end()) {
2284 2313
              if ((*_node_data)[vi].heap[it->second] > rw) {
2285 2314
                (*_node_data)[vi].heap.replace(it->second, e);
2286 2315
                (*_node_data)[vi].heap.decrease(e, rw);
2287 2316
                it->second = e;
2288 2317
              }
2289 2318
            } else {
2290 2319
              (*_node_data)[vi].heap.push(e, rw);
2291 2320
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2292 2321
            }
2293 2322

	
2294 2323
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2295 2324
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2296 2325

	
2297 2326
              if ((*_blossom_data)[vb].status == MATCHED) {
2298 2327
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2299 2328
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2300 2329
                               (*_blossom_data)[vb].offset);
2301 2330
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2302 2331
                           (*_blossom_data)[vb].offset){
2303 2332
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2304 2333
                                   (*_blossom_data)[vb].offset);
2305 2334
                }
2306 2335
              }
2307 2336
            }
2308 2337
          }
2309 2338
        }
2310 2339
      }
2311 2340
      (*_blossom_data)[blossom].offset = 0;
2312 2341
    }
2313 2342

	
2314 2343
    void matchedToOdd(int blossom) {
2315 2344
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2316 2345
        _delta2->erase(blossom);
2317 2346
      }
2318 2347
      (*_blossom_data)[blossom].offset += _delta_sum;
2319 2348
      if (!_blossom_set->trivial(blossom)) {
2320 2349
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
2321 2350
                     (*_blossom_data)[blossom].offset);
2322 2351
      }
2323 2352
    }
2324 2353

	
2325 2354
    void evenToMatched(int blossom, int tree) {
2326 2355
      if (!_blossom_set->trivial(blossom)) {
2327 2356
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
2328 2357
      }
2329 2358

	
2330 2359
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2331 2360
           n != INVALID; ++n) {
2332 2361
        int ni = (*_node_index)[n];
2333 2362
        (*_node_data)[ni].pot -= _delta_sum;
2334 2363

	
... ...
@@ -2785,423 +2814,431 @@
2785 2814
          (*_blossom_data)[sb].pred =
2786 2815
            _graph.oppositeArc((*_blossom_data)[tb].next);
2787 2816

	
2788 2817
          (*_blossom_data)[tb].status = EVEN;
2789 2818
          matchedToEven(tb, tree);
2790 2819
          _tree_set->insert(tb, tree);
2791 2820
          (*_blossom_data)[tb].pred =
2792 2821
            (*_blossom_data)[tb].next =
2793 2822
            _graph.oppositeArc((*_blossom_data)[ub].next);
2794 2823
          next = (*_blossom_data)[ub].next;
2795 2824
        }
2796 2825

	
2797 2826
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2798 2827
        matchedToOdd(subblossoms[ib]);
2799 2828
        _tree_set->insert(subblossoms[ib], tree);
2800 2829
        (*_blossom_data)[subblossoms[ib]].next = next;
2801 2830
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2802 2831
      }
2803 2832
      _tree_set->erase(blossom);
2804 2833
    }
2805 2834

	
2806 2835
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2807 2836
      if (_blossom_set->trivial(blossom)) {
2808 2837
        int bi = (*_node_index)[base];
2809 2838
        Value pot = (*_node_data)[bi].pot;
2810 2839

	
2811 2840
        (*_matching)[base] = matching;
2812 2841
        _blossom_node_list.push_back(base);
2813 2842
        (*_node_potential)[base] = pot;
2814 2843
      } else {
2815 2844

	
2816 2845
        Value pot = (*_blossom_data)[blossom].pot;
2817 2846
        int bn = _blossom_node_list.size();
2818 2847

	
2819 2848
        std::vector<int> subblossoms;
2820 2849
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2821 2850
        int b = _blossom_set->find(base);
2822 2851
        int ib = -1;
2823 2852
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2824 2853
          if (subblossoms[i] == b) { ib = i; break; }
2825 2854
        }
2826 2855

	
2827 2856
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2828 2857
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2829 2858
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2830 2859

	
2831 2860
          Arc m = (*_blossom_data)[tb].next;
2832 2861
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2833 2862
          extractBlossom(tb, _graph.source(m), m);
2834 2863
        }
2835 2864
        extractBlossom(subblossoms[ib], base, matching);
2836 2865

	
2837 2866
        int en = _blossom_node_list.size();
2838 2867

	
2839 2868
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2840 2869
      }
2841 2870
    }
2842 2871

	
2843 2872
    void extractMatching() {
2844 2873
      std::vector<int> blossoms;
2845 2874
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2846 2875
        blossoms.push_back(c);
2847 2876
      }
2848 2877

	
2849 2878
      for (int i = 0; i < int(blossoms.size()); ++i) {
2850 2879

	
2851 2880
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2852 2881
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2853 2882
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2854 2883
             n != INVALID; ++n) {
2855 2884
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2856 2885
        }
2857 2886

	
2858 2887
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2859 2888
        Node base = _graph.source(matching);
2860 2889
        extractBlossom(blossoms[i], base, matching);
2861 2890
      }
2862 2891
    }
2863 2892

	
2864 2893
  public:
2865 2894

	
2866 2895
    /// \brief Constructor
2867 2896
    ///
2868 2897
    /// Constructor.
2869 2898
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2870 2899
      : _graph(graph), _weight(weight), _matching(0),
2871 2900
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2872 2901
        _node_num(0), _blossom_num(0),
2873 2902

	
2874 2903
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2875 2904
        _node_index(0), _node_heap_index(0), _node_data(0),
2876 2905
        _tree_set_index(0), _tree_set(0),
2877 2906

	
2878 2907
        _delta2_index(0), _delta2(0),
2879 2908
        _delta3_index(0), _delta3(0),
2880 2909
        _delta4_index(0), _delta4(0),
2881 2910

	
2882 2911
        _delta_sum() {}
2883 2912

	
2884 2913
    ~MaxWeightedPerfectMatching() {
2885 2914
      destroyStructures();
2886 2915
    }
2887 2916

	
2888 2917
    /// \name Execution Control
2889 2918
    /// The simplest way to execute the algorithm is to use the
2890 2919
    /// \ref run() member function.
2891 2920

	
2892 2921
    ///@{
2893 2922

	
2894 2923
    /// \brief Initialize the algorithm
2895 2924
    ///
2896 2925
    /// This function initializes the algorithm.
2897 2926
    void init() {
2898 2927
      createStructures();
2899 2928

	
2900 2929
      for (ArcIt e(_graph); e != INVALID; ++e) {
2901 2930
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
2902 2931
      }
2903 2932
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2904 2933
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
2905 2934
      }
2906 2935
      for (int i = 0; i < _blossom_num; ++i) {
2907 2936
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
2908 2937
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
2909 2938
      }
2910 2939

	
2911 2940
      int index = 0;
2912 2941
      for (NodeIt n(_graph); n != INVALID; ++n) {
2913 2942
        Value max = - std::numeric_limits<Value>::max();
2914 2943
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2915 2944
          if (_graph.target(e) == n) continue;
2916 2945
          if ((dualScale * _weight[e]) / 2 > max) {
2917 2946
            max = (dualScale * _weight[e]) / 2;
2918 2947
          }
2919 2948
        }
2920 2949
        (*_node_index)[n] = index;
2921 2950
        (*_node_data)[index].pot = max;
2922 2951
        int blossom =
2923 2952
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
2924 2953

	
2925 2954
        _tree_set->insert(blossom);
2926 2955

	
2927 2956
        (*_blossom_data)[blossom].status = EVEN;
2928 2957
        (*_blossom_data)[blossom].pred = INVALID;
2929 2958
        (*_blossom_data)[blossom].next = INVALID;
2930 2959
        (*_blossom_data)[blossom].pot = 0;
2931 2960
        (*_blossom_data)[blossom].offset = 0;
2932 2961
        ++index;
2933 2962
      }
2934 2963
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2935 2964
        int si = (*_node_index)[_graph.u(e)];
2936 2965
        int ti = (*_node_index)[_graph.v(e)];
2937 2966
        if (_graph.u(e) != _graph.v(e)) {
2938 2967
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
2939 2968
                            dualScale * _weight[e]) / 2);
2940 2969
        }
2941 2970
      }
2942 2971
    }
2943 2972

	
2944 2973
    /// \brief Start the algorithm
2945 2974
    ///
2946 2975
    /// This function starts the algorithm.
2947 2976
    ///
2948 2977
    /// \pre \ref init() must be called before using this function.
2949 2978
    bool start() {
2950 2979
      enum OpType {
2951 2980
        D2, D3, D4
2952 2981
      };
2953 2982

	
2954 2983
      int unmatched = _node_num;
2955 2984
      while (unmatched > 0) {
2956 2985
        Value d2 = !_delta2->empty() ?
2957 2986
          _delta2->prio() : std::numeric_limits<Value>::max();
2958 2987

	
2959 2988
        Value d3 = !_delta3->empty() ?
2960 2989
          _delta3->prio() : std::numeric_limits<Value>::max();
2961 2990

	
2962 2991
        Value d4 = !_delta4->empty() ?
2963 2992
          _delta4->prio() : std::numeric_limits<Value>::max();
2964 2993

	
2965 2994
        _delta_sum = d2; OpType ot = D2;
2966 2995
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2967 2996
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2968 2997

	
2969 2998
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2970 2999
          return false;
2971 3000
        }
2972 3001

	
2973 3002
        switch (ot) {
2974 3003
        case D2:
2975 3004
          {
2976 3005
            int blossom = _delta2->top();
2977 3006
            Node n = _blossom_set->classTop(blossom);
2978 3007
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
2979 3008
            extendOnArc(e);
2980 3009
          }
2981 3010
          break;
2982 3011
        case D3:
2983 3012
          {
2984 3013
            Edge e = _delta3->top();
2985 3014

	
2986 3015
            int left_blossom = _blossom_set->find(_graph.u(e));
2987 3016
            int right_blossom = _blossom_set->find(_graph.v(e));
2988 3017

	
2989 3018
            if (left_blossom == right_blossom) {
2990 3019
              _delta3->pop();
2991 3020
            } else {
2992 3021
              int left_tree = _tree_set->find(left_blossom);
2993 3022
              int right_tree = _tree_set->find(right_blossom);
2994 3023

	
2995 3024
              if (left_tree == right_tree) {
2996 3025
                shrinkOnEdge(e, left_tree);
2997 3026
              } else {
2998 3027
                augmentOnEdge(e);
2999 3028
                unmatched -= 2;
3000 3029
              }
3001 3030
            }
3002 3031
          } break;
3003 3032
        case D4:
3004 3033
          splitBlossom(_delta4->top());
3005 3034
          break;
3006 3035
        }
3007 3036
      }
3008 3037
      extractMatching();
3009 3038
      return true;
3010 3039
    }
3011 3040

	
3012 3041
    /// \brief Run the algorithm.
3013 3042
    ///
3014 3043
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3015 3044
    ///
3016 3045
    /// \note mwpm.run() is just a shortcut of the following code.
3017 3046
    /// \code
3018 3047
    ///   mwpm.init();
3019 3048
    ///   mwpm.start();
3020 3049
    /// \endcode
3021 3050
    bool run() {
3022 3051
      init();
3023 3052
      return start();
3024 3053
    }
3025 3054

	
3026 3055
    /// @}
3027 3056

	
3028 3057
    /// \name Primal Solution
3029 3058
    /// Functions to get the primal solution, i.e. the maximum weighted 
3030 3059
    /// perfect matching.\n
3031 3060
    /// Either \ref run() or \ref start() function should be called before
3032 3061
    /// using them.
3033 3062

	
3034 3063
    /// @{
3035 3064

	
3036 3065
    /// \brief Return the weight of the matching.
3037 3066
    ///
3038 3067
    /// This function returns the weight of the found matching.
3039 3068
    ///
3040 3069
    /// \pre Either run() or start() must be called before using this function.
3041
    Value matchingValue() const {
3070
    Value matchingWeight() const {
3042 3071
      Value sum = 0;
3043 3072
      for (NodeIt n(_graph); n != INVALID; ++n) {
3044 3073
        if ((*_matching)[n] != INVALID) {
3045 3074
          sum += _weight[(*_matching)[n]];
3046 3075
        }
3047 3076
      }
3048 3077
      return sum /= 2;
3049 3078
    }
3050 3079

	
3051 3080
    /// \brief Return \c true if the given edge is in the matching.
3052 3081
    ///
3053 3082
    /// This function returns \c true if the given edge is in the found 
3054 3083
    /// matching.
3055 3084
    ///
3056 3085
    /// \pre Either run() or start() must be called before using this function.
3057 3086
    bool matching(const Edge& edge) const {
3058 3087
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3059 3088
    }
3060 3089

	
3061 3090
    /// \brief Return the matching arc (or edge) incident to the given node.
3062 3091
    ///
3063 3092
    /// This function returns the matching arc (or edge) incident to the
3064 3093
    /// given node in the found matching or \c INVALID if the node is 
3065 3094
    /// not covered by the matching.
3066 3095
    ///
3067 3096
    /// \pre Either run() or start() must be called before using this function.
3068 3097
    Arc matching(const Node& node) const {
3069 3098
      return (*_matching)[node];
3070 3099
    }
3071 3100

	
3101
    /// \brief Return a const reference to the matching map.
3102
    ///
3103
    /// This function returns a const reference to a node map that stores
3104
    /// the matching arc (or edge) incident to each node.
3105
    const MatchingMap& matchingMap() const {
3106
      return *_matching;
3107
    }
3108

	
3072 3109
    /// \brief Return the mate of the given node.
3073 3110
    ///
3074 3111
    /// This function returns the mate of the given node in the found 
3075 3112
    /// matching or \c INVALID if the node is not covered by the matching.
3076 3113
    ///
3077 3114
    /// \pre Either run() or start() must be called before using this function.
3078 3115
    Node mate(const Node& node) const {
3079 3116
      return _graph.target((*_matching)[node]);
3080 3117
    }
3081 3118

	
3082 3119
    /// @}
3083 3120

	
3084 3121
    /// \name Dual Solution
3085 3122
    /// Functions to get the dual solution.\n
3086 3123
    /// Either \ref run() or \ref start() function should be called before
3087 3124
    /// using them.
3088 3125

	
3089 3126
    /// @{
3090 3127

	
3091 3128
    /// \brief Return the value of the dual solution.
3092 3129
    ///
3093 3130
    /// This function returns the value of the dual solution. 
3094 3131
    /// It should be equal to the primal value scaled by \ref dualScale 
3095 3132
    /// "dual scale".
3096 3133
    ///
3097 3134
    /// \pre Either run() or start() must be called before using this function.
3098 3135
    Value dualValue() const {
3099 3136
      Value sum = 0;
3100 3137
      for (NodeIt n(_graph); n != INVALID; ++n) {
3101 3138
        sum += nodeValue(n);
3102 3139
      }
3103 3140
      for (int i = 0; i < blossomNum(); ++i) {
3104 3141
        sum += blossomValue(i) * (blossomSize(i) / 2);
3105 3142
      }
3106 3143
      return sum;
3107 3144
    }
3108 3145

	
3109 3146
    /// \brief Return the dual value (potential) of the given node.
3110 3147
    ///
3111 3148
    /// This function returns the dual value (potential) of the given node.
3112 3149
    ///
3113 3150
    /// \pre Either run() or start() must be called before using this function.
3114 3151
    Value nodeValue(const Node& n) const {
3115 3152
      return (*_node_potential)[n];
3116 3153
    }
3117 3154

	
3118 3155
    /// \brief Return the number of the blossoms in the basis.
3119 3156
    ///
3120 3157
    /// This function returns the number of the blossoms in the basis.
3121 3158
    ///
3122 3159
    /// \pre Either run() or start() must be called before using this function.
3123 3160
    /// \see BlossomIt
3124 3161
    int blossomNum() const {
3125 3162
      return _blossom_potential.size();
3126 3163
    }
3127 3164

	
3128 3165
    /// \brief Return the number of the nodes in the given blossom.
3129 3166
    ///
3130 3167
    /// This function returns the number of the nodes in the given blossom.
3131 3168
    ///
3132 3169
    /// \pre Either run() or start() must be called before using this function.
3133 3170
    /// \see BlossomIt
3134 3171
    int blossomSize(int k) const {
3135 3172
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3136 3173
    }
3137 3174

	
3138 3175
    /// \brief Return the dual value (ptential) of the given blossom.
3139 3176
    ///
3140 3177
    /// This function returns the dual value (ptential) of the given blossom.
3141 3178
    ///
3142 3179
    /// \pre Either run() or start() must be called before using this function.
3143 3180
    Value blossomValue(int k) const {
3144 3181
      return _blossom_potential[k].value;
3145 3182
    }
3146 3183

	
3147 3184
    /// \brief Iterator for obtaining the nodes of a blossom.
3148 3185
    ///
3149 3186
    /// This class provides an iterator for obtaining the nodes of the 
3150 3187
    /// given blossom. It lists a subset of the nodes.
3151 3188
    /// Before using this iterator, you must allocate a 
3152 3189
    /// MaxWeightedPerfectMatching class and execute it.
3153 3190
    class BlossomIt {
3154 3191
    public:
3155 3192

	
3156 3193
      /// \brief Constructor.
3157 3194
      ///
3158 3195
      /// Constructor to get the nodes of the given variable.
3159 3196
      ///
3160 3197
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
3161 3198
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
3162 3199
      /// must be called before initializing this iterator.
3163 3200
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3164 3201
        : _algorithm(&algorithm)
3165 3202
      {
3166 3203
        _index = _algorithm->_blossom_potential[variable].begin;
3167 3204
        _last = _algorithm->_blossom_potential[variable].end;
3168 3205
      }
3169 3206

	
3170 3207
      /// \brief Conversion to \c Node.
3171 3208
      ///
3172 3209
      /// Conversion to \c Node.
3173 3210
      operator Node() const {
3174 3211
        return _algorithm->_blossom_node_list[_index];
3175 3212
      }
3176 3213

	
3177 3214
      /// \brief Increment operator.
3178 3215
      ///
3179 3216
      /// Increment operator.
3180 3217
      BlossomIt& operator++() {
3181 3218
        ++_index;
3182 3219
        return *this;
3183 3220
      }
3184 3221

	
3185 3222
      /// \brief Validity checking
3186 3223
      ///
3187 3224
      /// This function checks whether the iterator is invalid.
3188 3225
      bool operator==(Invalid) const { return _index == _last; }
3189 3226

	
3190 3227
      /// \brief Validity checking
3191 3228
      ///
3192 3229
      /// This function checks whether the iterator is valid.
3193 3230
      bool operator!=(Invalid) const { return _index != _last; }
3194 3231

	
3195 3232
    private:
3196 3233
      const MaxWeightedPerfectMatching* _algorithm;
3197 3234
      int _last;
3198 3235
      int _index;
3199 3236
    };
3200 3237

	
3201 3238
    /// @}
3202 3239

	
3203 3240
  };
3204 3241

	
3205 3242
} //END OF NAMESPACE LEMON
3206 3243

	
3207 3244
#endif //LEMON_MAX_MATCHING_H
Ignore white space 512 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <sstream>
21 21
#include <vector>
22 22
#include <queue>
23 23
#include <cstdlib>
24 24

	
25 25
#include <lemon/max_matching.h>
26 26
#include <lemon/smart_graph.h>
27 27
#include <lemon/concepts/graph.h>
28 28
#include <lemon/concepts/maps.h>
29 29
#include <lemon/lgf_reader.h>
30 30
#include <lemon/math.h>
31 31

	
32 32
#include "test_tools.h"
33 33

	
34 34
using namespace std;
35 35
using namespace lemon;
36 36

	
37 37
GRAPH_TYPEDEFS(SmartGraph);
38 38

	
39 39

	
40 40
const int lgfn = 3;
41 41
const std::string lgf[lgfn] = {
42 42
  "@nodes\n"
43 43
  "label\n"
44 44
  "0\n"
45 45
  "1\n"
46 46
  "2\n"
47 47
  "3\n"
48 48
  "4\n"
49 49
  "5\n"
50 50
  "6\n"
51 51
  "7\n"
52 52
  "@edges\n"
53 53
  "     label  weight\n"
54 54
  "7 4  0      984\n"
55 55
  "0 7  1      73\n"
56 56
  "7 1  2      204\n"
57 57
  "2 3  3      583\n"
58 58
  "2 7  4      565\n"
59 59
  "2 1  5      582\n"
60 60
  "0 4  6      551\n"
61 61
  "2 5  7      385\n"
62 62
  "1 5  8      561\n"
63 63
  "5 3  9      484\n"
64 64
  "7 5  10     904\n"
65 65
  "3 6  11     47\n"
66 66
  "7 6  12     888\n"
67 67
  "3 0  13     747\n"
68 68
  "6 1  14     310\n",
69 69

	
70 70
  "@nodes\n"
71 71
  "label\n"
72 72
  "0\n"
73 73
  "1\n"
74 74
  "2\n"
75 75
  "3\n"
76 76
  "4\n"
77 77
  "5\n"
78 78
  "6\n"
79 79
  "7\n"
80 80
  "@edges\n"
81 81
  "     label  weight\n"
82 82
  "2 5  0      710\n"
83 83
  "0 5  1      241\n"
84 84
  "2 4  2      856\n"
85 85
  "2 6  3      762\n"
86 86
  "4 1  4      747\n"
87 87
  "6 1  5      962\n"
88 88
  "4 7  6      723\n"
89 89
  "1 7  7      661\n"
90 90
  "2 3  8      376\n"
91 91
  "1 0  9      416\n"
92 92
  "6 7  10     391\n",
93 93

	
94 94
  "@nodes\n"
95 95
  "label\n"
96 96
  "0\n"
97 97
  "1\n"
98 98
  "2\n"
99 99
  "3\n"
100 100
  "4\n"
101 101
  "5\n"
102 102
  "6\n"
103 103
  "7\n"
104 104
  "@edges\n"
105 105
  "     label  weight\n"
106 106
  "6 2  0      553\n"
107 107
  "0 7  1      653\n"
108 108
  "6 3  2      22\n"
109 109
  "4 7  3      846\n"
110 110
  "7 2  4      981\n"
111 111
  "7 6  5      250\n"
112 112
  "5 2  6      539\n",
113 113
};
114 114

	
115 115
void checkMaxMatchingCompile()
116 116
{
117 117
  typedef concepts::Graph Graph;
118 118
  typedef Graph::Node Node;
119 119
  typedef Graph::Edge Edge;
120 120
  typedef Graph::EdgeMap<bool> MatMap;
121 121

	
122 122
  Graph g;
123 123
  Node n;
124 124
  Edge e;
125 125
  MatMap mat(g);
126 126

	
127 127
  MaxMatching<Graph> mat_test(g);
128 128
  const MaxMatching<Graph>&
129 129
    const_mat_test = mat_test;
130 130

	
131 131
  mat_test.init();
132 132
  mat_test.greedyInit();
133 133
  mat_test.matchingInit(mat);
134 134
  mat_test.startSparse();
135 135
  mat_test.startDense();
136 136
  mat_test.run();
137 137
  
138 138
  const_mat_test.matchingSize();
139 139
  const_mat_test.matching(e);
140 140
  const_mat_test.matching(n);
141
  const MaxMatching<Graph>::MatchingMap& mmap =
142
    const_mat_test.matchingMap();
143
  e = mmap[n];
141 144
  const_mat_test.mate(n);
142 145

	
143 146
  MaxMatching<Graph>::Status stat = 
144
    const_mat_test.decomposition(n);
147
    const_mat_test.status(n);
148
  const MaxMatching<Graph>::StatusMap& smap =
149
    const_mat_test.statusMap();
150
  stat = smap[n];
145 151
  const_mat_test.barrier(n);
146
  
147
  ignore_unused_variable_warning(stat);
148 152
}
149 153

	
150 154
void checkMaxWeightedMatchingCompile()
151 155
{
152 156
  typedef concepts::Graph Graph;
153 157
  typedef Graph::Node Node;
154 158
  typedef Graph::Edge Edge;
155 159
  typedef Graph::EdgeMap<int> WeightMap;
156 160

	
157 161
  Graph g;
158 162
  Node n;
159 163
  Edge e;
160 164
  WeightMap w(g);
161 165

	
162 166
  MaxWeightedMatching<Graph> mat_test(g, w);
163 167
  const MaxWeightedMatching<Graph>&
164 168
    const_mat_test = mat_test;
165 169

	
166 170
  mat_test.init();
167 171
  mat_test.start();
168 172
  mat_test.run();
169 173
  
170
  const_mat_test.matchingValue();
174
  const_mat_test.matchingWeight();
171 175
  const_mat_test.matchingSize();
172 176
  const_mat_test.matching(e);
173 177
  const_mat_test.matching(n);
178
  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
179
    const_mat_test.matchingMap();
180
  e = mmap[n];
174 181
  const_mat_test.mate(n);
175 182
  
176 183
  int k = 0;
177 184
  const_mat_test.dualValue();
178 185
  const_mat_test.nodeValue(n);
179 186
  const_mat_test.blossomNum();
180 187
  const_mat_test.blossomSize(k);
181 188
  const_mat_test.blossomValue(k);
182 189
}
183 190

	
184 191
void checkMaxWeightedPerfectMatchingCompile()
185 192
{
186 193
  typedef concepts::Graph Graph;
187 194
  typedef Graph::Node Node;
188 195
  typedef Graph::Edge Edge;
189 196
  typedef Graph::EdgeMap<int> WeightMap;
190 197

	
191 198
  Graph g;
192 199
  Node n;
193 200
  Edge e;
194 201
  WeightMap w(g);
195 202

	
196 203
  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
197 204
  const MaxWeightedPerfectMatching<Graph>&
198 205
    const_mat_test = mat_test;
199 206

	
200 207
  mat_test.init();
201 208
  mat_test.start();
202 209
  mat_test.run();
203 210
  
204
  const_mat_test.matchingValue();
211
  const_mat_test.matchingWeight();
205 212
  const_mat_test.matching(e);
206 213
  const_mat_test.matching(n);
214
  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
215
    const_mat_test.matchingMap();
216
  e = mmap[n];
207 217
  const_mat_test.mate(n);
208 218
  
209 219
  int k = 0;
210 220
  const_mat_test.dualValue();
211 221
  const_mat_test.nodeValue(n);
212 222
  const_mat_test.blossomNum();
213 223
  const_mat_test.blossomSize(k);
214 224
  const_mat_test.blossomValue(k);
215 225
}
216 226

	
217 227
void checkMatching(const SmartGraph& graph,
218 228
                   const MaxMatching<SmartGraph>& mm) {
219 229
  int num = 0;
220 230

	
221 231
  IntNodeMap comp_index(graph);
222 232
  UnionFind<IntNodeMap> comp(comp_index);
223 233

	
224 234
  int barrier_num = 0;
225 235

	
226 236
  for (NodeIt n(graph); n != INVALID; ++n) {
227
    check(mm.decomposition(n) == MaxMatching<SmartGraph>::EVEN ||
237
    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
228 238
          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
229
    if (mm.decomposition(n) == MaxMatching<SmartGraph>::ODD) {
239
    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
230 240
      ++barrier_num;
231 241
    } else {
232 242
      comp.insert(n);
233 243
    }
234 244
  }
235 245

	
236 246
  for (EdgeIt e(graph); e != INVALID; ++e) {
237 247
    if (mm.matching(e)) {
238 248
      check(e == mm.matching(graph.u(e)), "Wrong matching");
239 249
      check(e == mm.matching(graph.v(e)), "Wrong matching");
240 250
      ++num;
241 251
    }
242
    check(mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
243
          mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
252
    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
253
          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
244 254
          "Wrong Gallai-Edmonds decomposition");
245 255

	
246
    check(mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
247
          mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
256
    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
257
          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
248 258
          "Wrong Gallai-Edmonds decomposition");
249 259

	
250
    if (mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
251
        mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
260
    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
261
        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
252 262
      comp.join(graph.u(e), graph.v(e));
253 263
    }
254 264
  }
255 265

	
256 266
  std::set<int> comp_root;
257 267
  int odd_comp_num = 0;
258 268
  for (NodeIt n(graph); n != INVALID; ++n) {
259
    if (mm.decomposition(n) != MaxMatching<SmartGraph>::ODD) {
269
    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
260 270
      int root = comp.find(n);
261 271
      if (comp_root.find(root) == comp_root.end()) {
262 272
        comp_root.insert(root);
263 273
        if (comp.size(n) % 2 == 1) {
264 274
          ++odd_comp_num;
265 275
        }
266 276
      }
267 277
    }
268 278
  }
269 279

	
270 280
  check(mm.matchingSize() == num, "Wrong matching");
271 281
  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
272 282
         "Wrong matching");
273 283
  return;
274 284
}
275 285

	
276 286
void checkWeightedMatching(const SmartGraph& graph,
277 287
                   const SmartGraph::EdgeMap<int>& weight,
278 288
                   const MaxWeightedMatching<SmartGraph>& mwm) {
279 289
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
280 290
    if (graph.u(e) == graph.v(e)) continue;
281 291
    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
282 292

	
283 293
    for (int i = 0; i < mwm.blossomNum(); ++i) {
284 294
      bool s = false, t = false;
285 295
      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
286 296
           n != INVALID; ++n) {
287 297
        if (graph.u(e) == n) s = true;
288 298
        if (graph.v(e) == n) t = true;
289 299
      }
290 300
      if (s == true && t == true) {
291 301
        rw += mwm.blossomValue(i);
292 302
      }
293 303
    }
294 304
    rw -= weight[e] * mwm.dualScale;
295 305

	
296 306
    check(rw >= 0, "Negative reduced weight");
297 307
    check(rw == 0 || !mwm.matching(e),
298 308
          "Non-zero reduced weight on matching edge");
299 309
  }
300 310

	
301 311
  int pv = 0;
302 312
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
303 313
    if (mwm.matching(n) != INVALID) {
304 314
      check(mwm.nodeValue(n) >= 0, "Invalid node value");
305 315
      pv += weight[mwm.matching(n)];
306 316
      SmartGraph::Node o = graph.target(mwm.matching(n));
307 317
      check(mwm.mate(n) == o, "Invalid matching");
308 318
      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
309 319
            "Invalid matching");
310 320
    } else {
311 321
      check(mwm.mate(n) == INVALID, "Invalid matching");
312 322
      check(mwm.nodeValue(n) == 0, "Invalid matching");
313 323
    }
314 324
  }
315 325

	
316 326
  int dv = 0;
317 327
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
318 328
    dv += mwm.nodeValue(n);
319 329
  }
320 330

	
321 331
  for (int i = 0; i < mwm.blossomNum(); ++i) {
322 332
    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
323 333
    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
324 334
    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
325 335
  }
326 336

	
327 337
  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
328 338

	
329 339
  return;
330 340
}
331 341

	
332 342
void checkWeightedPerfectMatching(const SmartGraph& graph,
333 343
                          const SmartGraph::EdgeMap<int>& weight,
334 344
                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
335 345
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
336 346
    if (graph.u(e) == graph.v(e)) continue;
337 347
    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
338 348

	
339 349
    for (int i = 0; i < mwpm.blossomNum(); ++i) {
340 350
      bool s = false, t = false;
341 351
      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
342 352
           n != INVALID; ++n) {
343 353
        if (graph.u(e) == n) s = true;
344 354
        if (graph.v(e) == n) t = true;
345 355
      }
346 356
      if (s == true && t == true) {
347 357
        rw += mwpm.blossomValue(i);
348 358
      }
349 359
    }
350 360
    rw -= weight[e] * mwpm.dualScale;
351 361

	
352 362
    check(rw >= 0, "Negative reduced weight");
353 363
    check(rw == 0 || !mwpm.matching(e),
354 364
          "Non-zero reduced weight on matching edge");
355 365
  }
356 366

	
357 367
  int pv = 0;
358 368
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
359 369
    check(mwpm.matching(n) != INVALID, "Non perfect");
360 370
    pv += weight[mwpm.matching(n)];
361 371
    SmartGraph::Node o = graph.target(mwpm.matching(n));
362 372
    check(mwpm.mate(n) == o, "Invalid matching");
363 373
    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
364 374
          "Invalid matching");
365 375
  }
366 376

	
367 377
  int dv = 0;
368 378
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
369 379
    dv += mwpm.nodeValue(n);
370 380
  }
371 381

	
372 382
  for (int i = 0; i < mwpm.blossomNum(); ++i) {
373 383
    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
374 384
    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
375 385
    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
376 386
  }
377 387

	
378 388
  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
379 389

	
380 390
  return;
381 391
}
382 392

	
383 393

	
384 394
int main() {
385 395

	
386 396
  for (int i = 0; i < lgfn; ++i) {
387 397
    SmartGraph graph;
388 398
    SmartGraph::EdgeMap<int> weight(graph);
389 399

	
390 400
    istringstream lgfs(lgf[i]);
391 401
    graphReader(graph, lgfs).
392 402
      edgeMap("weight", weight).run();
393 403

	
394 404
    MaxMatching<SmartGraph> mm(graph);
395 405
    mm.run();
396 406
    checkMatching(graph, mm);
397 407

	
398 408
    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
399 409
    mwm.run();
400 410
    checkWeightedMatching(graph, weight, mwm);
401 411

	
402 412
    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
403 413
    bool perfect = mwpm.run();
404 414

	
405 415
    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
406 416
          "Perfect matching found");
407 417

	
408 418
    if (perfect) {
409 419
      checkWeightedPerfectMatching(graph, weight, mwpm);
410 420
    }
411 421
  }
412 422

	
413 423
  return 0;
414 424
}
0 comments (0 inline)