gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Doc improvements in lemon/max_matching.h
0 1 0
default
1 file changed with 35 insertions and 36 deletions:
↑ Collapse diff ↑
Ignore white space 768 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-2008
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 Edmonds' alternating forest maximum matching algorithm.
41 41
  ///
42
  /// This class provides Edmonds' alternating forest matching
43
  /// algorithm. The starting matching (if any) can be passed to the
44
  /// algorithm using some of init functions.
42
  /// This class implements Edmonds' alternating forest matching
43
  /// algorithm. The algorithm can be started from an arbitrary initial
44
  /// matching (the default is the empty one)
45 45
  ///
46
  /// The dual side of a matching is a map of the nodes to
46
  /// The dual solution of the problem is a map of the nodes to
47 47
  /// MaxMatching::Status, having values \c EVEN/D, \c ODD/A and \c
48 48
  /// MATCHED/C showing the Gallai-Edmonds decomposition of the
49 49
  /// graph. The nodes in \c EVEN/D induce a graph with
50 50
  /// factor-critical components, the nodes in \c ODD/A form the
51 51
  /// barrier, and the nodes in \c MATCHED/C induce a graph having a
52
  /// perfect matching. The number of the fractor critical components
52
  /// perfect matching. The number of the factor-critical components
53 53
  /// minus the number of barrier nodes is a lower bound on the
54
  /// unmatched nodes, and if the matching is optimal this bound is
54
  /// unmatched nodes, and the matching is optimal if and only if this bound is
55 55
  /// tight. This decomposition can be attained by calling \c
56 56
  /// decomposition() after running the algorithm.
57 57
  ///
58 58
  /// \param _Graph The graph type the algorithm runs on.
59 59
  template <typename _Graph>
60 60
  class MaxMatching {
61 61
  public:
62 62

	
63 63
    typedef _Graph Graph;
64 64
    typedef typename Graph::template NodeMap<typename Graph::Arc>
65 65
    MatchingMap;
66 66

	
67 67
    ///\brief Indicates the Gallai-Edmonds decomposition of the graph.
68 68
    ///
69
    ///Indicates the Gallai-Edmonds decomposition of the graph, which
70
    ///shows an upper bound on the size of a maximum matching. The
69
    ///Indicates the Gallai-Edmonds decomposition of the graph. The
71 70
    ///nodes with Status \c EVEN/D induce a graph with factor-critical
72 71
    ///components, the nodes in \c ODD/A form the canonical barrier,
73 72
    ///and the nodes in \c MATCHED/C induce a graph having a perfect
74 73
    ///matching.
75 74
    enum Status {
76 75
      EVEN = 1, D = 1, MATCHED = 0, C = 0, ODD = -1, A = -1, UNMATCHED = -2
77 76
    };
78 77

	
79 78
    typedef typename Graph::template NodeMap<Status> StatusMap;
80 79

	
81 80
  private:
82 81

	
83 82
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
84 83

	
85 84
    typedef UnionFindEnum<IntNodeMap> BlossomSet;
86 85
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
87 86
    typedef RangeMap<Node> NodeIntMap;
88 87
    typedef MatchingMap EarMap;
89 88
    typedef std::vector<Node> NodeQueue;
90 89

	
91 90
    const Graph& _graph;
92 91
    MatchingMap* _matching;
93 92
    StatusMap* _status;
94 93

	
95 94
    EarMap* _ear;
96 95

	
97 96
    IntNodeMap* _blossom_set_index;
98 97
    BlossomSet* _blossom_set;
99 98
    NodeIntMap* _blossom_rep;
100 99

	
101 100
    IntNodeMap* _tree_set_index;
102 101
    TreeSet* _tree_set;
103 102

	
104 103
    NodeQueue _node_queue;
105 104
    int _process, _postpone, _last;
106 105

	
107 106
    int _node_num;
108 107

	
109 108
  private:
110 109

	
111 110
    void createStructures() {
112 111
      _node_num = countNodes(_graph);
113 112
      if (!_matching) {
114 113
        _matching = new MatchingMap(_graph);
115 114
      }
116 115
      if (!_status) {
117 116
        _status = new StatusMap(_graph);
118 117
      }
119 118
      if (!_ear) {
120 119
        _ear = new EarMap(_graph);
121 120
      }
122 121
      if (!_blossom_set) {
123 122
        _blossom_set_index = new IntNodeMap(_graph);
124 123
        _blossom_set = new BlossomSet(*_blossom_set_index);
125 124
      }
126 125
      if (!_blossom_rep) {
127 126
        _blossom_rep = new NodeIntMap(_node_num);
128 127
      }
129 128
      if (!_tree_set) {
130 129
        _tree_set_index = new IntNodeMap(_graph);
131 130
        _tree_set = new TreeSet(*_tree_set_index);
132 131
      }
133 132
      _node_queue.resize(_node_num);
134 133
    }
135 134

	
136 135
    void destroyStructures() {
137 136
      if (_matching) {
138 137
        delete _matching;
139 138
      }
140 139
      if (_status) {
141 140
        delete _status;
142 141
      }
143 142
      if (_ear) {
144 143
        delete _ear;
145 144
      }
146 145
      if (_blossom_set) {
147 146
        delete _blossom_set;
148 147
        delete _blossom_set_index;
149 148
      }
150 149
      if (_blossom_rep) {
151 150
        delete _blossom_rep;
152 151
      }
153 152
      if (_tree_set) {
154 153
        delete _tree_set_index;
155 154
        delete _tree_set;
156 155
      }
157 156
    }
158 157

	
159 158
    void processDense(const Node& n) {
160 159
      _process = _postpone = _last = 0;
161 160
      _node_queue[_last++] = n;
162 161

	
163 162
      while (_process != _last) {
164 163
        Node u = _node_queue[_process++];
165 164
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
166 165
          Node v = _graph.target(a);
167 166
          if ((*_status)[v] == MATCHED) {
168 167
            extendOnArc(a);
169 168
          } else if ((*_status)[v] == UNMATCHED) {
170 169
            augmentOnArc(a);
171 170
            return;
172 171
          }
173 172
        }
174 173
      }
175 174

	
176 175
      while (_postpone != _last) {
177 176
        Node u = _node_queue[_postpone++];
178 177

	
179 178
        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
180 179
          Node v = _graph.target(a);
181 180

	
182 181
          if ((*_status)[v] == EVEN) {
183 182
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
184 183
              shrinkOnEdge(a);
185 184
            }
186 185
          }
187 186

	
188 187
          while (_process != _last) {
189 188
            Node w = _node_queue[_process++];
190 189
            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
191 190
              Node x = _graph.target(b);
192 191
              if ((*_status)[x] == MATCHED) {
193 192
                extendOnArc(b);
194 193
              } else if ((*_status)[x] == UNMATCHED) {
195 194
                augmentOnArc(b);
196 195
                return;
197 196
              }
198 197
            }
199 198
          }
200 199
        }
201 200
      }
202 201
    }
203 202

	
204 203
    void processSparse(const Node& n) {
205 204
      _process = _last = 0;
206 205
      _node_queue[_last++] = n;
207 206
      while (_process != _last) {
208 207
        Node u = _node_queue[_process++];
209 208
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
210 209
          Node v = _graph.target(a);
211 210

	
212 211
          if ((*_status)[v] == EVEN) {
213 212
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
214 213
              shrinkOnEdge(a);
215 214
            }
216 215
          } else if ((*_status)[v] == MATCHED) {
217 216
            extendOnArc(a);
218 217
          } else if ((*_status)[v] == UNMATCHED) {
219 218
            augmentOnArc(a);
220 219
            return;
221 220
          }
222 221
        }
223 222
      }
224 223
    }
225 224

	
226 225
    void shrinkOnEdge(const Edge& e) {
227 226
      Node nca = INVALID;
228 227

	
229 228
      {
230 229
        std::set<Node> left_set, right_set;
231 230

	
232 231
        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
233 232
        left_set.insert(left);
234 233

	
235 234
        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
236 235
        right_set.insert(right);
237 236

	
238 237
        while (true) {
239 238
          if ((*_matching)[left] == INVALID) break;
240 239
          left = _graph.target((*_matching)[left]);
241 240
          left = (*_blossom_rep)[_blossom_set->
242 241
                                 find(_graph.target((*_ear)[left]))];
243 242
          if (right_set.find(left) != right_set.end()) {
244 243
            nca = left;
245 244
            break;
246 245
          }
247 246
          left_set.insert(left);
248 247

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

	
260 259
        if (nca == INVALID) {
261 260
          if ((*_matching)[left] == INVALID) {
262 261
            nca = right;
263 262
            while (left_set.find(nca) == left_set.end()) {
264 263
              nca = _graph.target((*_matching)[nca]);
265 264
              nca =(*_blossom_rep)[_blossom_set->
266 265
                                   find(_graph.target((*_ear)[nca]))];
267 266
            }
268 267
          } else {
269 268
            nca = left;
270 269
            while (right_set.find(nca) == right_set.end()) {
271 270
              nca = _graph.target((*_matching)[nca]);
272 271
              nca = (*_blossom_rep)[_blossom_set->
273 272
                                   find(_graph.target((*_ear)[nca]))];
274 273
            }
275 274
          }
276 275
        }
277 276
      }
278 277

	
279 278
      {
280 279

	
281 280
        Node node = _graph.u(e);
282 281
        Arc arc = _graph.direct(e, true);
283 282
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
284 283

	
285 284
        while (base != nca) {
286 285
          _ear->set(node, arc);
287 286

	
288 287
          Node n = node;
289 288
          while (n != base) {
290 289
            n = _graph.target((*_matching)[n]);
291 290
            Arc a = (*_ear)[n];
292 291
            n = _graph.target(a);
293 292
            _ear->set(n, _graph.oppositeArc(a));
294 293
          }
295 294
          node = _graph.target((*_matching)[base]);
296 295
          _tree_set->erase(base);
297 296
          _tree_set->erase(node);
298 297
          _blossom_set->insert(node, _blossom_set->find(base));
299 298
          _status->set(node, EVEN);
300 299
          _node_queue[_last++] = node;
301 300
          arc = _graph.oppositeArc((*_ear)[node]);
302 301
          node = _graph.target((*_ear)[node]);
303 302
          base = (*_blossom_rep)[_blossom_set->find(node)];
304 303
          _blossom_set->join(_graph.target(arc), base);
305 304
        }
306 305
      }
307 306

	
308 307
      _blossom_rep->set(_blossom_set->find(nca), nca);
309 308

	
310 309
      {
311 310

	
312 311
        Node node = _graph.v(e);
313 312
        Arc arc = _graph.direct(e, false);
314 313
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
315 314

	
316 315
        while (base != nca) {
317 316
          _ear->set(node, arc);
318 317

	
319 318
          Node n = node;
320 319
          while (n != base) {
321 320
            n = _graph.target((*_matching)[n]);
322 321
            Arc a = (*_ear)[n];
323 322
            n = _graph.target(a);
324 323
            _ear->set(n, _graph.oppositeArc(a));
325 324
          }
326 325
          node = _graph.target((*_matching)[base]);
327 326
          _tree_set->erase(base);
328 327
          _tree_set->erase(node);
329 328
          _blossom_set->insert(node, _blossom_set->find(base));
330 329
          _status->set(node, EVEN);
331 330
          _node_queue[_last++] = node;
332 331
          arc = _graph.oppositeArc((*_ear)[node]);
333 332
          node = _graph.target((*_ear)[node]);
334 333
          base = (*_blossom_rep)[_blossom_set->find(node)];
335 334
          _blossom_set->join(_graph.target(arc), base);
336 335
        }
337 336
      }
338 337

	
339 338
      _blossom_rep->set(_blossom_set->find(nca), nca);
340 339
    }
341 340

	
342 341

	
343 342

	
344 343
    void extendOnArc(const Arc& a) {
345 344
      Node base = _graph.source(a);
346 345
      Node odd = _graph.target(a);
347 346

	
348 347
      _ear->set(odd, _graph.oppositeArc(a));
349 348
      Node even = _graph.target((*_matching)[odd]);
350 349
      _blossom_rep->set(_blossom_set->insert(even), even);
351 350
      _status->set(odd, ODD);
352 351
      _status->set(even, EVEN);
353 352
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
354 353
      _tree_set->insert(odd, tree);
355 354
      _tree_set->insert(even, tree);
356 355
      _node_queue[_last++] = even;
357 356

	
358 357
    }
359 358

	
360 359
    void augmentOnArc(const Arc& a) {
361 360
      Node even = _graph.source(a);
362 361
      Node odd = _graph.target(a);
363 362

	
364 363
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
365 364

	
366 365
      _matching->set(odd, _graph.oppositeArc(a));
367 366
      _status->set(odd, MATCHED);
368 367

	
369 368
      Arc arc = (*_matching)[even];
370 369
      _matching->set(even, a);
371 370

	
372 371
      while (arc != INVALID) {
373 372
        odd = _graph.target(arc);
374 373
        arc = (*_ear)[odd];
375 374
        even = _graph.target(arc);
376 375
        _matching->set(odd, arc);
377 376
        arc = (*_matching)[even];
378 377
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
379 378
      }
380 379

	
381 380
      for (typename TreeSet::ItemIt it(*_tree_set, tree);
382 381
           it != INVALID; ++it) {
383 382
        if ((*_status)[it] == ODD) {
384 383
          _status->set(it, MATCHED);
385 384
        } else {
386 385
          int blossom = _blossom_set->find(it);
387 386
          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
388 387
               jt != INVALID; ++jt) {
389 388
            _status->set(jt, MATCHED);
390 389
          }
391 390
          _blossom_set->eraseClass(blossom);
392 391
        }
393 392
      }
394 393
      _tree_set->eraseClass(tree);
395 394

	
396 395
    }
397 396

	
398 397
  public:
399 398

	
400 399
    /// \brief Constructor
401 400
    ///
402 401
    /// Constructor.
403 402
    MaxMatching(const Graph& graph)
404 403
      : _graph(graph), _matching(0), _status(0), _ear(0),
405 404
        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
406 405
        _tree_set_index(0), _tree_set(0) {}
407 406

	
408 407
    ~MaxMatching() {
409 408
      destroyStructures();
410 409
    }
411 410

	
412 411
    /// \name Execution control
413
    /// The simplest way to execute the algorithm is to use the member
412
    /// The simplest way to execute the algorithm is to use the
414 413
    /// \c run() member function.
415 414
    /// \n
416 415

	
417
    /// If you need more control on the execution, first you must call
416
    /// If you need better control on the execution, you must call
418 417
    /// \ref init(), \ref greedyInit() or \ref matchingInit()
419
    /// functions, then you can start the algorithm with the \ref
418
    /// functions first, then you can start the algorithm with the \ref
420 419
    /// startParse() or startDense() functions.
421 420

	
422 421
    ///@{
423 422

	
424 423
    /// \brief Sets the actual matching to the empty matching.
425 424
    ///
426 425
    /// Sets the actual matching to the empty matching.
427 426
    ///
428 427
    void init() {
429 428
      createStructures();
430 429
      for(NodeIt n(_graph); n != INVALID; ++n) {
431 430
        _matching->set(n, INVALID);
432 431
        _status->set(n, UNMATCHED);
433 432
      }
434 433
    }
435 434

	
436
    ///\brief Finds a greedy matching for initial matching.
435
    ///\brief Finds an initial matching in a greedy way
437 436
    ///
438
    ///For initial matchig it finds a maximal greedy matching.
437
    ///It finds an initial matching in a greedy way.
439 438
    void greedyInit() {
440 439
      createStructures();
441 440
      for (NodeIt n(_graph); n != INVALID; ++n) {
442 441
        _matching->set(n, INVALID);
443 442
        _status->set(n, UNMATCHED);
444 443
      }
445 444
      for (NodeIt n(_graph); n != INVALID; ++n) {
446 445
        if ((*_matching)[n] == INVALID) {
447 446
          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
448 447
            Node v = _graph.target(a);
449 448
            if ((*_matching)[v] == INVALID && v != n) {
450 449
              _matching->set(n, a);
451 450
              _status->set(n, MATCHED);
452 451
              _matching->set(v, _graph.oppositeArc(a));
453 452
              _status->set(v, MATCHED);
454 453
              break;
455 454
            }
456 455
          }
457 456
        }
458 457
      }
459 458
    }
460 459

	
461 460

	
462
    /// \brief Initialize the matching from the map containing a matching.
461
    /// \brief Initialize the matching from a map containing.
463 462
    ///
464 463
    /// Initialize the matching from a \c bool valued \c Edge map. This
465 464
    /// map must have the property that there are no two incident edges
466 465
    /// with true value, ie. it contains a matching.
467 466
    /// \return %True if the map contains a matching.
468 467
    template <typename MatchingMap>
469 468
    bool matchingInit(const MatchingMap& matching) {
470 469
      createStructures();
471 470

	
472 471
      for (NodeIt n(_graph); n != INVALID; ++n) {
473 472
        _matching->set(n, INVALID);
474 473
        _status->set(n, UNMATCHED);
475 474
      }
476 475
      for(EdgeIt e(_graph); e!=INVALID; ++e) {
477 476
        if (matching[e]) {
478 477

	
479 478
          Node u = _graph.u(e);
480 479
          if ((*_matching)[u] != INVALID) return false;
481 480
          _matching->set(u, _graph.direct(e, true));
482 481
          _status->set(u, MATCHED);
483 482

	
484 483
          Node v = _graph.v(e);
485 484
          if ((*_matching)[v] != INVALID) return false;
486 485
          _matching->set(v, _graph.direct(e, false));
487 486
          _status->set(v, MATCHED);
488 487
        }
489 488
      }
490 489
      return true;
491 490
    }
492 491

	
493 492
    /// \brief Starts Edmonds' algorithm
494 493
    ///
495 494
    /// If runs the original Edmonds' algorithm.
496 495
    void startSparse() {
497 496
      for(NodeIt n(_graph); n != INVALID; ++n) {
498 497
        if ((*_status)[n] == UNMATCHED) {
499 498
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
500 499
          _tree_set->insert(n);
501 500
          _status->set(n, EVEN);
502 501
          processSparse(n);
503 502
        }
504 503
      }
505 504
    }
506 505

	
507 506
    /// \brief Starts Edmonds' algorithm.
508 507
    ///
509 508
    /// It runs Edmonds' algorithm with a heuristic of postponing
510
    /// shrinks, giving a faster algorithm for dense graphs.
509
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
511 510
    void startDense() {
512 511
      for(NodeIt n(_graph); n != INVALID; ++n) {
513 512
        if ((*_status)[n] == UNMATCHED) {
514 513
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
515 514
          _tree_set->insert(n);
516 515
          _status->set(n, EVEN);
517 516
          processDense(n);
518 517
        }
519 518
      }
520 519
    }
521 520

	
522 521

	
523 522
    /// \brief Runs Edmonds' algorithm
524 523
    ///
525 524
    /// Runs Edmonds' algorithm for sparse graphs (<tt>m<2*n</tt>)
526 525
    /// or Edmonds' algorithm with a heuristic of
527 526
    /// postponing shrinks for dense graphs.
528 527
    void run() {
529 528
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
530 529
        greedyInit();
531 530
        startSparse();
532 531
      } else {
533 532
        init();
534 533
        startDense();
535 534
      }
536 535
    }
537 536

	
538 537
    /// @}
539 538

	
540 539
    /// \name Primal solution
541
    /// Functions for get the primal solution, ie. the matching.
540
    /// Functions to get the primal solution, ie. the matching.
542 541

	
543 542
    /// @{
544 543

	
545
    ///\brief Returns the size of the actual matching stored.
544
    ///\brief Returns the size of the current matching.
546 545
    ///
547
    ///Returns the size of the actual matching stored. After \ref
546
    ///Returns the size of the current matching. After \ref
548 547
    ///run() it returns the size of the maximum matching in the graph.
549 548
    int matchingSize() const {
550 549
      int size = 0;
551 550
      for (NodeIt n(_graph); n != INVALID; ++n) {
552 551
        if ((*_matching)[n] != INVALID) {
553 552
          ++size;
554 553
        }
555 554
      }
556 555
      return size / 2;
557 556
    }
558 557

	
559 558
    /// \brief Returns true when the edge is in the matching.
560 559
    ///
561 560
    /// Returns true when the edge is in the matching.
562 561
    bool matching(const Edge& edge) const {
563 562
      return edge == (*_matching)[_graph.u(edge)];
564 563
    }
565 564

	
566 565
    /// \brief Returns the matching edge incident to the given node.
567 566
    ///
568 567
    /// Returns the matching edge of a \c node in the actual matching or
569 568
    /// INVALID if the \c node is not covered by the actual matching.
570 569
    Arc matching(const Node& n) const {
571 570
      return (*_matching)[n];
572 571
    }
573 572

	
574 573
    ///\brief Returns the mate of a node in the actual matching.
575 574
    ///
576 575
    ///Returns the mate of a \c node in the actual matching or
577 576
    ///INVALID if the \c node is not covered by the actual matching.
578 577
    Node mate(const Node& n) const {
579 578
      return (*_matching)[n] != INVALID ?
580 579
        _graph.target((*_matching)[n]) : INVALID;
581 580
    }
582 581

	
583 582
    /// @}
584 583

	
585 584
    /// \name Dual solution
586
    /// Functions for get the dual solution, ie. the decomposition.
585
    /// Functions to get the dual solution, ie. the decomposition.
587 586

	
588 587
    /// @{
589 588

	
590 589
    /// \brief Returns the class of the node in the Edmonds-Gallai
591 590
    /// decomposition.
592 591
    ///
593 592
    /// Returns the class of the node in the Edmonds-Gallai
594 593
    /// decomposition.
595 594
    Status decomposition(const Node& n) const {
596 595
      return (*_status)[n];
597 596
    }
598 597

	
599 598
    /// \brief Returns true when the node is in the barrier.
600 599
    ///
601 600
    /// Returns true when the node is in the barrier.
602 601
    bool barrier(const Node& n) const {
603 602
      return (*_status)[n] == ODD;
604 603
    }
605 604

	
606 605
    /// @}
607 606

	
608 607
  };
609 608

	
610 609
  /// \ingroup matching
611 610
  ///
612 611
  /// \brief Weighted matching in general graphs
613 612
  ///
614 613
  /// This class provides an efficient implementation of Edmond's
615 614
  /// maximum weighted matching algorithm. The implementation is based
616 615
  /// on extensive use of priority queues and provides
617 616
  /// \f$O(nm\log(n))\f$ time complexity.
618 617
  ///
619 618
  /// The maximum weighted matching problem is to find undirected
620 619
  /// edges in the graph with maximum overall weight and no two of
621 620
  /// them shares their ends. The problem can be formulated with the
622 621
  /// following linear program.
623 622
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
624 623
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
625 624
      \quad \forall B\in\mathcal{O}\f] */
626 625
  /// \f[x_e \ge 0\quad \forall e\in E\f]
627 626
  /// \f[\max \sum_{e\in E}x_ew_e\f]
628 627
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
629 628
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
630 629
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
631 630
  /// subsets of the nodes.
632 631
  ///
633 632
  /// The algorithm calculates an optimal matching and a proof of the
634 633
  /// optimality. The solution of the dual problem can be used to check
635 634
  /// the result of the algorithm. The dual linear problem is the
636 635
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
637 636
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
638 637
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
639 638
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
640 639
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
641 640
      \frac{\vert B \vert - 1}{2}z_B\f] */
642 641
  ///
643 642
  /// The algorithm can be executed with \c run() or the \c init() and
644 643
  /// then the \c start() member functions. After it the matching can
645 644
  /// be asked with \c matching() or mate() functions. The dual
646 645
  /// solution can be get with \c nodeValue(), \c blossomNum() and \c
647 646
  /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
648
  /// "BlossomIt" nested class which is able to iterate on the nodes
647
  /// "BlossomIt" nested class, which is able to iterate on the nodes
649 648
  /// of a blossom. If the value type is integral then the dual
650 649
  /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
651 650
  template <typename _Graph,
652 651
            typename _WeightMap = typename _Graph::template EdgeMap<int> >
653 652
  class MaxWeightedMatching {
654 653
  public:
655 654

	
656 655
    typedef _Graph Graph;
657 656
    typedef _WeightMap WeightMap;
658 657
    typedef typename WeightMap::Value Value;
659 658

	
660 659
    /// \brief Scaling factor for dual solution
661 660
    ///
662 661
    /// Scaling factor for dual solution, it is equal to 4 or 1
663 662
    /// according to the value type.
664 663
    static const int dualScale =
665 664
      std::numeric_limits<Value>::is_integer ? 4 : 1;
666 665

	
667 666
    typedef typename Graph::template NodeMap<typename Graph::Arc>
668 667
    MatchingMap;
669 668

	
670 669
  private:
671 670

	
672 671
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
673 672

	
674 673
    typedef typename Graph::template NodeMap<Value> NodePotential;
675 674
    typedef std::vector<Node> BlossomNodeList;
676 675

	
677 676
    struct BlossomVariable {
678 677
      int begin, end;
679 678
      Value value;
680 679

	
681 680
      BlossomVariable(int _begin, int _end, Value _value)
682 681
        : begin(_begin), end(_end), value(_value) {}
683 682

	
684 683
    };
685 684

	
686 685
    typedef std::vector<BlossomVariable> BlossomPotential;
687 686

	
688 687
    const Graph& _graph;
689 688
    const WeightMap& _weight;
690 689

	
691 690
    MatchingMap* _matching;
692 691

	
693 692
    NodePotential* _node_potential;
694 693

	
695 694
    BlossomPotential _blossom_potential;
696 695
    BlossomNodeList _blossom_node_list;
697 696

	
698 697
    int _node_num;
699 698
    int _blossom_num;
700 699

	
701 700
    typedef RangeMap<int> IntIntMap;
702 701

	
703 702
    enum Status {
704 703
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
705 704
    };
706 705

	
707 706
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
708 707
    struct BlossomData {
709 708
      int tree;
710 709
      Status status;
711 710
      Arc pred, next;
712 711
      Value pot, offset;
713 712
      Node base;
714 713
    };
715 714

	
716 715
    IntNodeMap *_blossom_index;
717 716
    BlossomSet *_blossom_set;
718 717
    RangeMap<BlossomData>* _blossom_data;
719 718

	
720 719
    IntNodeMap *_node_index;
721 720
    IntArcMap *_node_heap_index;
722 721

	
723 722
    struct NodeData {
724 723

	
725 724
      NodeData(IntArcMap& node_heap_index)
726 725
        : heap(node_heap_index) {}
727 726

	
728 727
      int blossom;
729 728
      Value pot;
730 729
      BinHeap<Value, IntArcMap> heap;
731 730
      std::map<int, Arc> heap_index;
732 731

	
733 732
      int tree;
734 733
    };
735 734

	
736 735
    RangeMap<NodeData>* _node_data;
737 736

	
738 737
    typedef ExtendFindEnum<IntIntMap> TreeSet;
739 738

	
740 739
    IntIntMap *_tree_set_index;
741 740
    TreeSet *_tree_set;
742 741

	
743 742
    IntNodeMap *_delta1_index;
744 743
    BinHeap<Value, IntNodeMap> *_delta1;
745 744

	
746 745
    IntIntMap *_delta2_index;
747 746
    BinHeap<Value, IntIntMap> *_delta2;
748 747

	
749 748
    IntEdgeMap *_delta3_index;
750 749
    BinHeap<Value, IntEdgeMap> *_delta3;
751 750

	
752 751
    IntIntMap *_delta4_index;
753 752
    BinHeap<Value, IntIntMap> *_delta4;
754 753

	
755 754
    Value _delta_sum;
756 755

	
757 756
    void createStructures() {
758 757
      _node_num = countNodes(_graph);
759 758
      _blossom_num = _node_num * 3 / 2;
760 759

	
761 760
      if (!_matching) {
762 761
        _matching = new MatchingMap(_graph);
763 762
      }
764 763
      if (!_node_potential) {
765 764
        _node_potential = new NodePotential(_graph);
766 765
      }
767 766
      if (!_blossom_set) {
768 767
        _blossom_index = new IntNodeMap(_graph);
769 768
        _blossom_set = new BlossomSet(*_blossom_index);
770 769
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
771 770
      }
772 771

	
773 772
      if (!_node_index) {
774 773
        _node_index = new IntNodeMap(_graph);
775 774
        _node_heap_index = new IntArcMap(_graph);
776 775
        _node_data = new RangeMap<NodeData>(_node_num,
777 776
                                              NodeData(*_node_heap_index));
778 777
      }
779 778

	
780 779
      if (!_tree_set) {
781 780
        _tree_set_index = new IntIntMap(_blossom_num);
782 781
        _tree_set = new TreeSet(*_tree_set_index);
783 782
      }
784 783
      if (!_delta1) {
785 784
        _delta1_index = new IntNodeMap(_graph);
786 785
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
787 786
      }
788 787
      if (!_delta2) {
789 788
        _delta2_index = new IntIntMap(_blossom_num);
790 789
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
791 790
      }
792 791
      if (!_delta3) {
793 792
        _delta3_index = new IntEdgeMap(_graph);
794 793
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
795 794
      }
796 795
      if (!_delta4) {
797 796
        _delta4_index = new IntIntMap(_blossom_num);
798 797
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
799 798
      }
800 799
    }
801 800

	
802 801
    void destroyStructures() {
803 802
      _node_num = countNodes(_graph);
804 803
      _blossom_num = _node_num * 3 / 2;
805 804

	
806 805
      if (_matching) {
807 806
        delete _matching;
808 807
      }
809 808
      if (_node_potential) {
810 809
        delete _node_potential;
811 810
      }
812 811
      if (_blossom_set) {
813 812
        delete _blossom_index;
814 813
        delete _blossom_set;
815 814
        delete _blossom_data;
816 815
      }
817 816

	
818 817
      if (_node_index) {
819 818
        delete _node_index;
820 819
        delete _node_heap_index;
821 820
        delete _node_data;
822 821
      }
823 822

	
824 823
      if (_tree_set) {
825 824
        delete _tree_set_index;
826 825
        delete _tree_set;
827 826
      }
828 827
      if (_delta1) {
829 828
        delete _delta1_index;
830 829
        delete _delta1;
831 830
      }
832 831
      if (_delta2) {
833 832
        delete _delta2_index;
834 833
        delete _delta2;
835 834
      }
836 835
      if (_delta3) {
837 836
        delete _delta3_index;
838 837
        delete _delta3;
839 838
      }
840 839
      if (_delta4) {
841 840
        delete _delta4_index;
842 841
        delete _delta4;
843 842
      }
844 843
    }
845 844

	
846 845
    void matchedToEven(int blossom, int tree) {
847 846
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
848 847
        _delta2->erase(blossom);
849 848
      }
850 849

	
851 850
      if (!_blossom_set->trivial(blossom)) {
852 851
        (*_blossom_data)[blossom].pot -=
853 852
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
854 853
      }
855 854

	
856 855
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
857 856
           n != INVALID; ++n) {
858 857

	
859 858
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
860 859
        int ni = (*_node_index)[n];
861 860

	
862 861
        (*_node_data)[ni].heap.clear();
863 862
        (*_node_data)[ni].heap_index.clear();
864 863

	
865 864
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
866 865

	
867 866
        _delta1->push(n, (*_node_data)[ni].pot);
868 867

	
869 868
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
870 869
          Node v = _graph.source(e);
871 870
          int vb = _blossom_set->find(v);
872 871
          int vi = (*_node_index)[v];
873 872

	
874 873
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
875 874
            dualScale * _weight[e];
876 875

	
877 876
          if ((*_blossom_data)[vb].status == EVEN) {
878 877
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
879 878
              _delta3->push(e, rw / 2);
880 879
            }
881 880
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
882 881
            if (_delta3->state(e) != _delta3->IN_HEAP) {
883 882
              _delta3->push(e, rw);
884 883
            }
885 884
          } else {
886 885
            typename std::map<int, Arc>::iterator it =
887 886
              (*_node_data)[vi].heap_index.find(tree);
888 887

	
889 888
            if (it != (*_node_data)[vi].heap_index.end()) {
890 889
              if ((*_node_data)[vi].heap[it->second] > rw) {
891 890
                (*_node_data)[vi].heap.replace(it->second, e);
892 891
                (*_node_data)[vi].heap.decrease(e, rw);
893 892
                it->second = e;
894 893
              }
895 894
            } else {
896 895
              (*_node_data)[vi].heap.push(e, rw);
897 896
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
898 897
            }
899 898

	
900 899
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
901 900
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
902 901

	
903 902
              if ((*_blossom_data)[vb].status == MATCHED) {
904 903
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
905 904
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
906 905
                               (*_blossom_data)[vb].offset);
907 906
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
908 907
                           (*_blossom_data)[vb].offset){
909 908
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
910 909
                                   (*_blossom_data)[vb].offset);
911 910
                }
912 911
              }
913 912
            }
914 913
          }
915 914
        }
916 915
      }
917 916
      (*_blossom_data)[blossom].offset = 0;
918 917
    }
919 918

	
920 919
    void matchedToOdd(int blossom) {
921 920
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
922 921
        _delta2->erase(blossom);
923 922
      }
924 923
      (*_blossom_data)[blossom].offset += _delta_sum;
925 924
      if (!_blossom_set->trivial(blossom)) {
926 925
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
927 926
                     (*_blossom_data)[blossom].offset);
928 927
      }
929 928
    }
930 929

	
931 930
    void evenToMatched(int blossom, int tree) {
932 931
      if (!_blossom_set->trivial(blossom)) {
933 932
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
934 933
      }
935 934

	
936 935
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
937 936
           n != INVALID; ++n) {
938 937
        int ni = (*_node_index)[n];
939 938
        (*_node_data)[ni].pot -= _delta_sum;
940 939

	
941 940
        _delta1->erase(n);
942 941

	
943 942
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
944 943
          Node v = _graph.source(e);
945 944
          int vb = _blossom_set->find(v);
946 945
          int vi = (*_node_index)[v];
947 946

	
948 947
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
949 948
            dualScale * _weight[e];
950 949

	
951 950
          if (vb == blossom) {
952 951
            if (_delta3->state(e) == _delta3->IN_HEAP) {
953 952
              _delta3->erase(e);
954 953
            }
955 954
          } else if ((*_blossom_data)[vb].status == EVEN) {
956 955

	
957 956
            if (_delta3->state(e) == _delta3->IN_HEAP) {
958 957
              _delta3->erase(e);
959 958
            }
960 959

	
961 960
            int vt = _tree_set->find(vb);
962 961

	
963 962
            if (vt != tree) {
964 963

	
965 964
              Arc r = _graph.oppositeArc(e);
966 965

	
967 966
              typename std::map<int, Arc>::iterator it =
968 967
                (*_node_data)[ni].heap_index.find(vt);
969 968

	
970 969
              if (it != (*_node_data)[ni].heap_index.end()) {
971 970
                if ((*_node_data)[ni].heap[it->second] > rw) {
972 971
                  (*_node_data)[ni].heap.replace(it->second, r);
973 972
                  (*_node_data)[ni].heap.decrease(r, rw);
974 973
                  it->second = r;
975 974
                }
976 975
              } else {
977 976
                (*_node_data)[ni].heap.push(r, rw);
978 977
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
979 978
              }
980 979

	
981 980
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
982 981
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
983 982

	
984 983
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
985 984
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
986 985
                               (*_blossom_data)[blossom].offset);
987 986
                } else if ((*_delta2)[blossom] >
988 987
                           _blossom_set->classPrio(blossom) -
989 988
                           (*_blossom_data)[blossom].offset){
990 989
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
991 990
                                   (*_blossom_data)[blossom].offset);
992 991
                }
993 992
              }
994 993
            }
995 994

	
996 995
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
997 996
            if (_delta3->state(e) == _delta3->IN_HEAP) {
998 997
              _delta3->erase(e);
999 998
            }
1000 999
          } else {
1001 1000

	
1002 1001
            typename std::map<int, Arc>::iterator it =
1003 1002
              (*_node_data)[vi].heap_index.find(tree);
1004 1003

	
1005 1004
            if (it != (*_node_data)[vi].heap_index.end()) {
1006 1005
              (*_node_data)[vi].heap.erase(it->second);
1007 1006
              (*_node_data)[vi].heap_index.erase(it);
1008 1007
              if ((*_node_data)[vi].heap.empty()) {
1009 1008
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1010 1009
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1011 1010
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1012 1011
              }
1013 1012

	
1014 1013
              if ((*_blossom_data)[vb].status == MATCHED) {
1015 1014
                if (_blossom_set->classPrio(vb) ==
1016 1015
                    std::numeric_limits<Value>::max()) {
1017 1016
                  _delta2->erase(vb);
1018 1017
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1019 1018
                           (*_blossom_data)[vb].offset) {
1020 1019
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1021 1020
                                   (*_blossom_data)[vb].offset);
1022 1021
                }
1023 1022
              }
1024 1023
            }
1025 1024
          }
1026 1025
        }
1027 1026
      }
1028 1027
    }
1029 1028

	
1030 1029
    void oddToMatched(int blossom) {
1031 1030
      (*_blossom_data)[blossom].offset -= _delta_sum;
1032 1031

	
... ...
@@ -1249,1047 +1248,1047 @@
1249 1248

	
1250 1249
      alternatePath(blossom, tree);
1251 1250
      destroyTree(tree);
1252 1251

	
1253 1252
      (*_blossom_data)[blossom].status = UNMATCHED;
1254 1253
      (*_blossom_data)[blossom].base = node;
1255 1254
      matchedToUnmatched(blossom);
1256 1255
    }
1257 1256

	
1258 1257

	
1259 1258
    void augmentOnEdge(const Edge& edge) {
1260 1259

	
1261 1260
      int left = _blossom_set->find(_graph.u(edge));
1262 1261
      int right = _blossom_set->find(_graph.v(edge));
1263 1262

	
1264 1263
      if ((*_blossom_data)[left].status == EVEN) {
1265 1264
        int left_tree = _tree_set->find(left);
1266 1265
        alternatePath(left, left_tree);
1267 1266
        destroyTree(left_tree);
1268 1267
      } else {
1269 1268
        (*_blossom_data)[left].status = MATCHED;
1270 1269
        unmatchedToMatched(left);
1271 1270
      }
1272 1271

	
1273 1272
      if ((*_blossom_data)[right].status == EVEN) {
1274 1273
        int right_tree = _tree_set->find(right);
1275 1274
        alternatePath(right, right_tree);
1276 1275
        destroyTree(right_tree);
1277 1276
      } else {
1278 1277
        (*_blossom_data)[right].status = MATCHED;
1279 1278
        unmatchedToMatched(right);
1280 1279
      }
1281 1280

	
1282 1281
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1283 1282
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1284 1283
    }
1285 1284

	
1286 1285
    void extendOnArc(const Arc& arc) {
1287 1286
      int base = _blossom_set->find(_graph.target(arc));
1288 1287
      int tree = _tree_set->find(base);
1289 1288

	
1290 1289
      int odd = _blossom_set->find(_graph.source(arc));
1291 1290
      _tree_set->insert(odd, tree);
1292 1291
      (*_blossom_data)[odd].status = ODD;
1293 1292
      matchedToOdd(odd);
1294 1293
      (*_blossom_data)[odd].pred = arc;
1295 1294

	
1296 1295
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1297 1296
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
1298 1297
      _tree_set->insert(even, tree);
1299 1298
      (*_blossom_data)[even].status = EVEN;
1300 1299
      matchedToEven(even, tree);
1301 1300
    }
1302 1301

	
1303 1302
    void shrinkOnEdge(const Edge& edge, int tree) {
1304 1303
      int nca = -1;
1305 1304
      std::vector<int> left_path, right_path;
1306 1305

	
1307 1306
      {
1308 1307
        std::set<int> left_set, right_set;
1309 1308
        int left = _blossom_set->find(_graph.u(edge));
1310 1309
        left_path.push_back(left);
1311 1310
        left_set.insert(left);
1312 1311

	
1313 1312
        int right = _blossom_set->find(_graph.v(edge));
1314 1313
        right_path.push_back(right);
1315 1314
        right_set.insert(right);
1316 1315

	
1317 1316
        while (true) {
1318 1317

	
1319 1318
          if ((*_blossom_data)[left].pred == INVALID) break;
1320 1319

	
1321 1320
          left =
1322 1321
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1323 1322
          left_path.push_back(left);
1324 1323
          left =
1325 1324
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1326 1325
          left_path.push_back(left);
1327 1326

	
1328 1327
          left_set.insert(left);
1329 1328

	
1330 1329
          if (right_set.find(left) != right_set.end()) {
1331 1330
            nca = left;
1332 1331
            break;
1333 1332
          }
1334 1333

	
1335 1334
          if ((*_blossom_data)[right].pred == INVALID) break;
1336 1335

	
1337 1336
          right =
1338 1337
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1339 1338
          right_path.push_back(right);
1340 1339
          right =
1341 1340
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1342 1341
          right_path.push_back(right);
1343 1342

	
1344 1343
          right_set.insert(right);
1345 1344

	
1346 1345
          if (left_set.find(right) != left_set.end()) {
1347 1346
            nca = right;
1348 1347
            break;
1349 1348
          }
1350 1349

	
1351 1350
        }
1352 1351

	
1353 1352
        if (nca == -1) {
1354 1353
          if ((*_blossom_data)[left].pred == INVALID) {
1355 1354
            nca = right;
1356 1355
            while (left_set.find(nca) == left_set.end()) {
1357 1356
              nca =
1358 1357
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1359 1358
              right_path.push_back(nca);
1360 1359
              nca =
1361 1360
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1362 1361
              right_path.push_back(nca);
1363 1362
            }
1364 1363
          } else {
1365 1364
            nca = left;
1366 1365
            while (right_set.find(nca) == right_set.end()) {
1367 1366
              nca =
1368 1367
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1369 1368
              left_path.push_back(nca);
1370 1369
              nca =
1371 1370
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1372 1371
              left_path.push_back(nca);
1373 1372
            }
1374 1373
          }
1375 1374
        }
1376 1375
      }
1377 1376

	
1378 1377
      std::vector<int> subblossoms;
1379 1378
      Arc prev;
1380 1379

	
1381 1380
      prev = _graph.direct(edge, true);
1382 1381
      for (int i = 0; left_path[i] != nca; i += 2) {
1383 1382
        subblossoms.push_back(left_path[i]);
1384 1383
        (*_blossom_data)[left_path[i]].next = prev;
1385 1384
        _tree_set->erase(left_path[i]);
1386 1385

	
1387 1386
        subblossoms.push_back(left_path[i + 1]);
1388 1387
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
1389 1388
        oddToEven(left_path[i + 1], tree);
1390 1389
        _tree_set->erase(left_path[i + 1]);
1391 1390
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
1392 1391
      }
1393 1392

	
1394 1393
      int k = 0;
1395 1394
      while (right_path[k] != nca) ++k;
1396 1395

	
1397 1396
      subblossoms.push_back(nca);
1398 1397
      (*_blossom_data)[nca].next = prev;
1399 1398

	
1400 1399
      for (int i = k - 2; i >= 0; i -= 2) {
1401 1400
        subblossoms.push_back(right_path[i + 1]);
1402 1401
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
1403 1402
        oddToEven(right_path[i + 1], tree);
1404 1403
        _tree_set->erase(right_path[i + 1]);
1405 1404

	
1406 1405
        (*_blossom_data)[right_path[i + 1]].next =
1407 1406
          (*_blossom_data)[right_path[i + 1]].pred;
1408 1407

	
1409 1408
        subblossoms.push_back(right_path[i]);
1410 1409
        _tree_set->erase(right_path[i]);
1411 1410
      }
1412 1411

	
1413 1412
      int surface =
1414 1413
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
1415 1414

	
1416 1415
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1417 1416
        if (!_blossom_set->trivial(subblossoms[i])) {
1418 1417
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
1419 1418
        }
1420 1419
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
1421 1420
      }
1422 1421

	
1423 1422
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
1424 1423
      (*_blossom_data)[surface].offset = 0;
1425 1424
      (*_blossom_data)[surface].status = EVEN;
1426 1425
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
1427 1426
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
1428 1427

	
1429 1428
      _tree_set->insert(surface, tree);
1430 1429
      _tree_set->erase(nca);
1431 1430
    }
1432 1431

	
1433 1432
    void splitBlossom(int blossom) {
1434 1433
      Arc next = (*_blossom_data)[blossom].next;
1435 1434
      Arc pred = (*_blossom_data)[blossom].pred;
1436 1435

	
1437 1436
      int tree = _tree_set->find(blossom);
1438 1437

	
1439 1438
      (*_blossom_data)[blossom].status = MATCHED;
1440 1439
      oddToMatched(blossom);
1441 1440
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1442 1441
        _delta2->erase(blossom);
1443 1442
      }
1444 1443

	
1445 1444
      std::vector<int> subblossoms;
1446 1445
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
1447 1446

	
1448 1447
      Value offset = (*_blossom_data)[blossom].offset;
1449 1448
      int b = _blossom_set->find(_graph.source(pred));
1450 1449
      int d = _blossom_set->find(_graph.source(next));
1451 1450

	
1452 1451
      int ib = -1, id = -1;
1453 1452
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1454 1453
        if (subblossoms[i] == b) ib = i;
1455 1454
        if (subblossoms[i] == d) id = i;
1456 1455

	
1457 1456
        (*_blossom_data)[subblossoms[i]].offset = offset;
1458 1457
        if (!_blossom_set->trivial(subblossoms[i])) {
1459 1458
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
1460 1459
        }
1461 1460
        if (_blossom_set->classPrio(subblossoms[i]) !=
1462 1461
            std::numeric_limits<Value>::max()) {
1463 1462
          _delta2->push(subblossoms[i],
1464 1463
                        _blossom_set->classPrio(subblossoms[i]) -
1465 1464
                        (*_blossom_data)[subblossoms[i]].offset);
1466 1465
        }
1467 1466
      }
1468 1467

	
1469 1468
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1470 1469
        for (int i = (id + 1) % subblossoms.size();
1471 1470
             i != ib; i = (i + 2) % subblossoms.size()) {
1472 1471
          int sb = subblossoms[i];
1473 1472
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1474 1473
          (*_blossom_data)[sb].next =
1475 1474
            _graph.oppositeArc((*_blossom_data)[tb].next);
1476 1475
        }
1477 1476

	
1478 1477
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1479 1478
          int sb = subblossoms[i];
1480 1479
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1481 1480
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1482 1481

	
1483 1482
          (*_blossom_data)[sb].status = ODD;
1484 1483
          matchedToOdd(sb);
1485 1484
          _tree_set->insert(sb, tree);
1486 1485
          (*_blossom_data)[sb].pred = pred;
1487 1486
          (*_blossom_data)[sb].next =
1488 1487
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1489 1488

	
1490 1489
          pred = (*_blossom_data)[ub].next;
1491 1490

	
1492 1491
          (*_blossom_data)[tb].status = EVEN;
1493 1492
          matchedToEven(tb, tree);
1494 1493
          _tree_set->insert(tb, tree);
1495 1494
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1496 1495
        }
1497 1496

	
1498 1497
        (*_blossom_data)[subblossoms[id]].status = ODD;
1499 1498
        matchedToOdd(subblossoms[id]);
1500 1499
        _tree_set->insert(subblossoms[id], tree);
1501 1500
        (*_blossom_data)[subblossoms[id]].next = next;
1502 1501
        (*_blossom_data)[subblossoms[id]].pred = pred;
1503 1502

	
1504 1503
      } else {
1505 1504

	
1506 1505
        for (int i = (ib + 1) % subblossoms.size();
1507 1506
             i != id; i = (i + 2) % subblossoms.size()) {
1508 1507
          int sb = subblossoms[i];
1509 1508
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1510 1509
          (*_blossom_data)[sb].next =
1511 1510
            _graph.oppositeArc((*_blossom_data)[tb].next);
1512 1511
        }
1513 1512

	
1514 1513
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
1515 1514
          int sb = subblossoms[i];
1516 1515
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1517 1516
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1518 1517

	
1519 1518
          (*_blossom_data)[sb].status = ODD;
1520 1519
          matchedToOdd(sb);
1521 1520
          _tree_set->insert(sb, tree);
1522 1521
          (*_blossom_data)[sb].next = next;
1523 1522
          (*_blossom_data)[sb].pred =
1524 1523
            _graph.oppositeArc((*_blossom_data)[tb].next);
1525 1524

	
1526 1525
          (*_blossom_data)[tb].status = EVEN;
1527 1526
          matchedToEven(tb, tree);
1528 1527
          _tree_set->insert(tb, tree);
1529 1528
          (*_blossom_data)[tb].pred =
1530 1529
            (*_blossom_data)[tb].next =
1531 1530
            _graph.oppositeArc((*_blossom_data)[ub].next);
1532 1531
          next = (*_blossom_data)[ub].next;
1533 1532
        }
1534 1533

	
1535 1534
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1536 1535
        matchedToOdd(subblossoms[ib]);
1537 1536
        _tree_set->insert(subblossoms[ib], tree);
1538 1537
        (*_blossom_data)[subblossoms[ib]].next = next;
1539 1538
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1540 1539
      }
1541 1540
      _tree_set->erase(blossom);
1542 1541
    }
1543 1542

	
1544 1543
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1545 1544
      if (_blossom_set->trivial(blossom)) {
1546 1545
        int bi = (*_node_index)[base];
1547 1546
        Value pot = (*_node_data)[bi].pot;
1548 1547

	
1549 1548
        _matching->set(base, matching);
1550 1549
        _blossom_node_list.push_back(base);
1551 1550
        _node_potential->set(base, pot);
1552 1551
      } else {
1553 1552

	
1554 1553
        Value pot = (*_blossom_data)[blossom].pot;
1555 1554
        int bn = _blossom_node_list.size();
1556 1555

	
1557 1556
        std::vector<int> subblossoms;
1558 1557
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1559 1558
        int b = _blossom_set->find(base);
1560 1559
        int ib = -1;
1561 1560
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1562 1561
          if (subblossoms[i] == b) { ib = i; break; }
1563 1562
        }
1564 1563

	
1565 1564
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1566 1565
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1567 1566
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1568 1567

	
1569 1568
          Arc m = (*_blossom_data)[tb].next;
1570 1569
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1571 1570
          extractBlossom(tb, _graph.source(m), m);
1572 1571
        }
1573 1572
        extractBlossom(subblossoms[ib], base, matching);
1574 1573

	
1575 1574
        int en = _blossom_node_list.size();
1576 1575

	
1577 1576
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1578 1577
      }
1579 1578
    }
1580 1579

	
1581 1580
    void extractMatching() {
1582 1581
      std::vector<int> blossoms;
1583 1582
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1584 1583
        blossoms.push_back(c);
1585 1584
      }
1586 1585

	
1587 1586
      for (int i = 0; i < int(blossoms.size()); ++i) {
1588 1587
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1589 1588

	
1590 1589
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1591 1590
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1592 1591
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1593 1592
               n != INVALID; ++n) {
1594 1593
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1595 1594
          }
1596 1595

	
1597 1596
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1598 1597
          Node base = _graph.source(matching);
1599 1598
          extractBlossom(blossoms[i], base, matching);
1600 1599
        } else {
1601 1600
          Node base = (*_blossom_data)[blossoms[i]].base;
1602 1601
          extractBlossom(blossoms[i], base, INVALID);
1603 1602
        }
1604 1603
      }
1605 1604
    }
1606 1605

	
1607 1606
  public:
1608 1607

	
1609 1608
    /// \brief Constructor
1610 1609
    ///
1611 1610
    /// Constructor.
1612 1611
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1613 1612
      : _graph(graph), _weight(weight), _matching(0),
1614 1613
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1615 1614
        _node_num(0), _blossom_num(0),
1616 1615

	
1617 1616
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1618 1617
        _node_index(0), _node_heap_index(0), _node_data(0),
1619 1618
        _tree_set_index(0), _tree_set(0),
1620 1619

	
1621 1620
        _delta1_index(0), _delta1(0),
1622 1621
        _delta2_index(0), _delta2(0),
1623 1622
        _delta3_index(0), _delta3(0),
1624 1623
        _delta4_index(0), _delta4(0),
1625 1624

	
1626 1625
        _delta_sum() {}
1627 1626

	
1628 1627
    ~MaxWeightedMatching() {
1629 1628
      destroyStructures();
1630 1629
    }
1631 1630

	
1632 1631
    /// \name Execution control
1633
    /// The simplest way to execute the algorithm is to use the member
1632
    /// The simplest way to execute the algorithm is to use the
1634 1633
    /// \c run() member function.
1635 1634

	
1636 1635
    ///@{
1637 1636

	
1638 1637
    /// \brief Initialize the algorithm
1639 1638
    ///
1640 1639
    /// Initialize the algorithm
1641 1640
    void init() {
1642 1641
      createStructures();
1643 1642

	
1644 1643
      for (ArcIt e(_graph); e != INVALID; ++e) {
1645 1644
        _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
1646 1645
      }
1647 1646
      for (NodeIt n(_graph); n != INVALID; ++n) {
1648 1647
        _delta1_index->set(n, _delta1->PRE_HEAP);
1649 1648
      }
1650 1649
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1651 1650
        _delta3_index->set(e, _delta3->PRE_HEAP);
1652 1651
      }
1653 1652
      for (int i = 0; i < _blossom_num; ++i) {
1654 1653
        _delta2_index->set(i, _delta2->PRE_HEAP);
1655 1654
        _delta4_index->set(i, _delta4->PRE_HEAP);
1656 1655
      }
1657 1656

	
1658 1657
      int index = 0;
1659 1658
      for (NodeIt n(_graph); n != INVALID; ++n) {
1660 1659
        Value max = 0;
1661 1660
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1662 1661
          if (_graph.target(e) == n) continue;
1663 1662
          if ((dualScale * _weight[e]) / 2 > max) {
1664 1663
            max = (dualScale * _weight[e]) / 2;
1665 1664
          }
1666 1665
        }
1667 1666
        _node_index->set(n, index);
1668 1667
        (*_node_data)[index].pot = max;
1669 1668
        _delta1->push(n, max);
1670 1669
        int blossom =
1671 1670
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1672 1671

	
1673 1672
        _tree_set->insert(blossom);
1674 1673

	
1675 1674
        (*_blossom_data)[blossom].status = EVEN;
1676 1675
        (*_blossom_data)[blossom].pred = INVALID;
1677 1676
        (*_blossom_data)[blossom].next = INVALID;
1678 1677
        (*_blossom_data)[blossom].pot = 0;
1679 1678
        (*_blossom_data)[blossom].offset = 0;
1680 1679
        ++index;
1681 1680
      }
1682 1681
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1683 1682
        int si = (*_node_index)[_graph.u(e)];
1684 1683
        int ti = (*_node_index)[_graph.v(e)];
1685 1684
        if (_graph.u(e) != _graph.v(e)) {
1686 1685
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1687 1686
                            dualScale * _weight[e]) / 2);
1688 1687
        }
1689 1688
      }
1690 1689
    }
1691 1690

	
1692 1691
    /// \brief Starts the algorithm
1693 1692
    ///
1694 1693
    /// Starts the algorithm
1695 1694
    void start() {
1696 1695
      enum OpType {
1697 1696
        D1, D2, D3, D4
1698 1697
      };
1699 1698

	
1700 1699
      int unmatched = _node_num;
1701 1700
      while (unmatched > 0) {
1702 1701
        Value d1 = !_delta1->empty() ?
1703 1702
          _delta1->prio() : std::numeric_limits<Value>::max();
1704 1703

	
1705 1704
        Value d2 = !_delta2->empty() ?
1706 1705
          _delta2->prio() : std::numeric_limits<Value>::max();
1707 1706

	
1708 1707
        Value d3 = !_delta3->empty() ?
1709 1708
          _delta3->prio() : std::numeric_limits<Value>::max();
1710 1709

	
1711 1710
        Value d4 = !_delta4->empty() ?
1712 1711
          _delta4->prio() : std::numeric_limits<Value>::max();
1713 1712

	
1714 1713
        _delta_sum = d1; OpType ot = D1;
1715 1714
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1716 1715
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1717 1716
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1718 1717

	
1719 1718

	
1720 1719
        switch (ot) {
1721 1720
        case D1:
1722 1721
          {
1723 1722
            Node n = _delta1->top();
1724 1723
            unmatchNode(n);
1725 1724
            --unmatched;
1726 1725
          }
1727 1726
          break;
1728 1727
        case D2:
1729 1728
          {
1730 1729
            int blossom = _delta2->top();
1731 1730
            Node n = _blossom_set->classTop(blossom);
1732 1731
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1733 1732
            extendOnArc(e);
1734 1733
          }
1735 1734
          break;
1736 1735
        case D3:
1737 1736
          {
1738 1737
            Edge e = _delta3->top();
1739 1738

	
1740 1739
            int left_blossom = _blossom_set->find(_graph.u(e));
1741 1740
            int right_blossom = _blossom_set->find(_graph.v(e));
1742 1741

	
1743 1742
            if (left_blossom == right_blossom) {
1744 1743
              _delta3->pop();
1745 1744
            } else {
1746 1745
              int left_tree;
1747 1746
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1748 1747
                left_tree = _tree_set->find(left_blossom);
1749 1748
              } else {
1750 1749
                left_tree = -1;
1751 1750
                ++unmatched;
1752 1751
              }
1753 1752
              int right_tree;
1754 1753
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1755 1754
                right_tree = _tree_set->find(right_blossom);
1756 1755
              } else {
1757 1756
                right_tree = -1;
1758 1757
                ++unmatched;
1759 1758
              }
1760 1759

	
1761 1760
              if (left_tree == right_tree) {
1762 1761
                shrinkOnEdge(e, left_tree);
1763 1762
              } else {
1764 1763
                augmentOnEdge(e);
1765 1764
                unmatched -= 2;
1766 1765
              }
1767 1766
            }
1768 1767
          } break;
1769 1768
        case D4:
1770 1769
          splitBlossom(_delta4->top());
1771 1770
          break;
1772 1771
        }
1773 1772
      }
1774 1773
      extractMatching();
1775 1774
    }
1776 1775

	
1777 1776
    /// \brief Runs %MaxWeightedMatching algorithm.
1778 1777
    ///
1779 1778
    /// This method runs the %MaxWeightedMatching algorithm.
1780 1779
    ///
1781 1780
    /// \note mwm.run() is just a shortcut of the following code.
1782 1781
    /// \code
1783 1782
    ///   mwm.init();
1784 1783
    ///   mwm.start();
1785 1784
    /// \endcode
1786 1785
    void run() {
1787 1786
      init();
1788 1787
      start();
1789 1788
    }
1790 1789

	
1791 1790
    /// @}
1792 1791

	
1793 1792
    /// \name Primal solution
1794
    /// Functions for get the primal solution, ie. the matching.
1793
    /// Functions to get the primal solution, ie. the matching.
1795 1794

	
1796 1795
    /// @{
1797 1796

	
1798
    /// \brief Returns the matching value.
1797
    /// \brief Returns the weight of the matching.
1799 1798
    ///
1800
    /// Returns the matching value.
1799
    /// Returns the weight of the matching.
1801 1800
    Value matchingValue() const {
1802 1801
      Value sum = 0;
1803 1802
      for (NodeIt n(_graph); n != INVALID; ++n) {
1804 1803
        if ((*_matching)[n] != INVALID) {
1805 1804
          sum += _weight[(*_matching)[n]];
1806 1805
        }
1807 1806
      }
1808 1807
      return sum /= 2;
1809 1808
    }
1810 1809

	
1811 1810
    /// \brief Returns the cardinality of the matching.
1812 1811
    ///
1813 1812
    /// Returns the cardinality of the matching.
1814 1813
    int matchingSize() const {
1815 1814
      int num = 0;
1816 1815
      for (NodeIt n(_graph); n != INVALID; ++n) {
1817 1816
        if ((*_matching)[n] != INVALID) {
1818 1817
          ++num;
1819 1818
        }
1820 1819
      }
1821 1820
      return num /= 2;
1822 1821
    }
1823 1822

	
1824 1823
    /// \brief Returns true when the edge is in the matching.
1825 1824
    ///
1826 1825
    /// Returns true when the edge is in the matching.
1827 1826
    bool matching(const Edge& edge) const {
1828 1827
      return edge == (*_matching)[_graph.u(edge)];
1829 1828
    }
1830 1829

	
1831 1830
    /// \brief Returns the incident matching arc.
1832 1831
    ///
1833 1832
    /// Returns the incident matching arc from given node. If the
1834 1833
    /// node is not matched then it gives back \c INVALID.
1835 1834
    Arc matching(const Node& node) const {
1836 1835
      return (*_matching)[node];
1837 1836
    }
1838 1837

	
1839 1838
    /// \brief Returns the mate of the node.
1840 1839
    ///
1841 1840
    /// Returns the adjancent node in a mathcing arc. If the node is
1842 1841
    /// not matched then it gives back \c INVALID.
1843 1842
    Node mate(const Node& node) const {
1844 1843
      return (*_matching)[node] != INVALID ?
1845 1844
        _graph.target((*_matching)[node]) : INVALID;
1846 1845
    }
1847 1846

	
1848 1847
    /// @}
1849 1848

	
1850 1849
    /// \name Dual solution
1851
    /// Functions for get the dual solution.
1850
    /// Functions to get the dual solution.
1852 1851

	
1853 1852
    /// @{
1854 1853

	
1855 1854
    /// \brief Returns the value of the dual solution.
1856 1855
    ///
1857 1856
    /// Returns the value of the dual solution. It should be equal to
1858 1857
    /// the primal value scaled by \ref dualScale "dual scale".
1859 1858
    Value dualValue() const {
1860 1859
      Value sum = 0;
1861 1860
      for (NodeIt n(_graph); n != INVALID; ++n) {
1862 1861
        sum += nodeValue(n);
1863 1862
      }
1864 1863
      for (int i = 0; i < blossomNum(); ++i) {
1865 1864
        sum += blossomValue(i) * (blossomSize(i) / 2);
1866 1865
      }
1867 1866
      return sum;
1868 1867
    }
1869 1868

	
1870 1869
    /// \brief Returns the value of the node.
1871 1870
    ///
1872 1871
    /// Returns the the value of the node.
1873 1872
    Value nodeValue(const Node& n) const {
1874 1873
      return (*_node_potential)[n];
1875 1874
    }
1876 1875

	
1877 1876
    /// \brief Returns the number of the blossoms in the basis.
1878 1877
    ///
1879 1878
    /// Returns the number of the blossoms in the basis.
1880 1879
    /// \see BlossomIt
1881 1880
    int blossomNum() const {
1882 1881
      return _blossom_potential.size();
1883 1882
    }
1884 1883

	
1885 1884

	
1886 1885
    /// \brief Returns the number of the nodes in the blossom.
1887 1886
    ///
1888 1887
    /// Returns the number of the nodes in the blossom.
1889 1888
    int blossomSize(int k) const {
1890 1889
      return _blossom_potential[k].end - _blossom_potential[k].begin;
1891 1890
    }
1892 1891

	
1893 1892
    /// \brief Returns the value of the blossom.
1894 1893
    ///
1895 1894
    /// Returns the the value of the blossom.
1896 1895
    /// \see BlossomIt
1897 1896
    Value blossomValue(int k) const {
1898 1897
      return _blossom_potential[k].value;
1899 1898
    }
1900 1899

	
1901
    /// \brief Lemon iterator for get the items of the blossom.
1900
    /// \brief Iterator for obtaining the nodes of the blossom.
1902 1901
    ///
1903
    /// Lemon iterator for get the nodes of the blossom. This class
1904
    /// provides a common style lemon iterator which gives back a
1902
    /// Iterator for obtaining the nodes of the blossom. This class
1903
    /// provides a common lemon style iterator for listing a
1905 1904
    /// subset of the nodes.
1906 1905
    class BlossomIt {
1907 1906
    public:
1908 1907

	
1909 1908
      /// \brief Constructor.
1910 1909
      ///
1911
      /// Constructor for get the nodes of the variable.
1910
      /// Constructor to get the nodes of the variable.
1912 1911
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
1913 1912
        : _algorithm(&algorithm)
1914 1913
      {
1915 1914
        _index = _algorithm->_blossom_potential[variable].begin;
1916 1915
        _last = _algorithm->_blossom_potential[variable].end;
1917 1916
      }
1918 1917

	
1919 1918
      /// \brief Conversion to node.
1920 1919
      ///
1921 1920
      /// Conversion to node.
1922 1921
      operator Node() const {
1923 1922
        return _algorithm->_blossom_node_list[_index];
1924 1923
      }
1925 1924

	
1926 1925
      /// \brief Increment operator.
1927 1926
      ///
1928 1927
      /// Increment operator.
1929 1928
      BlossomIt& operator++() {
1930 1929
        ++_index;
1931 1930
        return *this;
1932 1931
      }
1933 1932

	
1934 1933
      /// \brief Validity checking
1935 1934
      ///
1936 1935
      /// Checks whether the iterator is invalid.
1937 1936
      bool operator==(Invalid) const { return _index == _last; }
1938 1937

	
1939 1938
      /// \brief Validity checking
1940 1939
      ///
1941 1940
      /// Checks whether the iterator is valid.
1942 1941
      bool operator!=(Invalid) const { return _index != _last; }
1943 1942

	
1944 1943
    private:
1945 1944
      const MaxWeightedMatching* _algorithm;
1946 1945
      int _last;
1947 1946
      int _index;
1948 1947
    };
1949 1948

	
1950 1949
    /// @}
1951 1950

	
1952 1951
  };
1953 1952

	
1954 1953
  /// \ingroup matching
1955 1954
  ///
1956 1955
  /// \brief Weighted perfect matching in general graphs
1957 1956
  ///
1958 1957
  /// This class provides an efficient implementation of Edmond's
1959 1958
  /// maximum weighted perfect matching algorithm. The implementation
1960 1959
  /// is based on extensive use of priority queues and provides
1961 1960
  /// \f$O(nm\log(n))\f$ time complexity.
1962 1961
  ///
1963 1962
  /// The maximum weighted matching problem is to find undirected
1964 1963
  /// edges in the graph with maximum overall weight and no two of
1965 1964
  /// them shares their ends and covers all nodes. The problem can be
1966 1965
  /// formulated with the following linear program.
1967 1966
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
1968 1967
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
1969 1968
      \quad \forall B\in\mathcal{O}\f] */
1970 1969
  /// \f[x_e \ge 0\quad \forall e\in E\f]
1971 1970
  /// \f[\max \sum_{e\in E}x_ew_e\f]
1972 1971
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
1973 1972
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
1974 1973
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
1975 1974
  /// subsets of the nodes.
1976 1975
  ///
1977 1976
  /// The algorithm calculates an optimal matching and a proof of the
1978 1977
  /// optimality. The solution of the dual problem can be used to check
1979 1978
  /// the result of the algorithm. The dual linear problem is the
1980 1979
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
1981 1980
      w_{uv} \quad \forall uv\in E\f] */
1982 1981
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
1983 1982
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
1984 1983
      \frac{\vert B \vert - 1}{2}z_B\f] */
1985 1984
  ///
1986 1985
  /// The algorithm can be executed with \c run() or the \c init() and
1987 1986
  /// then the \c start() member functions. After it the matching can
1988 1987
  /// be asked with \c matching() or mate() functions. The dual
1989 1988
  /// solution can be get with \c nodeValue(), \c blossomNum() and \c
1990 1989
  /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
1991 1990
  /// "BlossomIt" nested class which is able to iterate on the nodes
1992 1991
  /// of a blossom. If the value type is integral then the dual
1993 1992
  /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
1994 1993
  template <typename _Graph,
1995 1994
            typename _WeightMap = typename _Graph::template EdgeMap<int> >
1996 1995
  class MaxWeightedPerfectMatching {
1997 1996
  public:
1998 1997

	
1999 1998
    typedef _Graph Graph;
2000 1999
    typedef _WeightMap WeightMap;
2001 2000
    typedef typename WeightMap::Value Value;
2002 2001

	
2003 2002
    /// \brief Scaling factor for dual solution
2004 2003
    ///
2005 2004
    /// Scaling factor for dual solution, it is equal to 4 or 1
2006 2005
    /// according to the value type.
2007 2006
    static const int dualScale =
2008 2007
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2009 2008

	
2010 2009
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2011 2010
    MatchingMap;
2012 2011

	
2013 2012
  private:
2014 2013

	
2015 2014
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2016 2015

	
2017 2016
    typedef typename Graph::template NodeMap<Value> NodePotential;
2018 2017
    typedef std::vector<Node> BlossomNodeList;
2019 2018

	
2020 2019
    struct BlossomVariable {
2021 2020
      int begin, end;
2022 2021
      Value value;
2023 2022

	
2024 2023
      BlossomVariable(int _begin, int _end, Value _value)
2025 2024
        : begin(_begin), end(_end), value(_value) {}
2026 2025

	
2027 2026
    };
2028 2027

	
2029 2028
    typedef std::vector<BlossomVariable> BlossomPotential;
2030 2029

	
2031 2030
    const Graph& _graph;
2032 2031
    const WeightMap& _weight;
2033 2032

	
2034 2033
    MatchingMap* _matching;
2035 2034

	
2036 2035
    NodePotential* _node_potential;
2037 2036

	
2038 2037
    BlossomPotential _blossom_potential;
2039 2038
    BlossomNodeList _blossom_node_list;
2040 2039

	
2041 2040
    int _node_num;
2042 2041
    int _blossom_num;
2043 2042

	
2044 2043
    typedef RangeMap<int> IntIntMap;
2045 2044

	
2046 2045
    enum Status {
2047 2046
      EVEN = -1, MATCHED = 0, ODD = 1
2048 2047
    };
2049 2048

	
2050 2049
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2051 2050
    struct BlossomData {
2052 2051
      int tree;
2053 2052
      Status status;
2054 2053
      Arc pred, next;
2055 2054
      Value pot, offset;
2056 2055
    };
2057 2056

	
2058 2057
    IntNodeMap *_blossom_index;
2059 2058
    BlossomSet *_blossom_set;
2060 2059
    RangeMap<BlossomData>* _blossom_data;
2061 2060

	
2062 2061
    IntNodeMap *_node_index;
2063 2062
    IntArcMap *_node_heap_index;
2064 2063

	
2065 2064
    struct NodeData {
2066 2065

	
2067 2066
      NodeData(IntArcMap& node_heap_index)
2068 2067
        : heap(node_heap_index) {}
2069 2068

	
2070 2069
      int blossom;
2071 2070
      Value pot;
2072 2071
      BinHeap<Value, IntArcMap> heap;
2073 2072
      std::map<int, Arc> heap_index;
2074 2073

	
2075 2074
      int tree;
2076 2075
    };
2077 2076

	
2078 2077
    RangeMap<NodeData>* _node_data;
2079 2078

	
2080 2079
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2081 2080

	
2082 2081
    IntIntMap *_tree_set_index;
2083 2082
    TreeSet *_tree_set;
2084 2083

	
2085 2084
    IntIntMap *_delta2_index;
2086 2085
    BinHeap<Value, IntIntMap> *_delta2;
2087 2086

	
2088 2087
    IntEdgeMap *_delta3_index;
2089 2088
    BinHeap<Value, IntEdgeMap> *_delta3;
2090 2089

	
2091 2090
    IntIntMap *_delta4_index;
2092 2091
    BinHeap<Value, IntIntMap> *_delta4;
2093 2092

	
2094 2093
    Value _delta_sum;
2095 2094

	
2096 2095
    void createStructures() {
2097 2096
      _node_num = countNodes(_graph);
2098 2097
      _blossom_num = _node_num * 3 / 2;
2099 2098

	
2100 2099
      if (!_matching) {
2101 2100
        _matching = new MatchingMap(_graph);
2102 2101
      }
2103 2102
      if (!_node_potential) {
2104 2103
        _node_potential = new NodePotential(_graph);
2105 2104
      }
2106 2105
      if (!_blossom_set) {
2107 2106
        _blossom_index = new IntNodeMap(_graph);
2108 2107
        _blossom_set = new BlossomSet(*_blossom_index);
2109 2108
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2110 2109
      }
2111 2110

	
2112 2111
      if (!_node_index) {
2113 2112
        _node_index = new IntNodeMap(_graph);
2114 2113
        _node_heap_index = new IntArcMap(_graph);
2115 2114
        _node_data = new RangeMap<NodeData>(_node_num,
2116 2115
                                            NodeData(*_node_heap_index));
2117 2116
      }
2118 2117

	
2119 2118
      if (!_tree_set) {
2120 2119
        _tree_set_index = new IntIntMap(_blossom_num);
2121 2120
        _tree_set = new TreeSet(*_tree_set_index);
2122 2121
      }
2123 2122
      if (!_delta2) {
2124 2123
        _delta2_index = new IntIntMap(_blossom_num);
2125 2124
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2126 2125
      }
2127 2126
      if (!_delta3) {
2128 2127
        _delta3_index = new IntEdgeMap(_graph);
2129 2128
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2130 2129
      }
2131 2130
      if (!_delta4) {
2132 2131
        _delta4_index = new IntIntMap(_blossom_num);
2133 2132
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2134 2133
      }
2135 2134
    }
2136 2135

	
2137 2136
    void destroyStructures() {
2138 2137
      _node_num = countNodes(_graph);
2139 2138
      _blossom_num = _node_num * 3 / 2;
2140 2139

	
2141 2140
      if (_matching) {
2142 2141
        delete _matching;
2143 2142
      }
2144 2143
      if (_node_potential) {
2145 2144
        delete _node_potential;
2146 2145
      }
2147 2146
      if (_blossom_set) {
2148 2147
        delete _blossom_index;
2149 2148
        delete _blossom_set;
2150 2149
        delete _blossom_data;
2151 2150
      }
2152 2151

	
2153 2152
      if (_node_index) {
2154 2153
        delete _node_index;
2155 2154
        delete _node_heap_index;
2156 2155
        delete _node_data;
2157 2156
      }
2158 2157

	
2159 2158
      if (_tree_set) {
2160 2159
        delete _tree_set_index;
2161 2160
        delete _tree_set;
2162 2161
      }
2163 2162
      if (_delta2) {
2164 2163
        delete _delta2_index;
2165 2164
        delete _delta2;
2166 2165
      }
2167 2166
      if (_delta3) {
2168 2167
        delete _delta3_index;
2169 2168
        delete _delta3;
2170 2169
      }
2171 2170
      if (_delta4) {
2172 2171
        delete _delta4_index;
2173 2172
        delete _delta4;
2174 2173
      }
2175 2174
    }
2176 2175

	
2177 2176
    void matchedToEven(int blossom, int tree) {
2178 2177
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2179 2178
        _delta2->erase(blossom);
2180 2179
      }
2181 2180

	
2182 2181
      if (!_blossom_set->trivial(blossom)) {
2183 2182
        (*_blossom_data)[blossom].pot -=
2184 2183
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2185 2184
      }
2186 2185

	
2187 2186
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2188 2187
           n != INVALID; ++n) {
2189 2188

	
2190 2189
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2191 2190
        int ni = (*_node_index)[n];
2192 2191

	
2193 2192
        (*_node_data)[ni].heap.clear();
2194 2193
        (*_node_data)[ni].heap_index.clear();
2195 2194

	
2196 2195
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
2197 2196

	
2198 2197
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2199 2198
          Node v = _graph.source(e);
2200 2199
          int vb = _blossom_set->find(v);
2201 2200
          int vi = (*_node_index)[v];
2202 2201

	
2203 2202
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2204 2203
            dualScale * _weight[e];
2205 2204

	
2206 2205
          if ((*_blossom_data)[vb].status == EVEN) {
2207 2206
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2208 2207
              _delta3->push(e, rw / 2);
2209 2208
            }
2210 2209
          } else {
2211 2210
            typename std::map<int, Arc>::iterator it =
2212 2211
              (*_node_data)[vi].heap_index.find(tree);
2213 2212

	
2214 2213
            if (it != (*_node_data)[vi].heap_index.end()) {
2215 2214
              if ((*_node_data)[vi].heap[it->second] > rw) {
2216 2215
                (*_node_data)[vi].heap.replace(it->second, e);
2217 2216
                (*_node_data)[vi].heap.decrease(e, rw);
2218 2217
                it->second = e;
2219 2218
              }
2220 2219
            } else {
2221 2220
              (*_node_data)[vi].heap.push(e, rw);
2222 2221
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2223 2222
            }
2224 2223

	
2225 2224
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2226 2225
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2227 2226

	
2228 2227
              if ((*_blossom_data)[vb].status == MATCHED) {
2229 2228
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2230 2229
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2231 2230
                               (*_blossom_data)[vb].offset);
2232 2231
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2233 2232
                           (*_blossom_data)[vb].offset){
2234 2233
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2235 2234
                                   (*_blossom_data)[vb].offset);
2236 2235
                }
2237 2236
              }
2238 2237
            }
2239 2238
          }
2240 2239
        }
2241 2240
      }
2242 2241
      (*_blossom_data)[blossom].offset = 0;
2243 2242
    }
2244 2243

	
2245 2244
    void matchedToOdd(int blossom) {
2246 2245
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2247 2246
        _delta2->erase(blossom);
2248 2247
      }
2249 2248
      (*_blossom_data)[blossom].offset += _delta_sum;
2250 2249
      if (!_blossom_set->trivial(blossom)) {
2251 2250
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
2252 2251
                     (*_blossom_data)[blossom].offset);
2253 2252
      }
2254 2253
    }
2255 2254

	
2256 2255
    void evenToMatched(int blossom, int tree) {
2257 2256
      if (!_blossom_set->trivial(blossom)) {
2258 2257
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
2259 2258
      }
2260 2259

	
2261 2260
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2262 2261
           n != INVALID; ++n) {
2263 2262
        int ni = (*_node_index)[n];
2264 2263
        (*_node_data)[ni].pot -= _delta_sum;
2265 2264

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

	
2271 2270
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2272 2271
            dualScale * _weight[e];
2273 2272

	
2274 2273
          if (vb == blossom) {
2275 2274
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2276 2275
              _delta3->erase(e);
2277 2276
            }
2278 2277
          } else if ((*_blossom_data)[vb].status == EVEN) {
2279 2278

	
2280 2279
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2281 2280
              _delta3->erase(e);
2282 2281
            }
2283 2282

	
2284 2283
            int vt = _tree_set->find(vb);
2285 2284

	
2286 2285
            if (vt != tree) {
2287 2286

	
2288 2287
              Arc r = _graph.oppositeArc(e);
2289 2288

	
2290 2289
              typename std::map<int, Arc>::iterator it =
2291 2290
                (*_node_data)[ni].heap_index.find(vt);
2292 2291

	
2293 2292
              if (it != (*_node_data)[ni].heap_index.end()) {
2294 2293
                if ((*_node_data)[ni].heap[it->second] > rw) {
2295 2294
                  (*_node_data)[ni].heap.replace(it->second, r);
... ...
@@ -2436,670 +2435,670 @@
2436 2435
        (*_blossom_data)[odd].status = MATCHED;
2437 2436
        oddToMatched(odd);
2438 2437
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
2439 2438

	
2440 2439
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
2441 2440
        (*_blossom_data)[even].status = MATCHED;
2442 2441
        evenToMatched(even, tree);
2443 2442
        (*_blossom_data)[even].next =
2444 2443
          _graph.oppositeArc((*_blossom_data)[odd].pred);
2445 2444
      }
2446 2445

	
2447 2446
    }
2448 2447

	
2449 2448
    void destroyTree(int tree) {
2450 2449
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
2451 2450
        if ((*_blossom_data)[b].status == EVEN) {
2452 2451
          (*_blossom_data)[b].status = MATCHED;
2453 2452
          evenToMatched(b, tree);
2454 2453
        } else if ((*_blossom_data)[b].status == ODD) {
2455 2454
          (*_blossom_data)[b].status = MATCHED;
2456 2455
          oddToMatched(b);
2457 2456
        }
2458 2457
      }
2459 2458
      _tree_set->eraseClass(tree);
2460 2459
    }
2461 2460

	
2462 2461
    void augmentOnEdge(const Edge& edge) {
2463 2462

	
2464 2463
      int left = _blossom_set->find(_graph.u(edge));
2465 2464
      int right = _blossom_set->find(_graph.v(edge));
2466 2465

	
2467 2466
      int left_tree = _tree_set->find(left);
2468 2467
      alternatePath(left, left_tree);
2469 2468
      destroyTree(left_tree);
2470 2469

	
2471 2470
      int right_tree = _tree_set->find(right);
2472 2471
      alternatePath(right, right_tree);
2473 2472
      destroyTree(right_tree);
2474 2473

	
2475 2474
      (*_blossom_data)[left].next = _graph.direct(edge, true);
2476 2475
      (*_blossom_data)[right].next = _graph.direct(edge, false);
2477 2476
    }
2478 2477

	
2479 2478
    void extendOnArc(const Arc& arc) {
2480 2479
      int base = _blossom_set->find(_graph.target(arc));
2481 2480
      int tree = _tree_set->find(base);
2482 2481

	
2483 2482
      int odd = _blossom_set->find(_graph.source(arc));
2484 2483
      _tree_set->insert(odd, tree);
2485 2484
      (*_blossom_data)[odd].status = ODD;
2486 2485
      matchedToOdd(odd);
2487 2486
      (*_blossom_data)[odd].pred = arc;
2488 2487

	
2489 2488
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
2490 2489
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
2491 2490
      _tree_set->insert(even, tree);
2492 2491
      (*_blossom_data)[even].status = EVEN;
2493 2492
      matchedToEven(even, tree);
2494 2493
    }
2495 2494

	
2496 2495
    void shrinkOnEdge(const Edge& edge, int tree) {
2497 2496
      int nca = -1;
2498 2497
      std::vector<int> left_path, right_path;
2499 2498

	
2500 2499
      {
2501 2500
        std::set<int> left_set, right_set;
2502 2501
        int left = _blossom_set->find(_graph.u(edge));
2503 2502
        left_path.push_back(left);
2504 2503
        left_set.insert(left);
2505 2504

	
2506 2505
        int right = _blossom_set->find(_graph.v(edge));
2507 2506
        right_path.push_back(right);
2508 2507
        right_set.insert(right);
2509 2508

	
2510 2509
        while (true) {
2511 2510

	
2512 2511
          if ((*_blossom_data)[left].pred == INVALID) break;
2513 2512

	
2514 2513
          left =
2515 2514
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2516 2515
          left_path.push_back(left);
2517 2516
          left =
2518 2517
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2519 2518
          left_path.push_back(left);
2520 2519

	
2521 2520
          left_set.insert(left);
2522 2521

	
2523 2522
          if (right_set.find(left) != right_set.end()) {
2524 2523
            nca = left;
2525 2524
            break;
2526 2525
          }
2527 2526

	
2528 2527
          if ((*_blossom_data)[right].pred == INVALID) break;
2529 2528

	
2530 2529
          right =
2531 2530
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2532 2531
          right_path.push_back(right);
2533 2532
          right =
2534 2533
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2535 2534
          right_path.push_back(right);
2536 2535

	
2537 2536
          right_set.insert(right);
2538 2537

	
2539 2538
          if (left_set.find(right) != left_set.end()) {
2540 2539
            nca = right;
2541 2540
            break;
2542 2541
          }
2543 2542

	
2544 2543
        }
2545 2544

	
2546 2545
        if (nca == -1) {
2547 2546
          if ((*_blossom_data)[left].pred == INVALID) {
2548 2547
            nca = right;
2549 2548
            while (left_set.find(nca) == left_set.end()) {
2550 2549
              nca =
2551 2550
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2552 2551
              right_path.push_back(nca);
2553 2552
              nca =
2554 2553
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2555 2554
              right_path.push_back(nca);
2556 2555
            }
2557 2556
          } else {
2558 2557
            nca = left;
2559 2558
            while (right_set.find(nca) == right_set.end()) {
2560 2559
              nca =
2561 2560
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2562 2561
              left_path.push_back(nca);
2563 2562
              nca =
2564 2563
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2565 2564
              left_path.push_back(nca);
2566 2565
            }
2567 2566
          }
2568 2567
        }
2569 2568
      }
2570 2569

	
2571 2570
      std::vector<int> subblossoms;
2572 2571
      Arc prev;
2573 2572

	
2574 2573
      prev = _graph.direct(edge, true);
2575 2574
      for (int i = 0; left_path[i] != nca; i += 2) {
2576 2575
        subblossoms.push_back(left_path[i]);
2577 2576
        (*_blossom_data)[left_path[i]].next = prev;
2578 2577
        _tree_set->erase(left_path[i]);
2579 2578

	
2580 2579
        subblossoms.push_back(left_path[i + 1]);
2581 2580
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
2582 2581
        oddToEven(left_path[i + 1], tree);
2583 2582
        _tree_set->erase(left_path[i + 1]);
2584 2583
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
2585 2584
      }
2586 2585

	
2587 2586
      int k = 0;
2588 2587
      while (right_path[k] != nca) ++k;
2589 2588

	
2590 2589
      subblossoms.push_back(nca);
2591 2590
      (*_blossom_data)[nca].next = prev;
2592 2591

	
2593 2592
      for (int i = k - 2; i >= 0; i -= 2) {
2594 2593
        subblossoms.push_back(right_path[i + 1]);
2595 2594
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
2596 2595
        oddToEven(right_path[i + 1], tree);
2597 2596
        _tree_set->erase(right_path[i + 1]);
2598 2597

	
2599 2598
        (*_blossom_data)[right_path[i + 1]].next =
2600 2599
          (*_blossom_data)[right_path[i + 1]].pred;
2601 2600

	
2602 2601
        subblossoms.push_back(right_path[i]);
2603 2602
        _tree_set->erase(right_path[i]);
2604 2603
      }
2605 2604

	
2606 2605
      int surface =
2607 2606
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
2608 2607

	
2609 2608
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2610 2609
        if (!_blossom_set->trivial(subblossoms[i])) {
2611 2610
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
2612 2611
        }
2613 2612
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
2614 2613
      }
2615 2614

	
2616 2615
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
2617 2616
      (*_blossom_data)[surface].offset = 0;
2618 2617
      (*_blossom_data)[surface].status = EVEN;
2619 2618
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
2620 2619
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
2621 2620

	
2622 2621
      _tree_set->insert(surface, tree);
2623 2622
      _tree_set->erase(nca);
2624 2623
    }
2625 2624

	
2626 2625
    void splitBlossom(int blossom) {
2627 2626
      Arc next = (*_blossom_data)[blossom].next;
2628 2627
      Arc pred = (*_blossom_data)[blossom].pred;
2629 2628

	
2630 2629
      int tree = _tree_set->find(blossom);
2631 2630

	
2632 2631
      (*_blossom_data)[blossom].status = MATCHED;
2633 2632
      oddToMatched(blossom);
2634 2633
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2635 2634
        _delta2->erase(blossom);
2636 2635
      }
2637 2636

	
2638 2637
      std::vector<int> subblossoms;
2639 2638
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
2640 2639

	
2641 2640
      Value offset = (*_blossom_data)[blossom].offset;
2642 2641
      int b = _blossom_set->find(_graph.source(pred));
2643 2642
      int d = _blossom_set->find(_graph.source(next));
2644 2643

	
2645 2644
      int ib = -1, id = -1;
2646 2645
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2647 2646
        if (subblossoms[i] == b) ib = i;
2648 2647
        if (subblossoms[i] == d) id = i;
2649 2648

	
2650 2649
        (*_blossom_data)[subblossoms[i]].offset = offset;
2651 2650
        if (!_blossom_set->trivial(subblossoms[i])) {
2652 2651
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
2653 2652
        }
2654 2653
        if (_blossom_set->classPrio(subblossoms[i]) !=
2655 2654
            std::numeric_limits<Value>::max()) {
2656 2655
          _delta2->push(subblossoms[i],
2657 2656
                        _blossom_set->classPrio(subblossoms[i]) -
2658 2657
                        (*_blossom_data)[subblossoms[i]].offset);
2659 2658
        }
2660 2659
      }
2661 2660

	
2662 2661
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
2663 2662
        for (int i = (id + 1) % subblossoms.size();
2664 2663
             i != ib; i = (i + 2) % subblossoms.size()) {
2665 2664
          int sb = subblossoms[i];
2666 2665
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2667 2666
          (*_blossom_data)[sb].next =
2668 2667
            _graph.oppositeArc((*_blossom_data)[tb].next);
2669 2668
        }
2670 2669

	
2671 2670
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
2672 2671
          int sb = subblossoms[i];
2673 2672
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2674 2673
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2675 2674

	
2676 2675
          (*_blossom_data)[sb].status = ODD;
2677 2676
          matchedToOdd(sb);
2678 2677
          _tree_set->insert(sb, tree);
2679 2678
          (*_blossom_data)[sb].pred = pred;
2680 2679
          (*_blossom_data)[sb].next =
2681 2680
                           _graph.oppositeArc((*_blossom_data)[tb].next);
2682 2681

	
2683 2682
          pred = (*_blossom_data)[ub].next;
2684 2683

	
2685 2684
          (*_blossom_data)[tb].status = EVEN;
2686 2685
          matchedToEven(tb, tree);
2687 2686
          _tree_set->insert(tb, tree);
2688 2687
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
2689 2688
        }
2690 2689

	
2691 2690
        (*_blossom_data)[subblossoms[id]].status = ODD;
2692 2691
        matchedToOdd(subblossoms[id]);
2693 2692
        _tree_set->insert(subblossoms[id], tree);
2694 2693
        (*_blossom_data)[subblossoms[id]].next = next;
2695 2694
        (*_blossom_data)[subblossoms[id]].pred = pred;
2696 2695

	
2697 2696
      } else {
2698 2697

	
2699 2698
        for (int i = (ib + 1) % subblossoms.size();
2700 2699
             i != id; i = (i + 2) % subblossoms.size()) {
2701 2700
          int sb = subblossoms[i];
2702 2701
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2703 2702
          (*_blossom_data)[sb].next =
2704 2703
            _graph.oppositeArc((*_blossom_data)[tb].next);
2705 2704
        }
2706 2705

	
2707 2706
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
2708 2707
          int sb = subblossoms[i];
2709 2708
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2710 2709
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2711 2710

	
2712 2711
          (*_blossom_data)[sb].status = ODD;
2713 2712
          matchedToOdd(sb);
2714 2713
          _tree_set->insert(sb, tree);
2715 2714
          (*_blossom_data)[sb].next = next;
2716 2715
          (*_blossom_data)[sb].pred =
2717 2716
            _graph.oppositeArc((*_blossom_data)[tb].next);
2718 2717

	
2719 2718
          (*_blossom_data)[tb].status = EVEN;
2720 2719
          matchedToEven(tb, tree);
2721 2720
          _tree_set->insert(tb, tree);
2722 2721
          (*_blossom_data)[tb].pred =
2723 2722
            (*_blossom_data)[tb].next =
2724 2723
            _graph.oppositeArc((*_blossom_data)[ub].next);
2725 2724
          next = (*_blossom_data)[ub].next;
2726 2725
        }
2727 2726

	
2728 2727
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2729 2728
        matchedToOdd(subblossoms[ib]);
2730 2729
        _tree_set->insert(subblossoms[ib], tree);
2731 2730
        (*_blossom_data)[subblossoms[ib]].next = next;
2732 2731
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2733 2732
      }
2734 2733
      _tree_set->erase(blossom);
2735 2734
    }
2736 2735

	
2737 2736
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2738 2737
      if (_blossom_set->trivial(blossom)) {
2739 2738
        int bi = (*_node_index)[base];
2740 2739
        Value pot = (*_node_data)[bi].pot;
2741 2740

	
2742 2741
        _matching->set(base, matching);
2743 2742
        _blossom_node_list.push_back(base);
2744 2743
        _node_potential->set(base, pot);
2745 2744
      } else {
2746 2745

	
2747 2746
        Value pot = (*_blossom_data)[blossom].pot;
2748 2747
        int bn = _blossom_node_list.size();
2749 2748

	
2750 2749
        std::vector<int> subblossoms;
2751 2750
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2752 2751
        int b = _blossom_set->find(base);
2753 2752
        int ib = -1;
2754 2753
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2755 2754
          if (subblossoms[i] == b) { ib = i; break; }
2756 2755
        }
2757 2756

	
2758 2757
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2759 2758
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2760 2759
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2761 2760

	
2762 2761
          Arc m = (*_blossom_data)[tb].next;
2763 2762
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2764 2763
          extractBlossom(tb, _graph.source(m), m);
2765 2764
        }
2766 2765
        extractBlossom(subblossoms[ib], base, matching);
2767 2766

	
2768 2767
        int en = _blossom_node_list.size();
2769 2768

	
2770 2769
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2771 2770
      }
2772 2771
    }
2773 2772

	
2774 2773
    void extractMatching() {
2775 2774
      std::vector<int> blossoms;
2776 2775
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2777 2776
        blossoms.push_back(c);
2778 2777
      }
2779 2778

	
2780 2779
      for (int i = 0; i < int(blossoms.size()); ++i) {
2781 2780

	
2782 2781
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2783 2782
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2784 2783
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2785 2784
             n != INVALID; ++n) {
2786 2785
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2787 2786
        }
2788 2787

	
2789 2788
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2790 2789
        Node base = _graph.source(matching);
2791 2790
        extractBlossom(blossoms[i], base, matching);
2792 2791
      }
2793 2792
    }
2794 2793

	
2795 2794
  public:
2796 2795

	
2797 2796
    /// \brief Constructor
2798 2797
    ///
2799 2798
    /// Constructor.
2800 2799
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2801 2800
      : _graph(graph), _weight(weight), _matching(0),
2802 2801
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2803 2802
        _node_num(0), _blossom_num(0),
2804 2803

	
2805 2804
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2806 2805
        _node_index(0), _node_heap_index(0), _node_data(0),
2807 2806
        _tree_set_index(0), _tree_set(0),
2808 2807

	
2809 2808
        _delta2_index(0), _delta2(0),
2810 2809
        _delta3_index(0), _delta3(0),
2811 2810
        _delta4_index(0), _delta4(0),
2812 2811

	
2813 2812
        _delta_sum() {}
2814 2813

	
2815 2814
    ~MaxWeightedPerfectMatching() {
2816 2815
      destroyStructures();
2817 2816
    }
2818 2817

	
2819 2818
    /// \name Execution control
2820
    /// The simplest way to execute the algorithm is to use the member
2819
    /// The simplest way to execute the algorithm is to use the
2821 2820
    /// \c run() member function.
2822 2821

	
2823 2822
    ///@{
2824 2823

	
2825 2824
    /// \brief Initialize the algorithm
2826 2825
    ///
2827 2826
    /// Initialize the algorithm
2828 2827
    void init() {
2829 2828
      createStructures();
2830 2829

	
2831 2830
      for (ArcIt e(_graph); e != INVALID; ++e) {
2832 2831
        _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
2833 2832
      }
2834 2833
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2835 2834
        _delta3_index->set(e, _delta3->PRE_HEAP);
2836 2835
      }
2837 2836
      for (int i = 0; i < _blossom_num; ++i) {
2838 2837
        _delta2_index->set(i, _delta2->PRE_HEAP);
2839 2838
        _delta4_index->set(i, _delta4->PRE_HEAP);
2840 2839
      }
2841 2840

	
2842 2841
      int index = 0;
2843 2842
      for (NodeIt n(_graph); n != INVALID; ++n) {
2844 2843
        Value max = - std::numeric_limits<Value>::max();
2845 2844
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2846 2845
          if (_graph.target(e) == n) continue;
2847 2846
          if ((dualScale * _weight[e]) / 2 > max) {
2848 2847
            max = (dualScale * _weight[e]) / 2;
2849 2848
          }
2850 2849
        }
2851 2850
        _node_index->set(n, index);
2852 2851
        (*_node_data)[index].pot = max;
2853 2852
        int blossom =
2854 2853
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
2855 2854

	
2856 2855
        _tree_set->insert(blossom);
2857 2856

	
2858 2857
        (*_blossom_data)[blossom].status = EVEN;
2859 2858
        (*_blossom_data)[blossom].pred = INVALID;
2860 2859
        (*_blossom_data)[blossom].next = INVALID;
2861 2860
        (*_blossom_data)[blossom].pot = 0;
2862 2861
        (*_blossom_data)[blossom].offset = 0;
2863 2862
        ++index;
2864 2863
      }
2865 2864
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2866 2865
        int si = (*_node_index)[_graph.u(e)];
2867 2866
        int ti = (*_node_index)[_graph.v(e)];
2868 2867
        if (_graph.u(e) != _graph.v(e)) {
2869 2868
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
2870 2869
                            dualScale * _weight[e]) / 2);
2871 2870
        }
2872 2871
      }
2873 2872
    }
2874 2873

	
2875 2874
    /// \brief Starts the algorithm
2876 2875
    ///
2877 2876
    /// Starts the algorithm
2878 2877
    bool start() {
2879 2878
      enum OpType {
2880 2879
        D2, D3, D4
2881 2880
      };
2882 2881

	
2883 2882
      int unmatched = _node_num;
2884 2883
      while (unmatched > 0) {
2885 2884
        Value d2 = !_delta2->empty() ?
2886 2885
          _delta2->prio() : std::numeric_limits<Value>::max();
2887 2886

	
2888 2887
        Value d3 = !_delta3->empty() ?
2889 2888
          _delta3->prio() : std::numeric_limits<Value>::max();
2890 2889

	
2891 2890
        Value d4 = !_delta4->empty() ?
2892 2891
          _delta4->prio() : std::numeric_limits<Value>::max();
2893 2892

	
2894 2893
        _delta_sum = d2; OpType ot = D2;
2895 2894
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2896 2895
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2897 2896

	
2898 2897
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2899 2898
          return false;
2900 2899
        }
2901 2900

	
2902 2901
        switch (ot) {
2903 2902
        case D2:
2904 2903
          {
2905 2904
            int blossom = _delta2->top();
2906 2905
            Node n = _blossom_set->classTop(blossom);
2907 2906
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
2908 2907
            extendOnArc(e);
2909 2908
          }
2910 2909
          break;
2911 2910
        case D3:
2912 2911
          {
2913 2912
            Edge e = _delta3->top();
2914 2913

	
2915 2914
            int left_blossom = _blossom_set->find(_graph.u(e));
2916 2915
            int right_blossom = _blossom_set->find(_graph.v(e));
2917 2916

	
2918 2917
            if (left_blossom == right_blossom) {
2919 2918
              _delta3->pop();
2920 2919
            } else {
2921 2920
              int left_tree = _tree_set->find(left_blossom);
2922 2921
              int right_tree = _tree_set->find(right_blossom);
2923 2922

	
2924 2923
              if (left_tree == right_tree) {
2925 2924
                shrinkOnEdge(e, left_tree);
2926 2925
              } else {
2927 2926
                augmentOnEdge(e);
2928 2927
                unmatched -= 2;
2929 2928
              }
2930 2929
            }
2931 2930
          } break;
2932 2931
        case D4:
2933 2932
          splitBlossom(_delta4->top());
2934 2933
          break;
2935 2934
        }
2936 2935
      }
2937 2936
      extractMatching();
2938 2937
      return true;
2939 2938
    }
2940 2939

	
2941 2940
    /// \brief Runs %MaxWeightedPerfectMatching algorithm.
2942 2941
    ///
2943 2942
    /// This method runs the %MaxWeightedPerfectMatching algorithm.
2944 2943
    ///
2945 2944
    /// \note mwm.run() is just a shortcut of the following code.
2946 2945
    /// \code
2947 2946
    ///   mwm.init();
2948 2947
    ///   mwm.start();
2949 2948
    /// \endcode
2950 2949
    bool run() {
2951 2950
      init();
2952 2951
      return start();
2953 2952
    }
2954 2953

	
2955 2954
    /// @}
2956 2955

	
2957 2956
    /// \name Primal solution
2958
    /// Functions for get the primal solution, ie. the matching.
2957
    /// Functions to get the primal solution, ie. the matching.
2959 2958

	
2960 2959
    /// @{
2961 2960

	
2962 2961
    /// \brief Returns the matching value.
2963 2962
    ///
2964 2963
    /// Returns the matching value.
2965 2964
    Value matchingValue() const {
2966 2965
      Value sum = 0;
2967 2966
      for (NodeIt n(_graph); n != INVALID; ++n) {
2968 2967
        if ((*_matching)[n] != INVALID) {
2969 2968
          sum += _weight[(*_matching)[n]];
2970 2969
        }
2971 2970
      }
2972 2971
      return sum /= 2;
2973 2972
    }
2974 2973

	
2975 2974
    /// \brief Returns true when the edge is in the matching.
2976 2975
    ///
2977 2976
    /// Returns true when the edge is in the matching.
2978 2977
    bool matching(const Edge& edge) const {
2979 2978
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
2980 2979
    }
2981 2980

	
2982 2981
    /// \brief Returns the incident matching edge.
2983 2982
    ///
2984 2983
    /// Returns the incident matching arc from given edge.
2985 2984
    Arc matching(const Node& node) const {
2986 2985
      return (*_matching)[node];
2987 2986
    }
2988 2987

	
2989 2988
    /// \brief Returns the mate of the node.
2990 2989
    ///
2991 2990
    /// Returns the adjancent node in a mathcing arc.
2992 2991
    Node mate(const Node& node) const {
2993 2992
      return _graph.target((*_matching)[node]);
2994 2993
    }
2995 2994

	
2996 2995
    /// @}
2997 2996

	
2998 2997
    /// \name Dual solution
2999
    /// Functions for get the dual solution.
2998
    /// Functions to get the dual solution.
3000 2999

	
3001 3000
    /// @{
3002 3001

	
3003 3002
    /// \brief Returns the value of the dual solution.
3004 3003
    ///
3005 3004
    /// Returns the value of the dual solution. It should be equal to
3006 3005
    /// the primal value scaled by \ref dualScale "dual scale".
3007 3006
    Value dualValue() const {
3008 3007
      Value sum = 0;
3009 3008
      for (NodeIt n(_graph); n != INVALID; ++n) {
3010 3009
        sum += nodeValue(n);
3011 3010
      }
3012 3011
      for (int i = 0; i < blossomNum(); ++i) {
3013 3012
        sum += blossomValue(i) * (blossomSize(i) / 2);
3014 3013
      }
3015 3014
      return sum;
3016 3015
    }
3017 3016

	
3018 3017
    /// \brief Returns the value of the node.
3019 3018
    ///
3020 3019
    /// Returns the the value of the node.
3021 3020
    Value nodeValue(const Node& n) const {
3022 3021
      return (*_node_potential)[n];
3023 3022
    }
3024 3023

	
3025 3024
    /// \brief Returns the number of the blossoms in the basis.
3026 3025
    ///
3027 3026
    /// Returns the number of the blossoms in the basis.
3028 3027
    /// \see BlossomIt
3029 3028
    int blossomNum() const {
3030 3029
      return _blossom_potential.size();
3031 3030
    }
3032 3031

	
3033 3032

	
3034 3033
    /// \brief Returns the number of the nodes in the blossom.
3035 3034
    ///
3036 3035
    /// Returns the number of the nodes in the blossom.
3037 3036
    int blossomSize(int k) const {
3038 3037
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3039 3038
    }
3040 3039

	
3041 3040
    /// \brief Returns the value of the blossom.
3042 3041
    ///
3043 3042
    /// Returns the the value of the blossom.
3044 3043
    /// \see BlossomIt
3045 3044
    Value blossomValue(int k) const {
3046 3045
      return _blossom_potential[k].value;
3047 3046
    }
3048 3047

	
3049
    /// \brief Lemon iterator for get the items of the blossom.
3048
    /// \brief Iterator for obtaining the nodes of the blossom.
3050 3049
    ///
3051
    /// Lemon iterator for get the nodes of the blossom. This class
3052
    /// provides a common style lemon iterator which gives back a
3050
    /// Iterator for obtaining the nodes of the blossom. This class
3051
    /// provides a common lemon style iterator for listing a
3053 3052
    /// subset of the nodes.
3054 3053
    class BlossomIt {
3055 3054
    public:
3056 3055

	
3057 3056
      /// \brief Constructor.
3058 3057
      ///
3059
      /// Constructor for get the nodes of the variable.
3058
      /// Constructor to get the nodes of the variable.
3060 3059
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3061 3060
        : _algorithm(&algorithm)
3062 3061
      {
3063 3062
        _index = _algorithm->_blossom_potential[variable].begin;
3064 3063
        _last = _algorithm->_blossom_potential[variable].end;
3065 3064
      }
3066 3065

	
3067 3066
      /// \brief Conversion to node.
3068 3067
      ///
3069 3068
      /// Conversion to node.
3070 3069
      operator Node() const {
3071 3070
        return _algorithm->_blossom_node_list[_index];
3072 3071
      }
3073 3072

	
3074 3073
      /// \brief Increment operator.
3075 3074
      ///
3076 3075
      /// Increment operator.
3077 3076
      BlossomIt& operator++() {
3078 3077
        ++_index;
3079 3078
        return *this;
3080 3079
      }
3081 3080

	
3082 3081
      /// \brief Validity checking
3083 3082
      ///
3084 3083
      /// Checks whether the iterator is invalid.
3085 3084
      bool operator==(Invalid) const { return _index == _last; }
3086 3085

	
3087 3086
      /// \brief Validity checking
3088 3087
      ///
3089 3088
      /// Checks whether the iterator is valid.
3090 3089
      bool operator!=(Invalid) const { return _index != _last; }
3091 3090

	
3092 3091
    private:
3093 3092
      const MaxWeightedPerfectMatching* _algorithm;
3094 3093
      int _last;
3095 3094
      int _index;
3096 3095
    };
3097 3096

	
3098 3097
    /// @}
3099 3098

	
3100 3099
  };
3101 3100

	
3102 3101

	
3103 3102
} //END OF NAMESPACE LEMON
3104 3103

	
3105 3104
#endif //LEMON_MAX_MATCHING_H
0 comments (0 inline)