gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge #314
0 6 2
merge default
4 files changed with 3246 insertions and 378 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#ifndef LEMON_FRACTIONAL_MATCHING_H
20
#define LEMON_FRACTIONAL_MATCHING_H
21

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

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

	
34
///\ingroup matching
35
///\file
36
///\brief Fractional matching algorithms in general graphs.
37

	
38
namespace lemon {
39

	
40
  /// \brief Default traits class of MaxFractionalMatching class.
41
  ///
42
  /// Default traits class of MaxFractionalMatching class.
43
  /// \tparam GR Graph type.
44
  template <typename GR>
45
  struct MaxFractionalMatchingDefaultTraits {
46

	
47
    /// \brief The type of the graph the algorithm runs on.
48
    typedef GR Graph;
49

	
50
    /// \brief The type of the map that stores the matching.
51
    ///
52
    /// The type of the map that stores the matching arcs.
53
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
54
    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
55

	
56
    /// \brief Instantiates a MatchingMap.
57
    ///
58
    /// This function instantiates a \ref MatchingMap.
59
    /// \param graph The graph for which we would like to define
60
    /// the matching map.
61
    static MatchingMap* createMatchingMap(const Graph& graph) {
62
      return new MatchingMap(graph);
63
    }
64

	
65
    /// \brief The elevator type used by MaxFractionalMatching algorithm.
66
    ///
67
    /// The elevator type used by MaxFractionalMatching algorithm.
68
    ///
69
    /// \sa Elevator
70
    /// \sa LinkedElevator
71
    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
72

	
73
    /// \brief Instantiates an Elevator.
74
    ///
75
    /// This function instantiates an \ref Elevator.
76
    /// \param graph The graph for which we would like to define
77
    /// the elevator.
78
    /// \param max_level The maximum level of the elevator.
79
    static Elevator* createElevator(const Graph& graph, int max_level) {
80
      return new Elevator(graph, max_level);
81
    }
82
  };
83

	
84
  /// \ingroup matching
85
  ///
86
  /// \brief Max cardinality fractional matching
87
  ///
88
  /// This class provides an implementation of fractional matching
89
  /// algorithm based on push-relabel principle.
90
  ///
91
  /// The maximum cardinality fractional matching is a relaxation of the
92
  /// maximum cardinality matching problem where the odd set constraints
93
  /// are omitted.
94
  /// It can be formulated with the following linear program.
95
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
96
  /// \f[x_e \ge 0\quad \forall e\in E\f]
97
  /// \f[\max \sum_{e\in E}x_e\f]
98
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
99
  /// \f$X\f$. The result can be represented as the union of a
100
  /// matching with one value edges and a set of odd length cycles
101
  /// with half value edges.
102
  ///
103
  /// The algorithm calculates an optimal fractional matching and a
104
  /// barrier. The number of adjacents of any node set minus the size
105
  /// of node set is a lower bound on the uncovered nodes in the
106
  /// graph. For maximum matching a barrier is computed which
107
  /// maximizes this difference.
108
  ///
109
  /// The algorithm can be executed with the run() function.  After it
110
  /// the matching (the primal solution) and the barrier (the dual
111
  /// solution) can be obtained using the query functions.
112
  ///
113
  /// The primal solution is multiplied by
114
  /// \ref MaxFractionalMatching::primalScale "2".
115
  ///
116
  /// \tparam GR The undirected graph type the algorithm runs on.
117
#ifdef DOXYGEN
118
  template <typename GR, typename TR>
119
#else
120
  template <typename GR,
121
            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
122
#endif
123
  class MaxFractionalMatching {
124
  public:
125

	
126
    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
127
    /// class" of the algorithm.
128
    typedef TR Traits;
129
    /// The type of the graph the algorithm runs on.
130
    typedef typename TR::Graph Graph;
131
    /// The type of the matching map.
132
    typedef typename TR::MatchingMap MatchingMap;
133
    /// The type of the elevator.
134
    typedef typename TR::Elevator Elevator;
135

	
136
    /// \brief Scaling factor for primal solution
137
    ///
138
    /// Scaling factor for primal solution.
139
    static const int primalScale = 2;
140

	
141
  private:
142

	
143
    const Graph &_graph;
144
    int _node_num;
145
    bool _allow_loops;
146
    int _empty_level;
147

	
148
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
149

	
150
    bool _local_matching;
151
    MatchingMap *_matching;
152

	
153
    bool _local_level;
154
    Elevator *_level;
155

	
156
    typedef typename Graph::template NodeMap<int> InDegMap;
157
    InDegMap *_indeg;
158

	
159
    void createStructures() {
160
      _node_num = countNodes(_graph);
161

	
162
      if (!_matching) {
163
        _local_matching = true;
164
        _matching = Traits::createMatchingMap(_graph);
165
      }
166
      if (!_level) {
167
        _local_level = true;
168
        _level = Traits::createElevator(_graph, _node_num);
169
      }
170
      if (!_indeg) {
171
        _indeg = new InDegMap(_graph);
172
      }
173
    }
174

	
175
    void destroyStructures() {
176
      if (_local_matching) {
177
        delete _matching;
178
      }
179
      if (_local_level) {
180
        delete _level;
181
      }
182
      if (_indeg) {
183
        delete _indeg;
184
      }
185
    }
186

	
187
    void postprocessing() {
188
      for (NodeIt n(_graph); n != INVALID; ++n) {
189
        if ((*_indeg)[n] != 0) continue;
190
        _indeg->set(n, -1);
191
        Node u = n;
192
        while ((*_matching)[u] != INVALID) {
193
          Node v = _graph.target((*_matching)[u]);
194
          _indeg->set(v, -1);
195
          Arc a = _graph.oppositeArc((*_matching)[u]);
196
          u = _graph.target((*_matching)[v]);
197
          _indeg->set(u, -1);
198
          _matching->set(v, a);
199
        }
200
      }
201

	
202
      for (NodeIt n(_graph); n != INVALID; ++n) {
203
        if ((*_indeg)[n] != 1) continue;
204
        _indeg->set(n, -1);
205

	
206
        int num = 1;
207
        Node u = _graph.target((*_matching)[n]);
208
        while (u != n) {
209
          _indeg->set(u, -1);
210
          u = _graph.target((*_matching)[u]);
211
          ++num;
212
        }
213
        if (num % 2 == 0 && num > 2) {
214
          Arc prev = _graph.oppositeArc((*_matching)[n]);
215
          Node v = _graph.target((*_matching)[n]);
216
          u = _graph.target((*_matching)[v]);
217
          _matching->set(v, prev);
218
          while (u != n) {
219
            prev = _graph.oppositeArc((*_matching)[u]);
220
            v = _graph.target((*_matching)[u]);
221
            u = _graph.target((*_matching)[v]);
222
            _matching->set(v, prev);
223
          }
224
        }
225
      }
226
    }
227

	
228
  public:
229

	
230
    typedef MaxFractionalMatching Create;
231

	
232
    ///\name Named Template Parameters
233

	
234
    ///@{
235

	
236
    template <typename T>
237
    struct SetMatchingMapTraits : public Traits {
238
      typedef T MatchingMap;
239
      static MatchingMap *createMatchingMap(const Graph&) {
240
        LEMON_ASSERT(false, "MatchingMap is not initialized");
241
        return 0; // ignore warnings
242
      }
243
    };
244

	
245
    /// \brief \ref named-templ-param "Named parameter" for setting
246
    /// MatchingMap type
247
    ///
248
    /// \ref named-templ-param "Named parameter" for setting MatchingMap
249
    /// type.
250
    template <typename T>
251
    struct SetMatchingMap
252
      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
253
      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
254
    };
255

	
256
    template <typename T>
257
    struct SetElevatorTraits : public Traits {
258
      typedef T Elevator;
259
      static Elevator *createElevator(const Graph&, int) {
260
        LEMON_ASSERT(false, "Elevator is not initialized");
261
        return 0; // ignore warnings
262
      }
263
    };
264

	
265
    /// \brief \ref named-templ-param "Named parameter" for setting
266
    /// Elevator type
267
    ///
268
    /// \ref named-templ-param "Named parameter" for setting Elevator
269
    /// type. If this named parameter is used, then an external
270
    /// elevator object must be passed to the algorithm using the
271
    /// \ref elevator(Elevator&) "elevator()" function before calling
272
    /// \ref run() or \ref init().
273
    /// \sa SetStandardElevator
274
    template <typename T>
275
    struct SetElevator
276
      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
277
      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
278
    };
279

	
280
    template <typename T>
281
    struct SetStandardElevatorTraits : public Traits {
282
      typedef T Elevator;
283
      static Elevator *createElevator(const Graph& graph, int max_level) {
284
        return new Elevator(graph, max_level);
285
      }
286
    };
287

	
288
    /// \brief \ref named-templ-param "Named parameter" for setting
289
    /// Elevator type with automatic allocation
290
    ///
291
    /// \ref named-templ-param "Named parameter" for setting Elevator
292
    /// type with automatic allocation.
293
    /// The Elevator should have standard constructor interface to be
294
    /// able to automatically created by the algorithm (i.e. the
295
    /// graph and the maximum level should be passed to it).
296
    /// However an external elevator object could also be passed to the
297
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
298
    /// before calling \ref run() or \ref init().
299
    /// \sa SetElevator
300
    template <typename T>
301
    struct SetStandardElevator
302
      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
303
      typedef MaxFractionalMatching<Graph,
304
                                    SetStandardElevatorTraits<T> > Create;
305
    };
306

	
307
    /// @}
308

	
309
  protected:
310

	
311
    MaxFractionalMatching() {}
312

	
313
  public:
314

	
315
    /// \brief Constructor
316
    ///
317
    /// Constructor.
318
    ///
319
    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
320
      : _graph(graph), _allow_loops(allow_loops),
321
        _local_matching(false), _matching(0),
322
        _local_level(false), _level(0),  _indeg(0)
323
    {}
324

	
325
    ~MaxFractionalMatching() {
326
      destroyStructures();
327
    }
328

	
329
    /// \brief Sets the matching map.
330
    ///
331
    /// Sets the matching map.
332
    /// If you don't use this function before calling \ref run() or
333
    /// \ref init(), an instance will be allocated automatically.
334
    /// The destructor deallocates this automatically allocated map,
335
    /// of course.
336
    /// \return <tt>(*this)</tt>
337
    MaxFractionalMatching& matchingMap(MatchingMap& map) {
338
      if (_local_matching) {
339
        delete _matching;
340
        _local_matching = false;
341
      }
342
      _matching = &map;
343
      return *this;
344
    }
345

	
346
    /// \brief Sets the elevator used by algorithm.
347
    ///
348
    /// Sets the elevator used by algorithm.
349
    /// If you don't use this function before calling \ref run() or
350
    /// \ref init(), an instance will be allocated automatically.
351
    /// The destructor deallocates this automatically allocated elevator,
352
    /// of course.
353
    /// \return <tt>(*this)</tt>
354
    MaxFractionalMatching& elevator(Elevator& elevator) {
355
      if (_local_level) {
356
        delete _level;
357
        _local_level = false;
358
      }
359
      _level = &elevator;
360
      return *this;
361
    }
362

	
363
    /// \brief Returns a const reference to the elevator.
364
    ///
365
    /// Returns a const reference to the elevator.
366
    ///
367
    /// \pre Either \ref run() or \ref init() must be called before
368
    /// using this function.
369
    const Elevator& elevator() const {
370
      return *_level;
371
    }
372

	
373
    /// \name Execution control
374
    /// The simplest way to execute the algorithm is to use one of the
375
    /// member functions called \c run(). \n
376
    /// If you need more control on the execution, first
377
    /// you must call \ref init() and then one variant of the start()
378
    /// member.
379

	
380
    /// @{
381

	
382
    /// \brief Initializes the internal data structures.
383
    ///
384
    /// Initializes the internal data structures and sets the initial
385
    /// matching.
386
    void init() {
387
      createStructures();
388

	
389
      _level->initStart();
390
      for (NodeIt n(_graph); n != INVALID; ++n) {
391
        _indeg->set(n, 0);
392
        _matching->set(n, INVALID);
393
        _level->initAddItem(n);
394
      }
395
      _level->initFinish();
396

	
397
      _empty_level = _node_num;
398
      for (NodeIt n(_graph); n != INVALID; ++n) {
399
        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
400
          if (_graph.target(a) == n && !_allow_loops) continue;
401
          _matching->set(n, a);
402
          Node v = _graph.target((*_matching)[n]);
403
          _indeg->set(v, (*_indeg)[v] + 1);
404
          break;
405
        }
406
      }
407

	
408
      for (NodeIt n(_graph); n != INVALID; ++n) {
409
        if ((*_indeg)[n] == 0) {
410
          _level->activate(n);
411
        }
412
      }
413
    }
414

	
415
    /// \brief Starts the algorithm and computes a fractional matching
416
    ///
417
    /// The algorithm computes a maximum fractional matching.
418
    ///
419
    /// \param postprocess The algorithm computes first a matching
420
    /// which is a union of a matching with one value edges, cycles
421
    /// with half value edges and even length paths with half value
422
    /// edges. If the parameter is true, then after the push-relabel
423
    /// algorithm it postprocesses the matching to contain only
424
    /// matching edges and half value odd cycles.
425
    void start(bool postprocess = true) {
426
      Node n;
427
      while ((n = _level->highestActive()) != INVALID) {
428
        int level = _level->highestActiveLevel();
429
        int new_level = _level->maxLevel();
430
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
431
          Node u = _graph.source(a);
432
          if (n == u && !_allow_loops) continue;
433
          Node v = _graph.target((*_matching)[u]);
434
          if ((*_level)[v] < level) {
435
            _indeg->set(v, (*_indeg)[v] - 1);
436
            if ((*_indeg)[v] == 0) {
437
              _level->activate(v);
438
            }
439
            _matching->set(u, a);
440
            _indeg->set(n, (*_indeg)[n] + 1);
441
            _level->deactivate(n);
442
            goto no_more_push;
443
          } else if (new_level > (*_level)[v]) {
444
            new_level = (*_level)[v];
445
          }
446
        }
447

	
448
        if (new_level + 1 < _level->maxLevel()) {
449
          _level->liftHighestActive(new_level + 1);
450
        } else {
451
          _level->liftHighestActiveToTop();
452
        }
453
        if (_level->emptyLevel(level)) {
454
          _level->liftToTop(level);
455
        }
456
      no_more_push:
457
        ;
458
      }
459
      for (NodeIt n(_graph); n != INVALID; ++n) {
460
        if ((*_matching)[n] == INVALID) continue;
461
        Node u = _graph.target((*_matching)[n]);
462
        if ((*_indeg)[u] > 1) {
463
          _indeg->set(u, (*_indeg)[u] - 1);
464
          _matching->set(n, INVALID);
465
        }
466
      }
467
      if (postprocess) {
468
        postprocessing();
469
      }
470
    }
471

	
472
    /// \brief Starts the algorithm and computes a perfect fractional
473
    /// matching
474
    ///
475
    /// The algorithm computes a perfect fractional matching. If it
476
    /// does not exists, then the algorithm returns false and the
477
    /// matching is undefined and the barrier.
478
    ///
479
    /// \param postprocess The algorithm computes first a matching
480
    /// which is a union of a matching with one value edges, cycles
481
    /// with half value edges and even length paths with half value
482
    /// edges. If the parameter is true, then after the push-relabel
483
    /// algorithm it postprocesses the matching to contain only
484
    /// matching edges and half value odd cycles.
485
    bool startPerfect(bool postprocess = true) {
486
      Node n;
487
      while ((n = _level->highestActive()) != INVALID) {
488
        int level = _level->highestActiveLevel();
489
        int new_level = _level->maxLevel();
490
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
491
          Node u = _graph.source(a);
492
          if (n == u && !_allow_loops) continue;
493
          Node v = _graph.target((*_matching)[u]);
494
          if ((*_level)[v] < level) {
495
            _indeg->set(v, (*_indeg)[v] - 1);
496
            if ((*_indeg)[v] == 0) {
497
              _level->activate(v);
498
            }
499
            _matching->set(u, a);
500
            _indeg->set(n, (*_indeg)[n] + 1);
501
            _level->deactivate(n);
502
            goto no_more_push;
503
          } else if (new_level > (*_level)[v]) {
504
            new_level = (*_level)[v];
505
          }
506
        }
507

	
508
        if (new_level + 1 < _level->maxLevel()) {
509
          _level->liftHighestActive(new_level + 1);
510
        } else {
511
          _level->liftHighestActiveToTop();
512
          _empty_level = _level->maxLevel() - 1;
513
          return false;
514
        }
515
        if (_level->emptyLevel(level)) {
516
          _level->liftToTop(level);
517
          _empty_level = level;
518
          return false;
519
        }
520
      no_more_push:
521
        ;
522
      }
523
      if (postprocess) {
524
        postprocessing();
525
      }
526
      return true;
527
    }
528

	
529
    /// \brief Runs the algorithm
530
    ///
531
    /// Just a shortcut for the next code:
532
    ///\code
533
    /// init();
534
    /// start();
535
    ///\endcode
536
    void run(bool postprocess = true) {
537
      init();
538
      start(postprocess);
539
    }
540

	
541
    /// \brief Runs the algorithm to find a perfect fractional matching
542
    ///
543
    /// Just a shortcut for the next code:
544
    ///\code
545
    /// init();
546
    /// startPerfect();
547
    ///\endcode
548
    bool runPerfect(bool postprocess = true) {
549
      init();
550
      return startPerfect(postprocess);
551
    }
552

	
553
    ///@}
554

	
555
    /// \name Query Functions
556
    /// The result of the %Matching algorithm can be obtained using these
557
    /// functions.\n
558
    /// Before the use of these functions,
559
    /// either run() or start() must be called.
560
    ///@{
561

	
562

	
563
    /// \brief Return the number of covered nodes in the matching.
564
    ///
565
    /// This function returns the number of covered nodes in the matching.
566
    ///
567
    /// \pre Either run() or start() must be called before using this function.
568
    int matchingSize() const {
569
      int num = 0;
570
      for (NodeIt n(_graph); n != INVALID; ++n) {
571
        if ((*_matching)[n] != INVALID) {
572
          ++num;
573
        }
574
      }
575
      return num;
576
    }
577

	
578
    /// \brief Returns a const reference to the matching map.
579
    ///
580
    /// Returns a const reference to the node map storing the found
581
    /// fractional matching. This method can be called after
582
    /// running the algorithm.
583
    ///
584
    /// \pre Either \ref run() or \ref init() must be called before
585
    /// using this function.
586
    const MatchingMap& matchingMap() const {
587
      return *_matching;
588
    }
589

	
590
    /// \brief Return \c true if the given edge is in the matching.
591
    ///
592
    /// This function returns \c true if the given edge is in the
593
    /// found matching. The result is scaled by \ref primalScale
594
    /// "primal scale".
595
    ///
596
    /// \pre Either run() or start() must be called before using this function.
597
    int matching(const Edge& edge) const {
598
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
599
        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
600
    }
601

	
602
    /// \brief Return the fractional matching arc (or edge) incident
603
    /// to the given node.
604
    ///
605
    /// This function returns one of the fractional matching arc (or
606
    /// edge) incident to the given node in the found matching or \c
607
    /// INVALID if the node is not covered by the matching or if the
608
    /// node is on an odd length cycle then it is the successor edge
609
    /// on the cycle.
610
    ///
611
    /// \pre Either run() or start() must be called before using this function.
612
    Arc matching(const Node& node) const {
613
      return (*_matching)[node];
614
    }
615

	
616
    /// \brief Returns true if the node is in the barrier
617
    ///
618
    /// The barrier is a subset of the nodes. If the nodes in the
619
    /// barrier have less adjacent nodes than the size of the barrier,
620
    /// then at least as much nodes cannot be covered as the
621
    /// difference of the two subsets.
622
    bool barrier(const Node& node) const {
623
      return (*_level)[node] >= _empty_level;
624
    }
625

	
626
    /// @}
627

	
628
  };
629

	
630
  /// \ingroup matching
631
  ///
632
  /// \brief Weighted fractional matching in general graphs
633
  ///
634
  /// This class provides an efficient implementation of fractional
635
  /// matching algorithm. The implementation uses priority queues and
636
  /// provides \f$O(nm\log n)\f$ time complexity.
637
  ///
638
  /// The maximum weighted fractional matching is a relaxation of the
639
  /// maximum weighted matching problem where the odd set constraints
640
  /// are omitted.
641
  /// It can be formulated with the following linear program.
642
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
643
  /// \f[x_e \ge 0\quad \forall e\in E\f]
644
  /// \f[\max \sum_{e\in E}x_ew_e\f]
645
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
646
  /// \f$X\f$. The result must be the union of a matching with one
647
  /// value edges and a set of odd length cycles with half value edges.
648
  ///
649
  /// The algorithm calculates an optimal fractional matching and a
650
  /// proof of the optimality. The solution of the dual problem can be
651
  /// used to check the result of the algorithm. The dual linear
652
  /// problem is the following.
653
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
654
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
655
  /// \f[\min \sum_{u \in V}y_u \f]
656
  ///
657
  /// The algorithm can be executed with the run() function.
658
  /// After it the matching (the primal solution) and the dual solution
659
  /// can be obtained using the query functions.
660
  ///
661
  /// The primal solution is multiplied by
662
  /// \ref MaxWeightedFractionalMatching::primalScale "2".
663
  /// If the value type is integer, then the dual
664
  /// solution is scaled by
665
  /// \ref MaxWeightedFractionalMatching::dualScale "4".
666
  ///
667
  /// \tparam GR The undirected graph type the algorithm runs on.
668
  /// \tparam WM The type edge weight map. The default type is
669
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
670
#ifdef DOXYGEN
671
  template <typename GR, typename WM>
672
#else
673
  template <typename GR,
674
            typename WM = typename GR::template EdgeMap<int> >
675
#endif
676
  class MaxWeightedFractionalMatching {
677
  public:
678

	
679
    /// The graph type of the algorithm
680
    typedef GR Graph;
681
    /// The type of the edge weight map
682
    typedef WM WeightMap;
683
    /// The value type of the edge weights
684
    typedef typename WeightMap::Value Value;
685

	
686
    /// The type of the matching map
687
    typedef typename Graph::template NodeMap<typename Graph::Arc>
688
    MatchingMap;
689

	
690
    /// \brief Scaling factor for primal solution
691
    ///
692
    /// Scaling factor for primal solution.
693
    static const int primalScale = 2;
694

	
695
    /// \brief Scaling factor for dual solution
696
    ///
697
    /// Scaling factor for dual solution. It is equal to 4 or 1
698
    /// according to the value type.
699
    static const int dualScale =
700
      std::numeric_limits<Value>::is_integer ? 4 : 1;
701

	
702
  private:
703

	
704
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
705

	
706
    typedef typename Graph::template NodeMap<Value> NodePotential;
707

	
708
    const Graph& _graph;
709
    const WeightMap& _weight;
710

	
711
    MatchingMap* _matching;
712
    NodePotential* _node_potential;
713

	
714
    int _node_num;
715
    bool _allow_loops;
716

	
717
    enum Status {
718
      EVEN = -1, MATCHED = 0, ODD = 1
719
    };
720

	
721
    typedef typename Graph::template NodeMap<Status> StatusMap;
722
    StatusMap* _status;
723

	
724
    typedef typename Graph::template NodeMap<Arc> PredMap;
725
    PredMap* _pred;
726

	
727
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
728

	
729
    IntNodeMap *_tree_set_index;
730
    TreeSet *_tree_set;
731

	
732
    IntNodeMap *_delta1_index;
733
    BinHeap<Value, IntNodeMap> *_delta1;
734

	
735
    IntNodeMap *_delta2_index;
736
    BinHeap<Value, IntNodeMap> *_delta2;
737

	
738
    IntEdgeMap *_delta3_index;
739
    BinHeap<Value, IntEdgeMap> *_delta3;
740

	
741
    Value _delta_sum;
742

	
743
    void createStructures() {
744
      _node_num = countNodes(_graph);
745

	
746
      if (!_matching) {
747
        _matching = new MatchingMap(_graph);
748
      }
749
      if (!_node_potential) {
750
        _node_potential = new NodePotential(_graph);
751
      }
752
      if (!_status) {
753
        _status = new StatusMap(_graph);
754
      }
755
      if (!_pred) {
756
        _pred = new PredMap(_graph);
757
      }
758
      if (!_tree_set) {
759
        _tree_set_index = new IntNodeMap(_graph);
760
        _tree_set = new TreeSet(*_tree_set_index);
761
      }
762
      if (!_delta1) {
763
        _delta1_index = new IntNodeMap(_graph);
764
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
765
      }
766
      if (!_delta2) {
767
        _delta2_index = new IntNodeMap(_graph);
768
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
769
      }
770
      if (!_delta3) {
771
        _delta3_index = new IntEdgeMap(_graph);
772
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
773
      }
774
    }
775

	
776
    void destroyStructures() {
777
      if (_matching) {
778
        delete _matching;
779
      }
780
      if (_node_potential) {
781
        delete _node_potential;
782
      }
783
      if (_status) {
784
        delete _status;
785
      }
786
      if (_pred) {
787
        delete _pred;
788
      }
789
      if (_tree_set) {
790
        delete _tree_set_index;
791
        delete _tree_set;
792
      }
793
      if (_delta1) {
794
        delete _delta1_index;
795
        delete _delta1;
796
      }
797
      if (_delta2) {
798
        delete _delta2_index;
799
        delete _delta2;
800
      }
801
      if (_delta3) {
802
        delete _delta3_index;
803
        delete _delta3;
804
      }
805
    }
806

	
807
    void matchedToEven(Node node, int tree) {
808
      _tree_set->insert(node, tree);
809
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
810
      _delta1->push(node, (*_node_potential)[node]);
811

	
812
      if (_delta2->state(node) == _delta2->IN_HEAP) {
813
        _delta2->erase(node);
814
      }
815

	
816
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
817
        Node v = _graph.source(a);
818
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
819
          dualScale * _weight[a];
820
        if (node == v) {
821
          if (_allow_loops && _graph.direction(a)) {
822
            _delta3->push(a, rw / 2);
823
          }
824
        } else if ((*_status)[v] == EVEN) {
825
          _delta3->push(a, rw / 2);
826
        } else if ((*_status)[v] == MATCHED) {
827
          if (_delta2->state(v) != _delta2->IN_HEAP) {
828
            _pred->set(v, a);
829
            _delta2->push(v, rw);
830
          } else if ((*_delta2)[v] > rw) {
831
            _pred->set(v, a);
832
            _delta2->decrease(v, rw);
833
          }
834
        }
835
      }
836
    }
837

	
838
    void matchedToOdd(Node node, int tree) {
839
      _tree_set->insert(node, tree);
840
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
841

	
842
      if (_delta2->state(node) == _delta2->IN_HEAP) {
843
        _delta2->erase(node);
844
      }
845
    }
846

	
847
    void evenToMatched(Node node, int tree) {
848
      _delta1->erase(node);
849
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
850
      Arc min = INVALID;
851
      Value minrw = std::numeric_limits<Value>::max();
852
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
853
        Node v = _graph.source(a);
854
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
855
          dualScale * _weight[a];
856

	
857
        if (node == v) {
858
          if (_allow_loops && _graph.direction(a)) {
859
            _delta3->erase(a);
860
          }
861
        } else if ((*_status)[v] == EVEN) {
862
          _delta3->erase(a);
863
          if (minrw > rw) {
864
            min = _graph.oppositeArc(a);
865
            minrw = rw;
866
          }
867
        } else if ((*_status)[v]  == MATCHED) {
868
          if ((*_pred)[v] == a) {
869
            Arc mina = INVALID;
870
            Value minrwa = std::numeric_limits<Value>::max();
871
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
872
              Node va = _graph.target(aa);
873
              if ((*_status)[va] != EVEN ||
874
                  _tree_set->find(va) == tree) continue;
875
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
876
                dualScale * _weight[aa];
877
              if (minrwa > rwa) {
878
                minrwa = rwa;
879
                mina = aa;
880
              }
881
            }
882
            if (mina != INVALID) {
883
              _pred->set(v, mina);
884
              _delta2->increase(v, minrwa);
885
            } else {
886
              _pred->set(v, INVALID);
887
              _delta2->erase(v);
888
            }
889
          }
890
        }
891
      }
892
      if (min != INVALID) {
893
        _pred->set(node, min);
894
        _delta2->push(node, minrw);
895
      } else {
896
        _pred->set(node, INVALID);
897
      }
898
    }
899

	
900
    void oddToMatched(Node node) {
901
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
902
      Arc min = INVALID;
903
      Value minrw = std::numeric_limits<Value>::max();
904
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
905
        Node v = _graph.source(a);
906
        if ((*_status)[v] != EVEN) continue;
907
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
908
          dualScale * _weight[a];
909

	
910
        if (minrw > rw) {
911
          min = _graph.oppositeArc(a);
912
          minrw = rw;
913
        }
914
      }
915
      if (min != INVALID) {
916
        _pred->set(node, min);
917
        _delta2->push(node, minrw);
918
      } else {
919
        _pred->set(node, INVALID);
920
      }
921
    }
922

	
923
    void alternatePath(Node even, int tree) {
924
      Node odd;
925

	
926
      _status->set(even, MATCHED);
927
      evenToMatched(even, tree);
928

	
929
      Arc prev = (*_matching)[even];
930
      while (prev != INVALID) {
931
        odd = _graph.target(prev);
932
        even = _graph.target((*_pred)[odd]);
933
        _matching->set(odd, (*_pred)[odd]);
934
        _status->set(odd, MATCHED);
935
        oddToMatched(odd);
936

	
937
        prev = (*_matching)[even];
938
        _status->set(even, MATCHED);
939
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
940
        evenToMatched(even, tree);
941
      }
942
    }
943

	
944
    void destroyTree(int tree) {
945
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
946
        if ((*_status)[n] == EVEN) {
947
          _status->set(n, MATCHED);
948
          evenToMatched(n, tree);
949
        } else if ((*_status)[n] == ODD) {
950
          _status->set(n, MATCHED);
951
          oddToMatched(n);
952
        }
953
      }
954
      _tree_set->eraseClass(tree);
955
    }
956

	
957

	
958
    void unmatchNode(const Node& node) {
959
      int tree = _tree_set->find(node);
960

	
961
      alternatePath(node, tree);
962
      destroyTree(tree);
963

	
964
      _matching->set(node, INVALID);
965
    }
966

	
967

	
968
    void augmentOnEdge(const Edge& edge) {
969
      Node left = _graph.u(edge);
970
      int left_tree = _tree_set->find(left);
971

	
972
      alternatePath(left, left_tree);
973
      destroyTree(left_tree);
974
      _matching->set(left, _graph.direct(edge, true));
975

	
976
      Node right = _graph.v(edge);
977
      int right_tree = _tree_set->find(right);
978

	
979
      alternatePath(right, right_tree);
980
      destroyTree(right_tree);
981
      _matching->set(right, _graph.direct(edge, false));
982
    }
983

	
984
    void augmentOnArc(const Arc& arc) {
985
      Node left = _graph.source(arc);
986
      _status->set(left, MATCHED);
987
      _matching->set(left, arc);
988
      _pred->set(left, arc);
989

	
990
      Node right = _graph.target(arc);
991
      int right_tree = _tree_set->find(right);
992

	
993
      alternatePath(right, right_tree);
994
      destroyTree(right_tree);
995
      _matching->set(right, _graph.oppositeArc(arc));
996
    }
997

	
998
    void extendOnArc(const Arc& arc) {
999
      Node base = _graph.target(arc);
1000
      int tree = _tree_set->find(base);
1001

	
1002
      Node odd = _graph.source(arc);
1003
      _tree_set->insert(odd, tree);
1004
      _status->set(odd, ODD);
1005
      matchedToOdd(odd, tree);
1006
      _pred->set(odd, arc);
1007

	
1008
      Node even = _graph.target((*_matching)[odd]);
1009
      _tree_set->insert(even, tree);
1010
      _status->set(even, EVEN);
1011
      matchedToEven(even, tree);
1012
    }
1013

	
1014
    void cycleOnEdge(const Edge& edge, int tree) {
1015
      Node nca = INVALID;
1016
      std::vector<Node> left_path, right_path;
1017

	
1018
      {
1019
        std::set<Node> left_set, right_set;
1020
        Node left = _graph.u(edge);
1021
        left_path.push_back(left);
1022
        left_set.insert(left);
1023

	
1024
        Node right = _graph.v(edge);
1025
        right_path.push_back(right);
1026
        right_set.insert(right);
1027

	
1028
        while (true) {
1029

	
1030
          if (left_set.find(right) != left_set.end()) {
1031
            nca = right;
1032
            break;
1033
          }
1034

	
1035
          if ((*_matching)[left] == INVALID) break;
1036

	
1037
          left = _graph.target((*_matching)[left]);
1038
          left_path.push_back(left);
1039
          left = _graph.target((*_pred)[left]);
1040
          left_path.push_back(left);
1041

	
1042
          left_set.insert(left);
1043

	
1044
          if (right_set.find(left) != right_set.end()) {
1045
            nca = left;
1046
            break;
1047
          }
1048

	
1049
          if ((*_matching)[right] == INVALID) break;
1050

	
1051
          right = _graph.target((*_matching)[right]);
1052
          right_path.push_back(right);
1053
          right = _graph.target((*_pred)[right]);
1054
          right_path.push_back(right);
1055

	
1056
          right_set.insert(right);
1057

	
1058
        }
1059

	
1060
        if (nca == INVALID) {
1061
          if ((*_matching)[left] == INVALID) {
1062
            nca = right;
1063
            while (left_set.find(nca) == left_set.end()) {
1064
              nca = _graph.target((*_matching)[nca]);
1065
              right_path.push_back(nca);
1066
              nca = _graph.target((*_pred)[nca]);
1067
              right_path.push_back(nca);
1068
            }
1069
          } else {
1070
            nca = left;
1071
            while (right_set.find(nca) == right_set.end()) {
1072
              nca = _graph.target((*_matching)[nca]);
1073
              left_path.push_back(nca);
1074
              nca = _graph.target((*_pred)[nca]);
1075
              left_path.push_back(nca);
1076
            }
1077
          }
1078
        }
1079
      }
1080

	
1081
      alternatePath(nca, tree);
1082
      Arc prev;
1083

	
1084
      prev = _graph.direct(edge, true);
1085
      for (int i = 0; left_path[i] != nca; i += 2) {
1086
        _matching->set(left_path[i], prev);
1087
        _status->set(left_path[i], MATCHED);
1088
        evenToMatched(left_path[i], tree);
1089

	
1090
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
1091
        _status->set(left_path[i + 1], MATCHED);
1092
        oddToMatched(left_path[i + 1]);
1093
      }
1094
      _matching->set(nca, prev);
1095

	
1096
      for (int i = 0; right_path[i] != nca; i += 2) {
1097
        _status->set(right_path[i], MATCHED);
1098
        evenToMatched(right_path[i], tree);
1099

	
1100
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
1101
        _status->set(right_path[i + 1], MATCHED);
1102
        oddToMatched(right_path[i + 1]);
1103
      }
1104

	
1105
      destroyTree(tree);
1106
    }
1107

	
1108
    void extractCycle(const Arc &arc) {
1109
      Node left = _graph.source(arc);
1110
      Node odd = _graph.target((*_matching)[left]);
1111
      Arc prev;
1112
      while (odd != left) {
1113
        Node even = _graph.target((*_matching)[odd]);
1114
        prev = (*_matching)[odd];
1115
        odd = _graph.target((*_matching)[even]);
1116
        _matching->set(even, _graph.oppositeArc(prev));
1117
      }
1118
      _matching->set(left, arc);
1119

	
1120
      Node right = _graph.target(arc);
1121
      int right_tree = _tree_set->find(right);
1122
      alternatePath(right, right_tree);
1123
      destroyTree(right_tree);
1124
      _matching->set(right, _graph.oppositeArc(arc));
1125
    }
1126

	
1127
  public:
1128

	
1129
    /// \brief Constructor
1130
    ///
1131
    /// Constructor.
1132
    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
1133
                                  bool allow_loops = true)
1134
      : _graph(graph), _weight(weight), _matching(0),
1135
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1136
      _status(0),  _pred(0),
1137
      _tree_set_index(0), _tree_set(0),
1138

	
1139
      _delta1_index(0), _delta1(0),
1140
      _delta2_index(0), _delta2(0),
1141
      _delta3_index(0), _delta3(0),
1142

	
1143
      _delta_sum() {}
1144

	
1145
    ~MaxWeightedFractionalMatching() {
1146
      destroyStructures();
1147
    }
1148

	
1149
    /// \name Execution Control
1150
    /// The simplest way to execute the algorithm is to use the
1151
    /// \ref run() member function.
1152

	
1153
    ///@{
1154

	
1155
    /// \brief Initialize the algorithm
1156
    ///
1157
    /// This function initializes the algorithm.
1158
    void init() {
1159
      createStructures();
1160

	
1161
      for (NodeIt n(_graph); n != INVALID; ++n) {
1162
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1163
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1164
      }
1165
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1166
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1167
      }
1168

	
1169
      for (NodeIt n(_graph); n != INVALID; ++n) {
1170
        Value max = 0;
1171
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1172
          if (_graph.target(e) == n && !_allow_loops) continue;
1173
          if ((dualScale * _weight[e]) / 2 > max) {
1174
            max = (dualScale * _weight[e]) / 2;
1175
          }
1176
        }
1177
        _node_potential->set(n, max);
1178
        _delta1->push(n, max);
1179

	
1180
        _tree_set->insert(n);
1181

	
1182
        _matching->set(n, INVALID);
1183
        _status->set(n, EVEN);
1184
      }
1185

	
1186
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1187
        Node left = _graph.u(e);
1188
        Node right = _graph.v(e);
1189
        if (left == right && !_allow_loops) continue;
1190
        _delta3->push(e, ((*_node_potential)[left] +
1191
                          (*_node_potential)[right] -
1192
                          dualScale * _weight[e]) / 2);
1193
      }
1194
    }
1195

	
1196
    /// \brief Start the algorithm
1197
    ///
1198
    /// This function starts the algorithm.
1199
    ///
1200
    /// \pre \ref init() must be called before using this function.
1201
    void start() {
1202
      enum OpType {
1203
        D1, D2, D3
1204
      };
1205

	
1206
      int unmatched = _node_num;
1207
      while (unmatched > 0) {
1208
        Value d1 = !_delta1->empty() ?
1209
          _delta1->prio() : std::numeric_limits<Value>::max();
1210

	
1211
        Value d2 = !_delta2->empty() ?
1212
          _delta2->prio() : std::numeric_limits<Value>::max();
1213

	
1214
        Value d3 = !_delta3->empty() ?
1215
          _delta3->prio() : std::numeric_limits<Value>::max();
1216

	
1217
        _delta_sum = d3; OpType ot = D3;
1218
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1219
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1220

	
1221
        switch (ot) {
1222
        case D1:
1223
          {
1224
            Node n = _delta1->top();
1225
            unmatchNode(n);
1226
            --unmatched;
1227
          }
1228
          break;
1229
        case D2:
1230
          {
1231
            Node n = _delta2->top();
1232
            Arc a = (*_pred)[n];
1233
            if ((*_matching)[n] == INVALID) {
1234
              augmentOnArc(a);
1235
              --unmatched;
1236
            } else {
1237
              Node v = _graph.target((*_matching)[n]);
1238
              if ((*_matching)[n] !=
1239
                  _graph.oppositeArc((*_matching)[v])) {
1240
                extractCycle(a);
1241
                --unmatched;
1242
              } else {
1243
                extendOnArc(a);
1244
              }
1245
            }
1246
          } break;
1247
        case D3:
1248
          {
1249
            Edge e = _delta3->top();
1250

	
1251
            Node left = _graph.u(e);
1252
            Node right = _graph.v(e);
1253

	
1254
            int left_tree = _tree_set->find(left);
1255
            int right_tree = _tree_set->find(right);
1256

	
1257
            if (left_tree == right_tree) {
1258
              cycleOnEdge(e, left_tree);
1259
              --unmatched;
1260
            } else {
1261
              augmentOnEdge(e);
1262
              unmatched -= 2;
1263
            }
1264
          } break;
1265
        }
1266
      }
1267
    }
1268

	
1269
    /// \brief Run the algorithm.
1270
    ///
1271
    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
1272
    ///
1273
    /// \note mwfm.run() is just a shortcut of the following code.
1274
    /// \code
1275
    ///   mwfm.init();
1276
    ///   mwfm.start();
1277
    /// \endcode
1278
    void run() {
1279
      init();
1280
      start();
1281
    }
1282

	
1283
    /// @}
1284

	
1285
    /// \name Primal Solution
1286
    /// Functions to get the primal solution, i.e. the maximum weighted
1287
    /// matching.\n
1288
    /// Either \ref run() or \ref start() function should be called before
1289
    /// using them.
1290

	
1291
    /// @{
1292

	
1293
    /// \brief Return the weight of the matching.
1294
    ///
1295
    /// This function returns the weight of the found matching. This
1296
    /// value is scaled by \ref primalScale "primal scale".
1297
    ///
1298
    /// \pre Either run() or start() must be called before using this function.
1299
    Value matchingWeight() const {
1300
      Value sum = 0;
1301
      for (NodeIt n(_graph); n != INVALID; ++n) {
1302
        if ((*_matching)[n] != INVALID) {
1303
          sum += _weight[(*_matching)[n]];
1304
        }
1305
      }
1306
      return sum * primalScale / 2;
1307
    }
1308

	
1309
    /// \brief Return the number of covered nodes in the matching.
1310
    ///
1311
    /// This function returns the number of covered nodes in the matching.
1312
    ///
1313
    /// \pre Either run() or start() must be called before using this function.
1314
    int matchingSize() const {
1315
      int num = 0;
1316
      for (NodeIt n(_graph); n != INVALID; ++n) {
1317
        if ((*_matching)[n] != INVALID) {
1318
          ++num;
1319
        }
1320
      }
1321
      return num;
1322
    }
1323

	
1324
    /// \brief Return \c true if the given edge is in the matching.
1325
    ///
1326
    /// This function returns \c true if the given edge is in the
1327
    /// found matching. The result is scaled by \ref primalScale
1328
    /// "primal scale".
1329
    ///
1330
    /// \pre Either run() or start() must be called before using this function.
1331
    int matching(const Edge& edge) const {
1332
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
1333
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
1334
    }
1335

	
1336
    /// \brief Return the fractional matching arc (or edge) incident
1337
    /// to the given node.
1338
    ///
1339
    /// This function returns one of the fractional matching arc (or
1340
    /// edge) incident to the given node in the found matching or \c
1341
    /// INVALID if the node is not covered by the matching or if the
1342
    /// node is on an odd length cycle then it is the successor edge
1343
    /// on the cycle.
1344
    ///
1345
    /// \pre Either run() or start() must be called before using this function.
1346
    Arc matching(const Node& node) const {
1347
      return (*_matching)[node];
1348
    }
1349

	
1350
    /// \brief Return a const reference to the matching map.
1351
    ///
1352
    /// This function returns a const reference to a node map that stores
1353
    /// the matching arc (or edge) incident to each node.
1354
    const MatchingMap& matchingMap() const {
1355
      return *_matching;
1356
    }
1357

	
1358
    /// @}
1359

	
1360
    /// \name Dual Solution
1361
    /// Functions to get the dual solution.\n
1362
    /// Either \ref run() or \ref start() function should be called before
1363
    /// using them.
1364

	
1365
    /// @{
1366

	
1367
    /// \brief Return the value of the dual solution.
1368
    ///
1369
    /// This function returns the value of the dual solution.
1370
    /// It should be equal to the primal value scaled by \ref dualScale
1371
    /// "dual scale".
1372
    ///
1373
    /// \pre Either run() or start() must be called before using this function.
1374
    Value dualValue() const {
1375
      Value sum = 0;
1376
      for (NodeIt n(_graph); n != INVALID; ++n) {
1377
        sum += nodeValue(n);
1378
      }
1379
      return sum;
1380
    }
1381

	
1382
    /// \brief Return the dual value (potential) of the given node.
1383
    ///
1384
    /// This function returns the dual value (potential) of the given node.
1385
    ///
1386
    /// \pre Either run() or start() must be called before using this function.
1387
    Value nodeValue(const Node& n) const {
1388
      return (*_node_potential)[n];
1389
    }
1390

	
1391
    /// @}
1392

	
1393
  };
1394

	
1395
  /// \ingroup matching
1396
  ///
1397
  /// \brief Weighted fractional perfect matching in general graphs
1398
  ///
1399
  /// This class provides an efficient implementation of fractional
1400
  /// matching algorithm. The implementation uses priority queues and
1401
  /// provides \f$O(nm\log n)\f$ time complexity.
1402
  ///
1403
  /// The maximum weighted fractional perfect matching is a relaxation
1404
  /// of the maximum weighted perfect matching problem where the odd
1405
  /// set constraints are omitted.
1406
  /// It can be formulated with the following linear program.
1407
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
1408
  /// \f[x_e \ge 0\quad \forall e\in E\f]
1409
  /// \f[\max \sum_{e\in E}x_ew_e\f]
1410
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
1411
  /// \f$X\f$. The result must be the union of a matching with one
1412
  /// value edges and a set of odd length cycles with half value edges.
1413
  ///
1414
  /// The algorithm calculates an optimal fractional matching and a
1415
  /// proof of the optimality. The solution of the dual problem can be
1416
  /// used to check the result of the algorithm. The dual linear
1417
  /// problem is the following.
1418
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
1419
  /// \f[\min \sum_{u \in V}y_u \f]
1420
  ///
1421
  /// The algorithm can be executed with the run() function.
1422
  /// After it the matching (the primal solution) and the dual solution
1423
  /// can be obtained using the query functions.
1424
  ///
1425
  /// The primal solution is multiplied by
1426
  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
1427
  /// If the value type is integer, then the dual
1428
  /// solution is scaled by
1429
  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
1430
  ///
1431
  /// \tparam GR The undirected graph type the algorithm runs on.
1432
  /// \tparam WM The type edge weight map. The default type is
1433
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
1434
#ifdef DOXYGEN
1435
  template <typename GR, typename WM>
1436
#else
1437
  template <typename GR,
1438
            typename WM = typename GR::template EdgeMap<int> >
1439
#endif
1440
  class MaxWeightedPerfectFractionalMatching {
1441
  public:
1442

	
1443
    /// The graph type of the algorithm
1444
    typedef GR Graph;
1445
    /// The type of the edge weight map
1446
    typedef WM WeightMap;
1447
    /// The value type of the edge weights
1448
    typedef typename WeightMap::Value Value;
1449

	
1450
    /// The type of the matching map
1451
    typedef typename Graph::template NodeMap<typename Graph::Arc>
1452
    MatchingMap;
1453

	
1454
    /// \brief Scaling factor for primal solution
1455
    ///
1456
    /// Scaling factor for primal solution.
1457
    static const int primalScale = 2;
1458

	
1459
    /// \brief Scaling factor for dual solution
1460
    ///
1461
    /// Scaling factor for dual solution. It is equal to 4 or 1
1462
    /// according to the value type.
1463
    static const int dualScale =
1464
      std::numeric_limits<Value>::is_integer ? 4 : 1;
1465

	
1466
  private:
1467

	
1468
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1469

	
1470
    typedef typename Graph::template NodeMap<Value> NodePotential;
1471

	
1472
    const Graph& _graph;
1473
    const WeightMap& _weight;
1474

	
1475
    MatchingMap* _matching;
1476
    NodePotential* _node_potential;
1477

	
1478
    int _node_num;
1479
    bool _allow_loops;
1480

	
1481
    enum Status {
1482
      EVEN = -1, MATCHED = 0, ODD = 1
1483
    };
1484

	
1485
    typedef typename Graph::template NodeMap<Status> StatusMap;
1486
    StatusMap* _status;
1487

	
1488
    typedef typename Graph::template NodeMap<Arc> PredMap;
1489
    PredMap* _pred;
1490

	
1491
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
1492

	
1493
    IntNodeMap *_tree_set_index;
1494
    TreeSet *_tree_set;
1495

	
1496
    IntNodeMap *_delta2_index;
1497
    BinHeap<Value, IntNodeMap> *_delta2;
1498

	
1499
    IntEdgeMap *_delta3_index;
1500
    BinHeap<Value, IntEdgeMap> *_delta3;
1501

	
1502
    Value _delta_sum;
1503

	
1504
    void createStructures() {
1505
      _node_num = countNodes(_graph);
1506

	
1507
      if (!_matching) {
1508
        _matching = new MatchingMap(_graph);
1509
      }
1510
      if (!_node_potential) {
1511
        _node_potential = new NodePotential(_graph);
1512
      }
1513
      if (!_status) {
1514
        _status = new StatusMap(_graph);
1515
      }
1516
      if (!_pred) {
1517
        _pred = new PredMap(_graph);
1518
      }
1519
      if (!_tree_set) {
1520
        _tree_set_index = new IntNodeMap(_graph);
1521
        _tree_set = new TreeSet(*_tree_set_index);
1522
      }
1523
      if (!_delta2) {
1524
        _delta2_index = new IntNodeMap(_graph);
1525
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
1526
      }
1527
      if (!_delta3) {
1528
        _delta3_index = new IntEdgeMap(_graph);
1529
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
1530
      }
1531
    }
1532

	
1533
    void destroyStructures() {
1534
      if (_matching) {
1535
        delete _matching;
1536
      }
1537
      if (_node_potential) {
1538
        delete _node_potential;
1539
      }
1540
      if (_status) {
1541
        delete _status;
1542
      }
1543
      if (_pred) {
1544
        delete _pred;
1545
      }
1546
      if (_tree_set) {
1547
        delete _tree_set_index;
1548
        delete _tree_set;
1549
      }
1550
      if (_delta2) {
1551
        delete _delta2_index;
1552
        delete _delta2;
1553
      }
1554
      if (_delta3) {
1555
        delete _delta3_index;
1556
        delete _delta3;
1557
      }
1558
    }
1559

	
1560
    void matchedToEven(Node node, int tree) {
1561
      _tree_set->insert(node, tree);
1562
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
1563

	
1564
      if (_delta2->state(node) == _delta2->IN_HEAP) {
1565
        _delta2->erase(node);
1566
      }
1567

	
1568
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1569
        Node v = _graph.source(a);
1570
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1571
          dualScale * _weight[a];
1572
        if (node == v) {
1573
          if (_allow_loops && _graph.direction(a)) {
1574
            _delta3->push(a, rw / 2);
1575
          }
1576
        } else if ((*_status)[v] == EVEN) {
1577
          _delta3->push(a, rw / 2);
1578
        } else if ((*_status)[v] == MATCHED) {
1579
          if (_delta2->state(v) != _delta2->IN_HEAP) {
1580
            _pred->set(v, a);
1581
            _delta2->push(v, rw);
1582
          } else if ((*_delta2)[v] > rw) {
1583
            _pred->set(v, a);
1584
            _delta2->decrease(v, rw);
1585
          }
1586
        }
1587
      }
1588
    }
1589

	
1590
    void matchedToOdd(Node node, int tree) {
1591
      _tree_set->insert(node, tree);
1592
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
1593

	
1594
      if (_delta2->state(node) == _delta2->IN_HEAP) {
1595
        _delta2->erase(node);
1596
      }
1597
    }
1598

	
1599
    void evenToMatched(Node node, int tree) {
1600
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
1601
      Arc min = INVALID;
1602
      Value minrw = std::numeric_limits<Value>::max();
1603
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1604
        Node v = _graph.source(a);
1605
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1606
          dualScale * _weight[a];
1607

	
1608
        if (node == v) {
1609
          if (_allow_loops && _graph.direction(a)) {
1610
            _delta3->erase(a);
1611
          }
1612
        } else if ((*_status)[v] == EVEN) {
1613
          _delta3->erase(a);
1614
          if (minrw > rw) {
1615
            min = _graph.oppositeArc(a);
1616
            minrw = rw;
1617
          }
1618
        } else if ((*_status)[v]  == MATCHED) {
1619
          if ((*_pred)[v] == a) {
1620
            Arc mina = INVALID;
1621
            Value minrwa = std::numeric_limits<Value>::max();
1622
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
1623
              Node va = _graph.target(aa);
1624
              if ((*_status)[va] != EVEN ||
1625
                  _tree_set->find(va) == tree) continue;
1626
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
1627
                dualScale * _weight[aa];
1628
              if (minrwa > rwa) {
1629
                minrwa = rwa;
1630
                mina = aa;
1631
              }
1632
            }
1633
            if (mina != INVALID) {
1634
              _pred->set(v, mina);
1635
              _delta2->increase(v, minrwa);
1636
            } else {
1637
              _pred->set(v, INVALID);
1638
              _delta2->erase(v);
1639
            }
1640
          }
1641
        }
1642
      }
1643
      if (min != INVALID) {
1644
        _pred->set(node, min);
1645
        _delta2->push(node, minrw);
1646
      } else {
1647
        _pred->set(node, INVALID);
1648
      }
1649
    }
1650

	
1651
    void oddToMatched(Node node) {
1652
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
1653
      Arc min = INVALID;
1654
      Value minrw = std::numeric_limits<Value>::max();
1655
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1656
        Node v = _graph.source(a);
1657
        if ((*_status)[v] != EVEN) continue;
1658
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1659
          dualScale * _weight[a];
1660

	
1661
        if (minrw > rw) {
1662
          min = _graph.oppositeArc(a);
1663
          minrw = rw;
1664
        }
1665
      }
1666
      if (min != INVALID) {
1667
        _pred->set(node, min);
1668
        _delta2->push(node, minrw);
1669
      } else {
1670
        _pred->set(node, INVALID);
1671
      }
1672
    }
1673

	
1674
    void alternatePath(Node even, int tree) {
1675
      Node odd;
1676

	
1677
      _status->set(even, MATCHED);
1678
      evenToMatched(even, tree);
1679

	
1680
      Arc prev = (*_matching)[even];
1681
      while (prev != INVALID) {
1682
        odd = _graph.target(prev);
1683
        even = _graph.target((*_pred)[odd]);
1684
        _matching->set(odd, (*_pred)[odd]);
1685
        _status->set(odd, MATCHED);
1686
        oddToMatched(odd);
1687

	
1688
        prev = (*_matching)[even];
1689
        _status->set(even, MATCHED);
1690
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
1691
        evenToMatched(even, tree);
1692
      }
1693
    }
1694

	
1695
    void destroyTree(int tree) {
1696
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
1697
        if ((*_status)[n] == EVEN) {
1698
          _status->set(n, MATCHED);
1699
          evenToMatched(n, tree);
1700
        } else if ((*_status)[n] == ODD) {
1701
          _status->set(n, MATCHED);
1702
          oddToMatched(n);
1703
        }
1704
      }
1705
      _tree_set->eraseClass(tree);
1706
    }
1707

	
1708
    void augmentOnEdge(const Edge& edge) {
1709
      Node left = _graph.u(edge);
1710
      int left_tree = _tree_set->find(left);
1711

	
1712
      alternatePath(left, left_tree);
1713
      destroyTree(left_tree);
1714
      _matching->set(left, _graph.direct(edge, true));
1715

	
1716
      Node right = _graph.v(edge);
1717
      int right_tree = _tree_set->find(right);
1718

	
1719
      alternatePath(right, right_tree);
1720
      destroyTree(right_tree);
1721
      _matching->set(right, _graph.direct(edge, false));
1722
    }
1723

	
1724
    void augmentOnArc(const Arc& arc) {
1725
      Node left = _graph.source(arc);
1726
      _status->set(left, MATCHED);
1727
      _matching->set(left, arc);
1728
      _pred->set(left, arc);
1729

	
1730
      Node right = _graph.target(arc);
1731
      int right_tree = _tree_set->find(right);
1732

	
1733
      alternatePath(right, right_tree);
1734
      destroyTree(right_tree);
1735
      _matching->set(right, _graph.oppositeArc(arc));
1736
    }
1737

	
1738
    void extendOnArc(const Arc& arc) {
1739
      Node base = _graph.target(arc);
1740
      int tree = _tree_set->find(base);
1741

	
1742
      Node odd = _graph.source(arc);
1743
      _tree_set->insert(odd, tree);
1744
      _status->set(odd, ODD);
1745
      matchedToOdd(odd, tree);
1746
      _pred->set(odd, arc);
1747

	
1748
      Node even = _graph.target((*_matching)[odd]);
1749
      _tree_set->insert(even, tree);
1750
      _status->set(even, EVEN);
1751
      matchedToEven(even, tree);
1752
    }
1753

	
1754
    void cycleOnEdge(const Edge& edge, int tree) {
1755
      Node nca = INVALID;
1756
      std::vector<Node> left_path, right_path;
1757

	
1758
      {
1759
        std::set<Node> left_set, right_set;
1760
        Node left = _graph.u(edge);
1761
        left_path.push_back(left);
1762
        left_set.insert(left);
1763

	
1764
        Node right = _graph.v(edge);
1765
        right_path.push_back(right);
1766
        right_set.insert(right);
1767

	
1768
        while (true) {
1769

	
1770
          if (left_set.find(right) != left_set.end()) {
1771
            nca = right;
1772
            break;
1773
          }
1774

	
1775
          if ((*_matching)[left] == INVALID) break;
1776

	
1777
          left = _graph.target((*_matching)[left]);
1778
          left_path.push_back(left);
1779
          left = _graph.target((*_pred)[left]);
1780
          left_path.push_back(left);
1781

	
1782
          left_set.insert(left);
1783

	
1784
          if (right_set.find(left) != right_set.end()) {
1785
            nca = left;
1786
            break;
1787
          }
1788

	
1789
          if ((*_matching)[right] == INVALID) break;
1790

	
1791
          right = _graph.target((*_matching)[right]);
1792
          right_path.push_back(right);
1793
          right = _graph.target((*_pred)[right]);
1794
          right_path.push_back(right);
1795

	
1796
          right_set.insert(right);
1797

	
1798
        }
1799

	
1800
        if (nca == INVALID) {
1801
          if ((*_matching)[left] == INVALID) {
1802
            nca = right;
1803
            while (left_set.find(nca) == left_set.end()) {
1804
              nca = _graph.target((*_matching)[nca]);
1805
              right_path.push_back(nca);
1806
              nca = _graph.target((*_pred)[nca]);
1807
              right_path.push_back(nca);
1808
            }
1809
          } else {
1810
            nca = left;
1811
            while (right_set.find(nca) == right_set.end()) {
1812
              nca = _graph.target((*_matching)[nca]);
1813
              left_path.push_back(nca);
1814
              nca = _graph.target((*_pred)[nca]);
1815
              left_path.push_back(nca);
1816
            }
1817
          }
1818
        }
1819
      }
1820

	
1821
      alternatePath(nca, tree);
1822
      Arc prev;
1823

	
1824
      prev = _graph.direct(edge, true);
1825
      for (int i = 0; left_path[i] != nca; i += 2) {
1826
        _matching->set(left_path[i], prev);
1827
        _status->set(left_path[i], MATCHED);
1828
        evenToMatched(left_path[i], tree);
1829

	
1830
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
1831
        _status->set(left_path[i + 1], MATCHED);
1832
        oddToMatched(left_path[i + 1]);
1833
      }
1834
      _matching->set(nca, prev);
1835

	
1836
      for (int i = 0; right_path[i] != nca; i += 2) {
1837
        _status->set(right_path[i], MATCHED);
1838
        evenToMatched(right_path[i], tree);
1839

	
1840
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
1841
        _status->set(right_path[i + 1], MATCHED);
1842
        oddToMatched(right_path[i + 1]);
1843
      }
1844

	
1845
      destroyTree(tree);
1846
    }
1847

	
1848
    void extractCycle(const Arc &arc) {
1849
      Node left = _graph.source(arc);
1850
      Node odd = _graph.target((*_matching)[left]);
1851
      Arc prev;
1852
      while (odd != left) {
1853
        Node even = _graph.target((*_matching)[odd]);
1854
        prev = (*_matching)[odd];
1855
        odd = _graph.target((*_matching)[even]);
1856
        _matching->set(even, _graph.oppositeArc(prev));
1857
      }
1858
      _matching->set(left, arc);
1859

	
1860
      Node right = _graph.target(arc);
1861
      int right_tree = _tree_set->find(right);
1862
      alternatePath(right, right_tree);
1863
      destroyTree(right_tree);
1864
      _matching->set(right, _graph.oppositeArc(arc));
1865
    }
1866

	
1867
  public:
1868

	
1869
    /// \brief Constructor
1870
    ///
1871
    /// Constructor.
1872
    MaxWeightedPerfectFractionalMatching(const Graph& graph,
1873
                                         const WeightMap& weight,
1874
                                         bool allow_loops = true)
1875
      : _graph(graph), _weight(weight), _matching(0),
1876
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1877
      _status(0),  _pred(0),
1878
      _tree_set_index(0), _tree_set(0),
1879

	
1880
      _delta2_index(0), _delta2(0),
1881
      _delta3_index(0), _delta3(0),
1882

	
1883
      _delta_sum() {}
1884

	
1885
    ~MaxWeightedPerfectFractionalMatching() {
1886
      destroyStructures();
1887
    }
1888

	
1889
    /// \name Execution Control
1890
    /// The simplest way to execute the algorithm is to use the
1891
    /// \ref run() member function.
1892

	
1893
    ///@{
1894

	
1895
    /// \brief Initialize the algorithm
1896
    ///
1897
    /// This function initializes the algorithm.
1898
    void init() {
1899
      createStructures();
1900

	
1901
      for (NodeIt n(_graph); n != INVALID; ++n) {
1902
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1903
      }
1904
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1905
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1906
      }
1907

	
1908
      for (NodeIt n(_graph); n != INVALID; ++n) {
1909
        Value max = - std::numeric_limits<Value>::max();
1910
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1911
          if (_graph.target(e) == n && !_allow_loops) continue;
1912
          if ((dualScale * _weight[e]) / 2 > max) {
1913
            max = (dualScale * _weight[e]) / 2;
1914
          }
1915
        }
1916
        _node_potential->set(n, max);
1917

	
1918
        _tree_set->insert(n);
1919

	
1920
        _matching->set(n, INVALID);
1921
        _status->set(n, EVEN);
1922
      }
1923

	
1924
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1925
        Node left = _graph.u(e);
1926
        Node right = _graph.v(e);
1927
        if (left == right && !_allow_loops) continue;
1928
        _delta3->push(e, ((*_node_potential)[left] +
1929
                          (*_node_potential)[right] -
1930
                          dualScale * _weight[e]) / 2);
1931
      }
1932
    }
1933

	
1934
    /// \brief Start the algorithm
1935
    ///
1936
    /// This function starts the algorithm.
1937
    ///
1938
    /// \pre \ref init() must be called before using this function.
1939
    bool start() {
1940
      enum OpType {
1941
        D2, D3
1942
      };
1943

	
1944
      int unmatched = _node_num;
1945
      while (unmatched > 0) {
1946
        Value d2 = !_delta2->empty() ?
1947
          _delta2->prio() : std::numeric_limits<Value>::max();
1948

	
1949
        Value d3 = !_delta3->empty() ?
1950
          _delta3->prio() : std::numeric_limits<Value>::max();
1951

	
1952
        _delta_sum = d3; OpType ot = D3;
1953
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1954

	
1955
        if (_delta_sum == std::numeric_limits<Value>::max()) {
1956
          return false;
1957
        }
1958

	
1959
        switch (ot) {
1960
        case D2:
1961
          {
1962
            Node n = _delta2->top();
1963
            Arc a = (*_pred)[n];
1964
            if ((*_matching)[n] == INVALID) {
1965
              augmentOnArc(a);
1966
              --unmatched;
1967
            } else {
1968
              Node v = _graph.target((*_matching)[n]);
1969
              if ((*_matching)[n] !=
1970
                  _graph.oppositeArc((*_matching)[v])) {
1971
                extractCycle(a);
1972
                --unmatched;
1973
              } else {
1974
                extendOnArc(a);
1975
              }
1976
            }
1977
          } break;
1978
        case D3:
1979
          {
1980
            Edge e = _delta3->top();
1981

	
1982
            Node left = _graph.u(e);
1983
            Node right = _graph.v(e);
1984

	
1985
            int left_tree = _tree_set->find(left);
1986
            int right_tree = _tree_set->find(right);
1987

	
1988
            if (left_tree == right_tree) {
1989
              cycleOnEdge(e, left_tree);
1990
              --unmatched;
1991
            } else {
1992
              augmentOnEdge(e);
1993
              unmatched -= 2;
1994
            }
1995
          } break;
1996
        }
1997
      }
1998
      return true;
1999
    }
2000

	
2001
    /// \brief Run the algorithm.
2002
    ///
2003
    /// This method runs the \c %MaxWeightedPerfectFractionalMatching 
2004
    /// algorithm.
2005
    ///
2006
    /// \note mwfm.run() is just a shortcut of the following code.
2007
    /// \code
2008
    ///   mwpfm.init();
2009
    ///   mwpfm.start();
2010
    /// \endcode
2011
    bool run() {
2012
      init();
2013
      return start();
2014
    }
2015

	
2016
    /// @}
2017

	
2018
    /// \name Primal Solution
2019
    /// Functions to get the primal solution, i.e. the maximum weighted
2020
    /// matching.\n
2021
    /// Either \ref run() or \ref start() function should be called before
2022
    /// using them.
2023

	
2024
    /// @{
2025

	
2026
    /// \brief Return the weight of the matching.
2027
    ///
2028
    /// This function returns the weight of the found matching. This
2029
    /// value is scaled by \ref primalScale "primal scale".
2030
    ///
2031
    /// \pre Either run() or start() must be called before using this function.
2032
    Value matchingWeight() const {
2033
      Value sum = 0;
2034
      for (NodeIt n(_graph); n != INVALID; ++n) {
2035
        if ((*_matching)[n] != INVALID) {
2036
          sum += _weight[(*_matching)[n]];
2037
        }
2038
      }
2039
      return sum * primalScale / 2;
2040
    }
2041

	
2042
    /// \brief Return the number of covered nodes in the matching.
2043
    ///
2044
    /// This function returns the number of covered nodes in the matching.
2045
    ///
2046
    /// \pre Either run() or start() must be called before using this function.
2047
    int matchingSize() const {
2048
      int num = 0;
2049
      for (NodeIt n(_graph); n != INVALID; ++n) {
2050
        if ((*_matching)[n] != INVALID) {
2051
          ++num;
2052
        }
2053
      }
2054
      return num;
2055
    }
2056

	
2057
    /// \brief Return \c true if the given edge is in the matching.
2058
    ///
2059
    /// This function returns \c true if the given edge is in the
2060
    /// found matching. The result is scaled by \ref primalScale
2061
    /// "primal scale".
2062
    ///
2063
    /// \pre Either run() or start() must be called before using this function.
2064
    int matching(const Edge& edge) const {
2065
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
2066
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
2067
    }
2068

	
2069
    /// \brief Return the fractional matching arc (or edge) incident
2070
    /// to the given node.
2071
    ///
2072
    /// This function returns one of the fractional matching arc (or
2073
    /// edge) incident to the given node in the found matching or \c
2074
    /// INVALID if the node is not covered by the matching or if the
2075
    /// node is on an odd length cycle then it is the successor edge
2076
    /// on the cycle.
2077
    ///
2078
    /// \pre Either run() or start() must be called before using this function.
2079
    Arc matching(const Node& node) const {
2080
      return (*_matching)[node];
2081
    }
2082

	
2083
    /// \brief Return a const reference to the matching map.
2084
    ///
2085
    /// This function returns a const reference to a node map that stores
2086
    /// the matching arc (or edge) incident to each node.
2087
    const MatchingMap& matchingMap() const {
2088
      return *_matching;
2089
    }
2090

	
2091
    /// @}
2092

	
2093
    /// \name Dual Solution
2094
    /// Functions to get the dual solution.\n
2095
    /// Either \ref run() or \ref start() function should be called before
2096
    /// using them.
2097

	
2098
    /// @{
2099

	
2100
    /// \brief Return the value of the dual solution.
2101
    ///
2102
    /// This function returns the value of the dual solution.
2103
    /// It should be equal to the primal value scaled by \ref dualScale
2104
    /// "dual scale".
2105
    ///
2106
    /// \pre Either run() or start() must be called before using this function.
2107
    Value dualValue() const {
2108
      Value sum = 0;
2109
      for (NodeIt n(_graph); n != INVALID; ++n) {
2110
        sum += nodeValue(n);
2111
      }
2112
      return sum;
2113
    }
2114

	
2115
    /// \brief Return the dual value (potential) of the given node.
2116
    ///
2117
    /// This function returns the dual value (potential) of the given node.
2118
    ///
2119
    /// \pre Either run() or start() must be called before using this function.
2120
    Value nodeValue(const Node& n) const {
2121
      return (*_node_potential)[n];
2122
    }
2123

	
2124
    /// @}
2125

	
2126
  };
2127

	
2128
} //END OF NAMESPACE LEMON
2129

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

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

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

	
32
#include "test_tools.h"
33

	
34
using namespace std;
35
using namespace lemon;
36

	
37
GRAPH_TYPEDEFS(SmartGraph);
38

	
39

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

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

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

	
114
  "@nodes\n"
115
  "label\n"
116
  "0\n"
117
  "@edges\n"
118
  "     label  weight\n"
119
  "0 0  0      100\n"
120
};
121

	
122
void checkMaxFractionalMatchingCompile()
123
{
124
  typedef concepts::Graph Graph;
125
  typedef Graph::Node Node;
126
  typedef Graph::Edge Edge;
127

	
128
  Graph g;
129
  Node n;
130
  Edge e;
131

	
132
  MaxFractionalMatching<Graph> mat_test(g);
133
  const MaxFractionalMatching<Graph>&
134
    const_mat_test = mat_test;
135

	
136
  mat_test.init();
137
  mat_test.start();
138
  mat_test.start(true);
139
  mat_test.startPerfect();
140
  mat_test.startPerfect(true);
141
  mat_test.run();
142
  mat_test.run(true);
143
  mat_test.runPerfect();
144
  mat_test.runPerfect(true);
145

	
146
  const_mat_test.matchingSize();
147
  const_mat_test.matching(e);
148
  const_mat_test.matching(n);
149
  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
150
    const_mat_test.matchingMap();
151
  e = mmap[n];
152

	
153
  const_mat_test.barrier(n);
154
}
155

	
156
void checkMaxWeightedFractionalMatchingCompile()
157
{
158
  typedef concepts::Graph Graph;
159
  typedef Graph::Node Node;
160
  typedef Graph::Edge Edge;
161
  typedef Graph::EdgeMap<int> WeightMap;
162

	
163
  Graph g;
164
  Node n;
165
  Edge e;
166
  WeightMap w(g);
167

	
168
  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
169
  const MaxWeightedFractionalMatching<Graph>&
170
    const_mat_test = mat_test;
171

	
172
  mat_test.init();
173
  mat_test.start();
174
  mat_test.run();
175

	
176
  const_mat_test.matchingWeight();
177
  const_mat_test.matchingSize();
178
  const_mat_test.matching(e);
179
  const_mat_test.matching(n);
180
  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
181
    const_mat_test.matchingMap();
182
  e = mmap[n];
183

	
184
  const_mat_test.dualValue();
185
  const_mat_test.nodeValue(n);
186
}
187

	
188
void checkMaxWeightedPerfectFractionalMatchingCompile()
189
{
190
  typedef concepts::Graph Graph;
191
  typedef Graph::Node Node;
192
  typedef Graph::Edge Edge;
193
  typedef Graph::EdgeMap<int> WeightMap;
194

	
195
  Graph g;
196
  Node n;
197
  Edge e;
198
  WeightMap w(g);
199

	
200
  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
201
  const MaxWeightedPerfectFractionalMatching<Graph>&
202
    const_mat_test = mat_test;
203

	
204
  mat_test.init();
205
  mat_test.start();
206
  mat_test.run();
207

	
208
  const_mat_test.matchingWeight();
209
  const_mat_test.matching(e);
210
  const_mat_test.matching(n);
211
  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
212
    const_mat_test.matchingMap();
213
  e = mmap[n];
214

	
215
  const_mat_test.dualValue();
216
  const_mat_test.nodeValue(n);
217
}
218

	
219
void checkFractionalMatching(const SmartGraph& graph,
220
                             const MaxFractionalMatching<SmartGraph>& mfm,
221
                             bool allow_loops = true) {
222
  int pv = 0;
223
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
224
    int indeg = 0;
225
    for (InArcIt a(graph, n); a != INVALID; ++a) {
226
      if (mfm.matching(graph.source(a)) == a) {
227
        ++indeg;
228
      }
229
    }
230
    if (mfm.matching(n) != INVALID) {
231
      check(indeg == 1, "Invalid matching");
232
      ++pv;
233
    } else {
234
      check(indeg == 0, "Invalid matching");
235
    }
236
  }
237
  check(pv == mfm.matchingSize(), "Wrong matching size");
238

	
239
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
240
    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
241
          (e == mfm.matching(graph.v(e)) ? 1 : 0) == 
242
          mfm.matching(e), "Invalid matching");
243
  }
244

	
245
  SmartGraph::NodeMap<bool> processed(graph, false);
246
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
247
    if (processed[n]) continue;
248
    processed[n] = true;
249
    if (mfm.matching(n) == INVALID) continue;
250
    int num = 1;
251
    Node v = graph.target(mfm.matching(n));
252
    while (v != n) {
253
      processed[v] = true;
254
      ++num;
255
      v = graph.target(mfm.matching(v));
256
    }
257
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
258
    check(allow_loops || num != 1, "Wrong cycle size");
259
  }
260

	
261
  int anum = 0, bnum = 0;
262
  SmartGraph::NodeMap<bool> neighbours(graph, false);
263
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
264
    if (!mfm.barrier(n)) continue;
265
    ++anum;
266
    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
267
      Node u = graph.source(a);
268
      if (!allow_loops && u == n) continue;
269
      if (!neighbours[u]) {
270
        neighbours[u] = true;
271
        ++bnum;
272
      }
273
    }
274
  }
275
  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
276
        "Wrong barrier");
277
}
278

	
279
void checkPerfectFractionalMatching(const SmartGraph& graph,
280
                             const MaxFractionalMatching<SmartGraph>& mfm,
281
                             bool perfect, bool allow_loops = true) {
282
  if (perfect) {
283
    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
284
      int indeg = 0;
285
      for (InArcIt a(graph, n); a != INVALID; ++a) {
286
        if (mfm.matching(graph.source(a)) == a) {
287
          ++indeg;
288
        }
289
      }
290
      check(mfm.matching(n) != INVALID, "Invalid matching");
291
      check(indeg == 1, "Invalid matching");
292
    }
293
    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
294
      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
295
            (e == mfm.matching(graph.v(e)) ? 1 : 0) == 
296
            mfm.matching(e), "Invalid matching");
297
    }
298
  } else {
299
    int anum = 0, bnum = 0;
300
    SmartGraph::NodeMap<bool> neighbours(graph, false);
301
    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
302
      if (!mfm.barrier(n)) continue;
303
      ++anum;
304
      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
305
        Node u = graph.source(a);
306
        if (!allow_loops && u == n) continue;
307
        if (!neighbours[u]) {
308
          neighbours[u] = true;
309
          ++bnum;
310
        }
311
      }
312
    }
313
    check(anum - bnum > 0, "Wrong barrier");
314
  }
315
}
316

	
317
void checkWeightedFractionalMatching(const SmartGraph& graph,
318
                   const SmartGraph::EdgeMap<int>& weight,
319
                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
320
                   bool allow_loops = true) {
321
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
322
    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
323
    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
324
      - weight[e] * mwfm.dualScale;
325

	
326
    check(rw >= 0, "Negative reduced weight");
327
    check(rw == 0 || !mwfm.matching(e),
328
          "Non-zero reduced weight on matching edge");
329
  }
330

	
331
  int pv = 0;
332
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
333
    int indeg = 0;
334
    for (InArcIt a(graph, n); a != INVALID; ++a) {
335
      if (mwfm.matching(graph.source(a)) == a) {
336
        ++indeg;
337
      }
338
    }
339
    check(indeg <= 1, "Invalid matching");
340
    if (mwfm.matching(n) != INVALID) {
341
      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
342
      check(indeg == 1, "Invalid matching");
343
      pv += weight[mwfm.matching(n)];
344
      SmartGraph::Node o = graph.target(mwfm.matching(n));
345
    } else {
346
      check(mwfm.nodeValue(n) == 0, "Invalid matching");
347
      check(indeg == 0, "Invalid matching");
348
    }
349
  }
350

	
351
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
352
    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
353
          (e == mwfm.matching(graph.v(e)) ? 1 : 0) == 
354
          mwfm.matching(e), "Invalid matching");
355
  }
356

	
357
  int dv = 0;
358
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
359
    dv += mwfm.nodeValue(n);
360
  }
361

	
362
  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
363

	
364
  SmartGraph::NodeMap<bool> processed(graph, false);
365
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
366
    if (processed[n]) continue;
367
    processed[n] = true;
368
    if (mwfm.matching(n) == INVALID) continue;
369
    int num = 1;
370
    Node v = graph.target(mwfm.matching(n));
371
    while (v != n) {
372
      processed[v] = true;
373
      ++num;
374
      v = graph.target(mwfm.matching(v));
375
    }
376
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
377
    check(allow_loops || num != 1, "Wrong cycle size");
378
  }
379

	
380
  return;
381
}
382

	
383
void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
384
                const SmartGraph::EdgeMap<int>& weight,
385
                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
386
                bool allow_loops = true) {
387
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
388
    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
389
    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
390
      - weight[e] * mwpfm.dualScale;
391

	
392
    check(rw >= 0, "Negative reduced weight");
393
    check(rw == 0 || !mwpfm.matching(e),
394
          "Non-zero reduced weight on matching edge");
395
  }
396

	
397
  int pv = 0;
398
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
399
    int indeg = 0;
400
    for (InArcIt a(graph, n); a != INVALID; ++a) {
401
      if (mwpfm.matching(graph.source(a)) == a) {
402
        ++indeg;
403
      }
404
    }
405
    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
406
    check(indeg == 1, "Invalid perfect matching");
407
    pv += weight[mwpfm.matching(n)];
408
    SmartGraph::Node o = graph.target(mwpfm.matching(n));
409
  }
410

	
411
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
412
    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
413
          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) == 
414
          mwpfm.matching(e), "Invalid matching");
415
  }
416

	
417
  int dv = 0;
418
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
419
    dv += mwpfm.nodeValue(n);
420
  }
421

	
422
  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
423

	
424
  SmartGraph::NodeMap<bool> processed(graph, false);
425
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
426
    if (processed[n]) continue;
427
    processed[n] = true;
428
    if (mwpfm.matching(n) == INVALID) continue;
429
    int num = 1;
430
    Node v = graph.target(mwpfm.matching(n));
431
    while (v != n) {
432
      processed[v] = true;
433
      ++num;
434
      v = graph.target(mwpfm.matching(v));
435
    }
436
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
437
    check(allow_loops || num != 1, "Wrong cycle size");
438
  }
439

	
440
  return;
441
}
442

	
443

	
444
int main() {
445

	
446
  for (int i = 0; i < lgfn; ++i) {
447
    SmartGraph graph;
448
    SmartGraph::EdgeMap<int> weight(graph);
449

	
450
    istringstream lgfs(lgf[i]);
451
    graphReader(graph, lgfs).
452
      edgeMap("weight", weight).run();
453

	
454
    bool perfect_with_loops;
455
    {
456
      MaxFractionalMatching<SmartGraph> mfm(graph, true);
457
      mfm.run();
458
      checkFractionalMatching(graph, mfm, true);
459
      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
460
    }
461

	
462
    bool perfect_without_loops;
463
    {
464
      MaxFractionalMatching<SmartGraph> mfm(graph, false);
465
      mfm.run();
466
      checkFractionalMatching(graph, mfm, false);
467
      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
468
    }
469

	
470
    {
471
      MaxFractionalMatching<SmartGraph> mfm(graph, true);
472
      bool result = mfm.runPerfect();
473
      checkPerfectFractionalMatching(graph, mfm, result, true);
474
      check(result == perfect_with_loops, "Wrong perfect matching");
475
    }
476

	
477
    {
478
      MaxFractionalMatching<SmartGraph> mfm(graph, false);
479
      bool result = mfm.runPerfect();
480
      checkPerfectFractionalMatching(graph, mfm, result, false);
481
      check(result == perfect_without_loops, "Wrong perfect matching");
482
    }
483

	
484
    {
485
      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
486
      mwfm.run();
487
      checkWeightedFractionalMatching(graph, weight, mwfm, true);
488
    }
489

	
490
    {
491
      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
492
      mwfm.run();
493
      checkWeightedFractionalMatching(graph, weight, mwfm, false);
494
    }
495

	
496
    {
497
      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
498
                                                             true);
499
      bool perfect = mwpfm.run();
500
      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
501
            "Perfect matching found");
502
      check(perfect == perfect_with_loops, "Wrong perfect matching");
503

	
504
      if (perfect) {
505
        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
506
      }
507
    }
508

	
509
    {
510
      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
511
                                                             false);
512
      bool perfect = mwpfm.run();
513
      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
514
            "Perfect matching found");
515
      check(perfect == perfect_without_loops, "Wrong perfect matching");
516

	
517
      if (perfect) {
518
        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
519
      }
520
    }
521

	
522
  }
523

	
524
  return 0;
525
}
Ignore white space 192 line context
... ...
@@ -293,328 +293,335 @@
293 293
   "dim2::Point"'s.
294 294
*/
295 295

	
296 296
/**
297 297
@defgroup matrices Matrices
298 298
@ingroup auxdat
299 299
\brief Two dimensional data storages implemented in LEMON.
300 300

	
301 301
This group contains two dimensional data storages implemented in LEMON.
302 302
*/
303 303

	
304 304
/**
305 305
@defgroup algs Algorithms
306 306
\brief This group contains the several algorithms
307 307
implemented in LEMON.
308 308

	
309 309
This group contains the several algorithms
310 310
implemented in LEMON.
311 311
*/
312 312

	
313 313
/**
314 314
@defgroup search Graph Search
315 315
@ingroup algs
316 316
\brief Common graph search algorithms.
317 317

	
318 318
This group contains the common graph search algorithms, namely
319 319
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
320 320
\ref clrs01algorithms.
321 321
*/
322 322

	
323 323
/**
324 324
@defgroup shortest_path Shortest Path Algorithms
325 325
@ingroup algs
326 326
\brief Algorithms for finding shortest paths.
327 327

	
328 328
This group contains the algorithms for finding shortest paths in digraphs
329 329
\ref clrs01algorithms.
330 330

	
331 331
 - \ref Dijkstra algorithm for finding shortest paths from a source node
332 332
   when all arc lengths are non-negative.
333 333
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
334 334
   from a source node when arc lenghts can be either positive or negative,
335 335
   but the digraph should not contain directed cycles with negative total
336 336
   length.
337 337
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
338 338
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
339 339
   lenghts can be either positive or negative, but the digraph should
340 340
   not contain directed cycles with negative total length.
341 341
 - \ref Suurballe A successive shortest path algorithm for finding
342 342
   arc-disjoint paths between two nodes having minimum total length.
343 343
*/
344 344

	
345 345
/**
346 346
@defgroup spantree Minimum Spanning Tree Algorithms
347 347
@ingroup algs
348 348
\brief Algorithms for finding minimum cost spanning trees and arborescences.
349 349

	
350 350
This group contains the algorithms for finding minimum cost spanning
351 351
trees and arborescences \ref clrs01algorithms.
352 352
*/
353 353

	
354 354
/**
355 355
@defgroup max_flow Maximum Flow Algorithms
356 356
@ingroup algs
357 357
\brief Algorithms for finding maximum flows.
358 358

	
359 359
This group contains the algorithms for finding maximum flows and
360 360
feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
361 361

	
362 362
The \e maximum \e flow \e problem is to find a flow of maximum value between
363 363
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
364 364
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
365 365
\f$s, t \in V\f$ source and target nodes.
366 366
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
367 367
following optimization problem.
368 368

	
369 369
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
370 370
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
371 371
    \quad \forall u\in V\setminus\{s,t\} \f]
372 372
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
373 373

	
374 374
LEMON contains several algorithms for solving maximum flow problems:
375 375
- \ref EdmondsKarp Edmonds-Karp algorithm
376 376
  \ref edmondskarp72theoretical.
377 377
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
378 378
  \ref goldberg88newapproach.
379 379
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
380 380
  \ref dinic70algorithm, \ref sleator83dynamic.
381 381
- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
382 382
  \ref goldberg88newapproach, \ref sleator83dynamic.
383 383

	
384 384
In most cases the \ref Preflow algorithm provides the
385 385
fastest method for computing a maximum flow. All implementations
386 386
also provide functions to query the minimum cut, which is the dual
387 387
problem of maximum flow.
388 388

	
389
\ref Circulation is a preflow push-relabel algorithm implemented directly 
389
\ref Circulation is a preflow push-relabel algorithm implemented directly
390 390
for finding feasible circulations, which is a somewhat different problem,
391 391
but it is strongly related to maximum flow.
392 392
For more information, see \ref Circulation.
393 393
*/
394 394

	
395 395
/**
396 396
@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
397 397
@ingroup algs
398 398

	
399 399
\brief Algorithms for finding minimum cost flows and circulations.
400 400

	
401 401
This group contains the algorithms for finding minimum cost flows and
402 402
circulations \ref amo93networkflows. For more information about this
403 403
problem and its dual solution, see \ref min_cost_flow
404 404
"Minimum Cost Flow Problem".
405 405

	
406 406
LEMON contains several algorithms for this problem.
407 407
 - \ref NetworkSimplex Primal Network Simplex algorithm with various
408 408
   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
409 409
 - \ref CostScaling Cost Scaling algorithm based on push/augment and
410 410
   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
411 411
   \ref bunnagel98efficient.
412 412
 - \ref CapacityScaling Capacity Scaling algorithm based on the successive
413 413
   shortest path method \ref edmondskarp72theoretical.
414 414
 - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
415 415
   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
416 416

	
417 417
In general NetworkSimplex is the most efficient implementation,
418 418
but in special cases other algorithms could be faster.
419 419
For example, if the total supply and/or capacities are rather small,
420 420
CapacityScaling is usually the fastest algorithm (without effective scaling).
421 421
*/
422 422

	
423 423
/**
424 424
@defgroup min_cut Minimum Cut Algorithms
425 425
@ingroup algs
426 426

	
427 427
\brief Algorithms for finding minimum cut in graphs.
428 428

	
429 429
This group contains the algorithms for finding minimum cut in graphs.
430 430

	
431 431
The \e minimum \e cut \e problem is to find a non-empty and non-complete
432 432
\f$X\f$ subset of the nodes with minimum overall capacity on
433 433
outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
434 434
\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
435 435
cut is the \f$X\f$ solution of the next optimization problem:
436 436

	
437 437
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
438 438
    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
439 439

	
440 440
LEMON contains several algorithms related to minimum cut problems:
441 441

	
442 442
- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
443 443
  in directed graphs.
444 444
- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
445 445
  calculating minimum cut in undirected graphs.
446 446
- \ref GomoryHu "Gomory-Hu tree computation" for calculating
447 447
  all-pairs minimum cut in undirected graphs.
448 448

	
449 449
If you want to find minimum cut just between two distinict nodes,
450 450
see the \ref max_flow "maximum flow problem".
451 451
*/
452 452

	
453 453
/**
454 454
@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
455 455
@ingroup algs
456 456
\brief Algorithms for finding minimum mean cycles.
457 457

	
458 458
This group contains the algorithms for finding minimum mean cycles
459 459
\ref clrs01algorithms, \ref amo93networkflows.
460 460

	
461 461
The \e minimum \e mean \e cycle \e problem is to find a directed cycle
462 462
of minimum mean length (cost) in a digraph.
463 463
The mean length of a cycle is the average length of its arcs, i.e. the
464 464
ratio between the total length of the cycle and the number of arcs on it.
465 465

	
466 466
This problem has an important connection to \e conservative \e length
467 467
\e functions, too. A length function on the arcs of a digraph is called
468 468
conservative if and only if there is no directed cycle of negative total
469 469
length. For an arbitrary length function, the negative of the minimum
470 470
cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
471 471
arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
472 472
function.
473 473

	
474 474
LEMON contains three algorithms for solving the minimum mean cycle problem:
475 475
- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
476 476
  \ref dasdan98minmeancycle.
477 477
- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
478 478
  version of Karp's algorithm \ref dasdan98minmeancycle.
479 479
- \ref Howard "Howard"'s policy iteration algorithm
480 480
  \ref dasdan98minmeancycle.
481 481

	
482 482
In practice, the Howard algorithm proved to be by far the most efficient
483 483
one, though the best known theoretical bound on its running time is
484 484
exponential.
485 485
Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
486 486
O(n<sup>2</sup>+e), but the latter one is typically faster due to the
487 487
applied early termination scheme.
488 488
*/
489 489

	
490 490
/**
491 491
@defgroup matching Matching Algorithms
492 492
@ingroup algs
493 493
\brief Algorithms for finding matchings in graphs and bipartite graphs.
494 494

	
495 495
This group contains the algorithms for calculating
496 496
matchings in graphs and bipartite graphs. The general matching problem is
497 497
finding a subset of the edges for which each node has at most one incident
498 498
edge.
499 499

	
500 500
There are several different algorithms for calculate matchings in
501 501
graphs.  The matching problems in bipartite graphs are generally
502 502
easier than in general graphs. The goal of the matching optimization
503 503
can be finding maximum cardinality, maximum weight or minimum cost
504 504
matching. The search can be constrained to find perfect or
505 505
maximum cardinality matching.
506 506

	
507 507
The matching algorithms implemented in LEMON:
508 508
- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
509 509
  for calculating maximum cardinality matching in bipartite graphs.
510 510
- \ref PrBipartiteMatching Push-relabel algorithm
511 511
  for calculating maximum cardinality matching in bipartite graphs.
512 512
- \ref MaxWeightedBipartiteMatching
513 513
  Successive shortest path algorithm for calculating maximum weighted
514 514
  matching and maximum weighted bipartite matching in bipartite graphs.
515 515
- \ref MinCostMaxBipartiteMatching
516 516
  Successive shortest path algorithm for calculating minimum cost maximum
517 517
  matching in bipartite graphs.
518 518
- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
519 519
  maximum cardinality matching in general graphs.
520 520
- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
521 521
  maximum weighted matching in general graphs.
522 522
- \ref MaxWeightedPerfectMatching
523 523
  Edmond's blossom shrinking algorithm for calculating maximum weighted
524 524
  perfect matching in general graphs.
525
- \ref MaxFractionalMatching Push-relabel algorithm for calculating
526
  maximum cardinality fractional matching in general graphs.
527
- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
528
  maximum weighted fractional matching in general graphs.
529
- \ref MaxWeightedPerfectFractionalMatching
530
  Augmenting path algorithm for calculating maximum weighted
531
  perfect fractional matching in general graphs.
525 532

	
526 533
\image html matching.png
527 534
\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
528 535
*/
529 536

	
530 537
/**
531 538
@defgroup graph_properties Connectivity and Other Graph Properties
532 539
@ingroup algs
533 540
\brief Algorithms for discovering the graph properties
534 541

	
535 542
This group contains the algorithms for discovering the graph properties
536 543
like connectivity, bipartiteness, euler property, simplicity etc.
537 544

	
538 545
\image html connected_components.png
539 546
\image latex connected_components.eps "Connected components" width=\textwidth
540 547
*/
541 548

	
542 549
/**
543 550
@defgroup planar Planarity Embedding and Drawing
544 551
@ingroup algs
545 552
\brief Algorithms for planarity checking, embedding and drawing
546 553

	
547 554
This group contains the algorithms for planarity checking,
548 555
embedding and drawing.
549 556

	
550 557
\image html planar.png
551 558
\image latex planar.eps "Plane graph" width=\textwidth
552 559
*/
553 560

	
554 561
/**
555 562
@defgroup approx Approximation Algorithms
556 563
@ingroup algs
557 564
\brief Approximation algorithms.
558 565

	
559 566
This group contains the approximation and heuristic algorithms
560 567
implemented in LEMON.
561 568
*/
562 569

	
563 570
/**
564 571
@defgroup auxalg Auxiliary Algorithms
565 572
@ingroup algs
566 573
\brief Auxiliary algorithms implemented in LEMON.
567 574

	
568 575
This group contains some algorithms implemented in LEMON
569 576
in order to make it easier to implement complex algorithms.
570 577
*/
571 578

	
572 579
/**
573 580
@defgroup gen_opt_group General Optimization Tools
574 581
\brief This group contains some general optimization frameworks
575 582
implemented in LEMON.
576 583

	
577 584
This group contains some general optimization frameworks
578 585
implemented in LEMON.
579 586
*/
580 587

	
581 588
/**
582 589
@defgroup lp_group LP and MIP Solvers
583 590
@ingroup gen_opt_group
584 591
\brief LP and MIP solver interfaces for LEMON.
585 592

	
586 593
This group contains LP and MIP solver interfaces for LEMON.
587 594
Various LP solvers could be used in the same manner with this
588 595
high-level interface.
589 596

	
590 597
The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
591 598
\ref cplex, \ref soplex.
592 599
*/
593 600

	
594 601
/**
595 602
@defgroup lp_utils Tools for Lp and Mip Solvers
596 603
@ingroup lp_group
597 604
\brief Helper tools to the Lp and Mip solvers.
598 605

	
599 606
This group adds some helper tools to general optimization framework
600 607
implemented in LEMON.
601 608
*/
602 609

	
603 610
/**
604 611
@defgroup metah Metaheuristics
605 612
@ingroup gen_opt_group
606 613
\brief Metaheuristics for LEMON library.
607 614

	
608 615
This group contains some metaheuristic optimization tools.
609 616
*/
610 617

	
611 618
/**
612 619
@defgroup utils Tools and Utilities
613 620
\brief Tools and utilities for programming in LEMON
614 621

	
615 622
Tools and utilities for programming in LEMON.
616 623
*/
617 624

	
618 625
/**
619 626
@defgroup gutils Basic Graph Utilities
620 627
@ingroup utils
Ignore white space 192 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/CMakeLists.txt \
4 4
	lemon/config.h.cmake
5 5

	
6 6
pkgconfig_DATA += lemon/lemon.pc
7 7

	
8 8
lib_LTLIBRARIES += lemon/libemon.la
9 9

	
10 10
lemon_libemon_la_SOURCES = \
11 11
	lemon/arg_parser.cc \
12 12
	lemon/base.cc \
13 13
	lemon/color.cc \
14 14
	lemon/lp_base.cc \
15 15
	lemon/lp_skeleton.cc \
16 16
	lemon/random.cc \
17 17
	lemon/bits/windows.cc
18 18

	
19 19
nodist_lemon_HEADERS = lemon/config.h	
20 20

	
21 21
lemon_libemon_la_CXXFLAGS = \
22 22
	$(AM_CXXFLAGS) \
23 23
	$(GLPK_CFLAGS) \
24 24
	$(CPLEX_CFLAGS) \
25 25
	$(SOPLEX_CXXFLAGS) \
26 26
	$(CLP_CXXFLAGS) \
27 27
	$(CBC_CXXFLAGS)
28 28

	
29 29
lemon_libemon_la_LDFLAGS = \
30 30
	$(GLPK_LIBS) \
31 31
	$(CPLEX_LIBS) \
32 32
	$(SOPLEX_LIBS) \
33 33
	$(CLP_LIBS) \
34 34
	$(CBC_LIBS)
35 35

	
36 36
if HAVE_GLPK
37 37
lemon_libemon_la_SOURCES += lemon/glpk.cc
38 38
endif
39 39

	
40 40
if HAVE_CPLEX
41 41
lemon_libemon_la_SOURCES += lemon/cplex.cc
42 42
endif
43 43

	
44 44
if HAVE_SOPLEX
45 45
lemon_libemon_la_SOURCES += lemon/soplex.cc
46 46
endif
47 47

	
48 48
if HAVE_CLP
49 49
lemon_libemon_la_SOURCES += lemon/clp.cc
50 50
endif
51 51

	
52 52
if HAVE_CBC
53 53
lemon_libemon_la_SOURCES += lemon/cbc.cc
54 54
endif
55 55

	
56 56
lemon_HEADERS += \
57 57
	lemon/adaptors.h \
58 58
	lemon/arg_parser.h \
59 59
	lemon/assert.h \
60 60
	lemon/bellman_ford.h \
61 61
	lemon/bfs.h \
62 62
	lemon/bin_heap.h \
63 63
	lemon/binomial_heap.h \
64 64
	lemon/bucket_heap.h \
65 65
	lemon/capacity_scaling.h \
66 66
	lemon/cbc.h \
67 67
	lemon/circulation.h \
68 68
	lemon/clp.h \
69 69
	lemon/color.h \
70 70
	lemon/concept_check.h \
71 71
	lemon/connectivity.h \
72 72
	lemon/core.h \
73 73
	lemon/cost_scaling.h \
74 74
	lemon/counter.h \
75 75
	lemon/cplex.h \
76 76
	lemon/cycle_canceling.h \
77 77
	lemon/dfs.h \
78 78
	lemon/dheap.h \
79 79
	lemon/dijkstra.h \
80 80
	lemon/dim2.h \
81 81
	lemon/dimacs.h \
82 82
	lemon/edge_set.h \
83 83
	lemon/elevator.h \
84 84
	lemon/error.h \
85 85
	lemon/euler.h \
86 86
	lemon/fib_heap.h \
87
	lemon/fractional_matching.h \
87 88
	lemon/full_graph.h \
88 89
	lemon/glpk.h \
89 90
	lemon/gomory_hu.h \
90 91
	lemon/graph_to_eps.h \
91 92
	lemon/grid_graph.h \
92 93
	lemon/hartmann_orlin_mmc.h \
93 94
	lemon/howard_mmc.h \
94 95
	lemon/hypercube_graph.h \
95 96
	lemon/karp_mmc.h \
96 97
	lemon/kruskal.h \
97 98
	lemon/hao_orlin.h \
98 99
	lemon/lgf_reader.h \
99 100
	lemon/lgf_writer.h \
100 101
	lemon/list_graph.h \
101 102
	lemon/lp.h \
102 103
	lemon/lp_base.h \
103 104
	lemon/lp_skeleton.h \
104 105
	lemon/maps.h \
105 106
	lemon/matching.h \
106 107
	lemon/math.h \
107 108
	lemon/min_cost_arborescence.h \
108 109
	lemon/nauty_reader.h \
109 110
	lemon/network_simplex.h \
110 111
	lemon/pairing_heap.h \
111 112
	lemon/path.h \
112 113
	lemon/planarity.h \
113 114
	lemon/preflow.h \
114 115
	lemon/quad_heap.h \
115 116
	lemon/radix_heap.h \
116 117
	lemon/radix_sort.h \
117 118
	lemon/random.h \
118 119
	lemon/smart_graph.h \
119 120
	lemon/soplex.h \
120 121
	lemon/static_graph.h \
121 122
	lemon/suurballe.h \
122 123
	lemon/time_measure.h \
123 124
	lemon/tolerance.h \
124 125
	lemon/unionfind.h \
125 126
	lemon/bits/windows.h
126 127

	
127 128
bits_HEADERS += \
128 129
	lemon/bits/alteration_notifier.h \
129 130
	lemon/bits/array_map.h \
130 131
	lemon/bits/bezier.h \
131 132
	lemon/bits/default_map.h \
132 133
	lemon/bits/edge_set_extender.h \
133 134
	lemon/bits/enable_if.h \
134 135
	lemon/bits/graph_adaptor_extender.h \
135 136
	lemon/bits/graph_extender.h \
136 137
	lemon/bits/map_extender.h \
137 138
	lemon/bits/path_dump.h \
138 139
	lemon/bits/solver_bits.h \
139 140
	lemon/bits/traits.h \
140 141
	lemon/bits/variant.h \
141 142
	lemon/bits/vector_map.h
142 143

	
143 144
concept_HEADERS += \
144 145
	lemon/concepts/digraph.h \
145 146
	lemon/concepts/graph.h \
146 147
	lemon/concepts/graph_components.h \
147 148
	lemon/concepts/heap.h \
148 149
	lemon/concepts/maps.h \
149 150
	lemon/concepts/path.h
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19
#ifndef LEMON_MAX_MATCHING_H
20
#define LEMON_MAX_MATCHING_H
19
#ifndef LEMON_MATCHING_H
20
#define LEMON_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
#include <lemon/fractional_matching.h>
31 32

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

	
36 37
namespace lemon {
37 38

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

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

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

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

	
91 92
  private:
92 93

	
93 94
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
94 95

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

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

	
105 106
    EarMap* _ear;
106 107

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

	
111 112
    IntNodeMap* _tree_set_index;
112 113
    TreeSet* _tree_set;
113 114

	
114 115
    NodeQueue _node_queue;
115 116
    int _process, _postpone, _last;
116 117

	
117 118
    int _node_num;
118 119

	
119 120
  private:
120 121

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

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

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

	
... ...
@@ -419,1007 +420,903 @@
419 420

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

	
428 429
    ///@{
429 430

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

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

	
466 467

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

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

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

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

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

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

	
534 535

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

	
550 551
    /// @}
551 552

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

	
555 556
    /// @{
556 557

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

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

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

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

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

	
605 606
    /// @}
606 607

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

	
611 612
    /// @{
612 613

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

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

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

	
638 639
    /// @}
639 640

	
640 641
  };
641 642

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

	
696 697
    /// The graph type of the algorithm
697 698
    typedef GR Graph;
698 699
    /// The type of the edge weight map
699 700
    typedef WM WeightMap;
700 701
    /// The value type of the edge weights
701 702
    typedef typename WeightMap::Value Value;
702 703

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

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

	
714 715
  private:
715 716

	
716 717
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
717 718

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

	
721 722
    struct BlossomVariable {
722 723
      int begin, end;
723 724
      Value value;
724 725

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

	
728 729
    };
729 730

	
730 731
    typedef std::vector<BlossomVariable> BlossomPotential;
731 732

	
732 733
    const Graph& _graph;
733 734
    const WeightMap& _weight;
734 735

	
735 736
    MatchingMap* _matching;
736 737

	
737 738
    NodePotential* _node_potential;
738 739

	
739 740
    BlossomPotential _blossom_potential;
740 741
    BlossomNodeList _blossom_node_list;
741 742

	
742 743
    int _node_num;
743 744
    int _blossom_num;
744 745

	
745 746
    typedef RangeMap<int> IntIntMap;
746 747

	
747 748
    enum Status {
748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
749
      EVEN = -1, MATCHED = 0, ODD = 1
749 750
    };
750 751

	
751 752
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752 753
    struct BlossomData {
753 754
      int tree;
754 755
      Status status;
755 756
      Arc pred, next;
756 757
      Value pot, offset;
757 758
      Node base;
758 759
    };
759 760

	
760 761
    IntNodeMap *_blossom_index;
761 762
    BlossomSet *_blossom_set;
762 763
    RangeMap<BlossomData>* _blossom_data;
763 764

	
764 765
    IntNodeMap *_node_index;
765 766
    IntArcMap *_node_heap_index;
766 767

	
767 768
    struct NodeData {
768 769

	
769 770
      NodeData(IntArcMap& node_heap_index)
770 771
        : heap(node_heap_index) {}
771 772

	
772 773
      int blossom;
773 774
      Value pot;
774 775
      BinHeap<Value, IntArcMap> heap;
775 776
      std::map<int, Arc> heap_index;
776 777

	
777 778
      int tree;
778 779
    };
779 780

	
780 781
    RangeMap<NodeData>* _node_data;
781 782

	
782 783
    typedef ExtendFindEnum<IntIntMap> TreeSet;
783 784

	
784 785
    IntIntMap *_tree_set_index;
785 786
    TreeSet *_tree_set;
786 787

	
787 788
    IntNodeMap *_delta1_index;
788 789
    BinHeap<Value, IntNodeMap> *_delta1;
789 790

	
790 791
    IntIntMap *_delta2_index;
791 792
    BinHeap<Value, IntIntMap> *_delta2;
792 793

	
793 794
    IntEdgeMap *_delta3_index;
794 795
    BinHeap<Value, IntEdgeMap> *_delta3;
795 796

	
796 797
    IntIntMap *_delta4_index;
797 798
    BinHeap<Value, IntIntMap> *_delta4;
798 799

	
799 800
    Value _delta_sum;
801
    int _unmatched;
802

	
803
    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
804
    FractionalMatching *_fractional;
800 805

	
801 806
    void createStructures() {
802 807
      _node_num = countNodes(_graph);
803 808
      _blossom_num = _node_num * 3 / 2;
804 809

	
805 810
      if (!_matching) {
806 811
        _matching = new MatchingMap(_graph);
807 812
      }
808 813
      if (!_node_potential) {
809 814
        _node_potential = new NodePotential(_graph);
810 815
      }
811 816
      if (!_blossom_set) {
812 817
        _blossom_index = new IntNodeMap(_graph);
813 818
        _blossom_set = new BlossomSet(*_blossom_index);
814 819
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
815 820
      }
816 821

	
817 822
      if (!_node_index) {
818 823
        _node_index = new IntNodeMap(_graph);
819 824
        _node_heap_index = new IntArcMap(_graph);
820 825
        _node_data = new RangeMap<NodeData>(_node_num,
821 826
                                              NodeData(*_node_heap_index));
822 827
      }
823 828

	
824 829
      if (!_tree_set) {
825 830
        _tree_set_index = new IntIntMap(_blossom_num);
826 831
        _tree_set = new TreeSet(*_tree_set_index);
827 832
      }
828 833
      if (!_delta1) {
829 834
        _delta1_index = new IntNodeMap(_graph);
830 835
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
831 836
      }
832 837
      if (!_delta2) {
833 838
        _delta2_index = new IntIntMap(_blossom_num);
834 839
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
835 840
      }
836 841
      if (!_delta3) {
837 842
        _delta3_index = new IntEdgeMap(_graph);
838 843
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
839 844
      }
840 845
      if (!_delta4) {
841 846
        _delta4_index = new IntIntMap(_blossom_num);
842 847
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
843 848
      }
844 849
    }
845 850

	
846 851
    void destroyStructures() {
847
      _node_num = countNodes(_graph);
848
      _blossom_num = _node_num * 3 / 2;
849

	
850 852
      if (_matching) {
851 853
        delete _matching;
852 854
      }
853 855
      if (_node_potential) {
854 856
        delete _node_potential;
855 857
      }
856 858
      if (_blossom_set) {
857 859
        delete _blossom_index;
858 860
        delete _blossom_set;
859 861
        delete _blossom_data;
860 862
      }
861 863

	
862 864
      if (_node_index) {
863 865
        delete _node_index;
864 866
        delete _node_heap_index;
865 867
        delete _node_data;
866 868
      }
867 869

	
868 870
      if (_tree_set) {
869 871
        delete _tree_set_index;
870 872
        delete _tree_set;
871 873
      }
872 874
      if (_delta1) {
873 875
        delete _delta1_index;
874 876
        delete _delta1;
875 877
      }
876 878
      if (_delta2) {
877 879
        delete _delta2_index;
878 880
        delete _delta2;
879 881
      }
880 882
      if (_delta3) {
881 883
        delete _delta3_index;
882 884
        delete _delta3;
883 885
      }
884 886
      if (_delta4) {
885 887
        delete _delta4_index;
886 888
        delete _delta4;
887 889
      }
888 890
    }
889 891

	
890 892
    void matchedToEven(int blossom, int tree) {
891 893
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
892 894
        _delta2->erase(blossom);
893 895
      }
894 896

	
895 897
      if (!_blossom_set->trivial(blossom)) {
896 898
        (*_blossom_data)[blossom].pot -=
897 899
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
898 900
      }
899 901

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

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

	
906 908
        (*_node_data)[ni].heap.clear();
907 909
        (*_node_data)[ni].heap_index.clear();
908 910

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

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

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

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

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

	
933 931
            if (it != (*_node_data)[vi].heap_index.end()) {
934 932
              if ((*_node_data)[vi].heap[it->second] > rw) {
935 933
                (*_node_data)[vi].heap.replace(it->second, e);
936 934
                (*_node_data)[vi].heap.decrease(e, rw);
937 935
                it->second = e;
938 936
              }
939 937
            } else {
940 938
              (*_node_data)[vi].heap.push(e, rw);
941 939
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
942 940
            }
943 941

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

	
947 945
              if ((*_blossom_data)[vb].status == MATCHED) {
948 946
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
949 947
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
950 948
                               (*_blossom_data)[vb].offset);
951 949
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
952
                           (*_blossom_data)[vb].offset){
953
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
954
                                   (*_blossom_data)[vb].offset);
955
                }
956
              }
957
            }
958
          }
959
        }
960
      }
961
      (*_blossom_data)[blossom].offset = 0;
962
    }
963

	
964
    void matchedToOdd(int blossom) {
965
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
966
        _delta2->erase(blossom);
967
      }
968
      (*_blossom_data)[blossom].offset += _delta_sum;
969
      if (!_blossom_set->trivial(blossom)) {
970
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
971
                     (*_blossom_data)[blossom].offset);
972
      }
973
    }
974

	
975
    void evenToMatched(int blossom, int tree) {
976
      if (!_blossom_set->trivial(blossom)) {
977
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
978
      }
979

	
980
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
981
           n != INVALID; ++n) {
982
        int ni = (*_node_index)[n];
983
        (*_node_data)[ni].pot -= _delta_sum;
984

	
985
        _delta1->erase(n);
986

	
987
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
988
          Node v = _graph.source(e);
989
          int vb = _blossom_set->find(v);
990
          int vi = (*_node_index)[v];
991

	
992
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
993
            dualScale * _weight[e];
994

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

	
1001
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1002
              _delta3->erase(e);
1003
            }
1004

	
1005
            int vt = _tree_set->find(vb);
1006

	
1007
            if (vt != tree) {
1008

	
1009
              Arc r = _graph.oppositeArc(e);
1010

	
1011
              typename std::map<int, Arc>::iterator it =
1012
                (*_node_data)[ni].heap_index.find(vt);
1013

	
1014
              if (it != (*_node_data)[ni].heap_index.end()) {
1015
                if ((*_node_data)[ni].heap[it->second] > rw) {
1016
                  (*_node_data)[ni].heap.replace(it->second, r);
1017
                  (*_node_data)[ni].heap.decrease(r, rw);
1018
                  it->second = r;
1019
                }
1020
              } else {
1021
                (*_node_data)[ni].heap.push(r, rw);
1022
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1023
              }
1024

	
1025
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1026
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1027

	
1028
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1029
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1030
                               (*_blossom_data)[blossom].offset);
1031
                } else if ((*_delta2)[blossom] >
1032
                           _blossom_set->classPrio(blossom) -
1033
                           (*_blossom_data)[blossom].offset){
1034
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1035
                                   (*_blossom_data)[blossom].offset);
1036
                }
1037
              }
1038
            }
1039

	
1040
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1041
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1042
              _delta3->erase(e);
1043
            }
1044
          } else {
1045

	
1046
            typename std::map<int, Arc>::iterator it =
1047
              (*_node_data)[vi].heap_index.find(tree);
1048

	
1049
            if (it != (*_node_data)[vi].heap_index.end()) {
1050
              (*_node_data)[vi].heap.erase(it->second);
1051
              (*_node_data)[vi].heap_index.erase(it);
1052
              if ((*_node_data)[vi].heap.empty()) {
1053
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1054
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1055
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1056
              }
1057

	
1058
              if ((*_blossom_data)[vb].status == MATCHED) {
1059
                if (_blossom_set->classPrio(vb) ==
1060
                    std::numeric_limits<Value>::max()) {
1061
                  _delta2->erase(vb);
1062
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1063
                           (*_blossom_data)[vb].offset) {
1064
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1065
                                   (*_blossom_data)[vb].offset);
1066
                }
1067
              }
1068
            }
1069
          }
1070
        }
1071
      }
1072
    }
1073

	
1074
    void oddToMatched(int blossom) {
1075
      (*_blossom_data)[blossom].offset -= _delta_sum;
1076

	
1077
      if (_blossom_set->classPrio(blossom) !=
1078
          std::numeric_limits<Value>::max()) {
1079
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1080
                       (*_blossom_data)[blossom].offset);
1081
      }
1082

	
1083
      if (!_blossom_set->trivial(blossom)) {
1084
        _delta4->erase(blossom);
1085
      }
1086
    }
1087

	
1088
    void oddToEven(int blossom, int tree) {
1089
      if (!_blossom_set->trivial(blossom)) {
1090
        _delta4->erase(blossom);
1091
        (*_blossom_data)[blossom].pot -=
1092
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1093
      }
1094

	
1095
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1096
           n != INVALID; ++n) {
1097
        int ni = (*_node_index)[n];
1098

	
1099
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1100

	
1101
        (*_node_data)[ni].heap.clear();
1102
        (*_node_data)[ni].heap_index.clear();
1103
        (*_node_data)[ni].pot +=
1104
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1105

	
1106
        _delta1->push(n, (*_node_data)[ni].pot);
1107

	
1108
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1109
          Node v = _graph.source(e);
1110
          int vb = _blossom_set->find(v);
1111
          int vi = (*_node_index)[v];
1112

	
1113
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1114
            dualScale * _weight[e];
1115

	
1116
          if ((*_blossom_data)[vb].status == EVEN) {
1117
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1118
              _delta3->push(e, rw / 2);
1119
            }
1120
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1121
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1122
              _delta3->push(e, rw);
1123
            }
1124
          } else {
1125

	
1126
            typename std::map<int, Arc>::iterator it =
1127
              (*_node_data)[vi].heap_index.find(tree);
1128

	
1129
            if (it != (*_node_data)[vi].heap_index.end()) {
1130
              if ((*_node_data)[vi].heap[it->second] > rw) {
1131
                (*_node_data)[vi].heap.replace(it->second, e);
1132
                (*_node_data)[vi].heap.decrease(e, rw);
1133
                it->second = e;
1134
              }
1135
            } else {
1136
              (*_node_data)[vi].heap.push(e, rw);
1137
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1138
            }
1139

	
1140
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1141
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1142

	
1143
              if ((*_blossom_data)[vb].status == MATCHED) {
1144
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1145
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1146
                               (*_blossom_data)[vb].offset);
1147
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1148 950
                           (*_blossom_data)[vb].offset) {
1149 951
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1150 952
                                   (*_blossom_data)[vb].offset);
1151 953
                }
1152 954
              }
1153 955
            }
1154 956
          }
1155 957
        }
1156 958
      }
1157 959
      (*_blossom_data)[blossom].offset = 0;
1158 960
    }
1159 961

	
1160

	
1161
    void matchedToUnmatched(int blossom) {
962
    void matchedToOdd(int blossom) {
1162 963
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1163 964
        _delta2->erase(blossom);
1164 965
      }
966
      (*_blossom_data)[blossom].offset += _delta_sum;
967
      if (!_blossom_set->trivial(blossom)) {
968
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
969
                      (*_blossom_data)[blossom].offset);
970
      }
971
    }
972

	
973
    void evenToMatched(int blossom, int tree) {
974
      if (!_blossom_set->trivial(blossom)) {
975
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
976
      }
1165 977

	
1166 978
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1167 979
           n != INVALID; ++n) {
1168 980
        int ni = (*_node_index)[n];
1169

	
1170
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1171

	
1172
        (*_node_data)[ni].heap.clear();
1173
        (*_node_data)[ni].heap_index.clear();
1174

	
1175
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1176
          Node v = _graph.target(e);
981
        (*_node_data)[ni].pot -= _delta_sum;
982

	
983
        _delta1->erase(n);
984

	
985
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
986
          Node v = _graph.source(e);
1177 987
          int vb = _blossom_set->find(v);
1178 988
          int vi = (*_node_index)[v];
1179 989

	
1180 990
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1181 991
            dualScale * _weight[e];
1182 992

	
1183
          if ((*_blossom_data)[vb].status == EVEN) {
1184
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1185
              _delta3->push(e, rw);
993
          if (vb == blossom) {
994
            if (_delta3->state(e) == _delta3->IN_HEAP) {
995
              _delta3->erase(e);
996
            }
997
          } else if ((*_blossom_data)[vb].status == EVEN) {
998

	
999
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1000
              _delta3->erase(e);
1001
            }
1002

	
1003
            int vt = _tree_set->find(vb);
1004

	
1005
            if (vt != tree) {
1006

	
1007
              Arc r = _graph.oppositeArc(e);
1008

	
1009
              typename std::map<int, Arc>::iterator it =
1010
                (*_node_data)[ni].heap_index.find(vt);
1011

	
1012
              if (it != (*_node_data)[ni].heap_index.end()) {
1013
                if ((*_node_data)[ni].heap[it->second] > rw) {
1014
                  (*_node_data)[ni].heap.replace(it->second, r);
1015
                  (*_node_data)[ni].heap.decrease(r, rw);
1016
                  it->second = r;
1017
                }
1018
              } else {
1019
                (*_node_data)[ni].heap.push(r, rw);
1020
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1021
              }
1022

	
1023
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1024
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1025

	
1026
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1027
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1028
                               (*_blossom_data)[blossom].offset);
1029
                } else if ((*_delta2)[blossom] >
1030
                           _blossom_set->classPrio(blossom) -
1031
                           (*_blossom_data)[blossom].offset){
1032
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1033
                                   (*_blossom_data)[blossom].offset);
1034
                }
1035
              }
1036
            }
1037
          } else {
1038

	
1039
            typename std::map<int, Arc>::iterator it =
1040
              (*_node_data)[vi].heap_index.find(tree);
1041

	
1042
            if (it != (*_node_data)[vi].heap_index.end()) {
1043
              (*_node_data)[vi].heap.erase(it->second);
1044
              (*_node_data)[vi].heap_index.erase(it);
1045
              if ((*_node_data)[vi].heap.empty()) {
1046
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1047
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1048
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1049
              }
1050

	
1051
              if ((*_blossom_data)[vb].status == MATCHED) {
1052
                if (_blossom_set->classPrio(vb) ==
1053
                    std::numeric_limits<Value>::max()) {
1054
                  _delta2->erase(vb);
1055
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1056
                           (*_blossom_data)[vb].offset) {
1057
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1058
                                   (*_blossom_data)[vb].offset);
1059
                }
1060
              }
1186 1061
            }
1187 1062
          }
1188 1063
        }
1189 1064
      }
1190 1065
    }
1191 1066

	
1192
    void unmatchedToMatched(int blossom) {
1067
    void oddToMatched(int blossom) {
1068
      (*_blossom_data)[blossom].offset -= _delta_sum;
1069

	
1070
      if (_blossom_set->classPrio(blossom) !=
1071
          std::numeric_limits<Value>::max()) {
1072
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1073
                      (*_blossom_data)[blossom].offset);
1074
      }
1075

	
1076
      if (!_blossom_set->trivial(blossom)) {
1077
        _delta4->erase(blossom);
1078
      }
1079
    }
1080

	
1081
    void oddToEven(int blossom, int tree) {
1082
      if (!_blossom_set->trivial(blossom)) {
1083
        _delta4->erase(blossom);
1084
        (*_blossom_data)[blossom].pot -=
1085
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1086
      }
1087

	
1193 1088
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1194 1089
           n != INVALID; ++n) {
1195 1090
        int ni = (*_node_index)[n];
1196 1091

	
1092
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1093

	
1094
        (*_node_data)[ni].heap.clear();
1095
        (*_node_data)[ni].heap_index.clear();
1096
        (*_node_data)[ni].pot +=
1097
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1098

	
1099
        _delta1->push(n, (*_node_data)[ni].pot);
1100

	
1197 1101
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1198 1102
          Node v = _graph.source(e);
1199 1103
          int vb = _blossom_set->find(v);
1200 1104
          int vi = (*_node_index)[v];
1201 1105

	
1202 1106
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1203 1107
            dualScale * _weight[e];
1204 1108

	
1205
          if (vb == blossom) {
1206
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1207
              _delta3->erase(e);
1109
          if ((*_blossom_data)[vb].status == EVEN) {
1110
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1111
              _delta3->push(e, rw / 2);
1208 1112
            }
1209
          } else if ((*_blossom_data)[vb].status == EVEN) {
1210

	
1211
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1212
              _delta3->erase(e);
1213
            }
1214

	
1215
            int vt = _tree_set->find(vb);
1216

	
1217
            Arc r = _graph.oppositeArc(e);
1113
          } else {
1218 1114

	
1219 1115
            typename std::map<int, Arc>::iterator it =
1220
              (*_node_data)[ni].heap_index.find(vt);
1221

	
1222
            if (it != (*_node_data)[ni].heap_index.end()) {
1223
              if ((*_node_data)[ni].heap[it->second] > rw) {
1224
                (*_node_data)[ni].heap.replace(it->second, r);
1225
                (*_node_data)[ni].heap.decrease(r, rw);
1226
                it->second = r;
1116
              (*_node_data)[vi].heap_index.find(tree);
1117

	
1118
            if (it != (*_node_data)[vi].heap_index.end()) {
1119
              if ((*_node_data)[vi].heap[it->second] > rw) {
1120
                (*_node_data)[vi].heap.replace(it->second, e);
1121
                (*_node_data)[vi].heap.decrease(e, rw);
1122
                it->second = e;
1227 1123
              }
1228 1124
            } else {
1229
              (*_node_data)[ni].heap.push(r, rw);
1230
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1125
              (*_node_data)[vi].heap.push(e, rw);
1126
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1231 1127
            }
1232 1128

	
1233
            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1234
              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1235

	
1236
              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1237
                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1238
                             (*_blossom_data)[blossom].offset);
1239
              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
1240
                         (*_blossom_data)[blossom].offset){
1241
                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1242
                                 (*_blossom_data)[blossom].offset);
1129
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1130
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1131

	
1132
              if ((*_blossom_data)[vb].status == MATCHED) {
1133
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1134
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1135
                               (*_blossom_data)[vb].offset);
1136
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1137
                           (*_blossom_data)[vb].offset) {
1138
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1139
                                   (*_blossom_data)[vb].offset);
1140
                }
1243 1141
              }
1244 1142
            }
1245

	
1246
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1247
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1248
              _delta3->erase(e);
1249
            }
1250 1143
          }
1251 1144
        }
1252 1145
      }
1146
      (*_blossom_data)[blossom].offset = 0;
1253 1147
    }
1254 1148

	
1255 1149
    void alternatePath(int even, int tree) {
1256 1150
      int odd;
1257 1151

	
1258 1152
      evenToMatched(even, tree);
1259 1153
      (*_blossom_data)[even].status = MATCHED;
1260 1154

	
1261 1155
      while ((*_blossom_data)[even].pred != INVALID) {
1262 1156
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
1263 1157
        (*_blossom_data)[odd].status = MATCHED;
1264 1158
        oddToMatched(odd);
1265 1159
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
1266 1160

	
1267 1161
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
1268 1162
        (*_blossom_data)[even].status = MATCHED;
1269 1163
        evenToMatched(even, tree);
1270 1164
        (*_blossom_data)[even].next =
1271 1165
          _graph.oppositeArc((*_blossom_data)[odd].pred);
1272 1166
      }
1273 1167

	
1274 1168
    }
1275 1169

	
1276 1170
    void destroyTree(int tree) {
1277 1171
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
1278 1172
        if ((*_blossom_data)[b].status == EVEN) {
1279 1173
          (*_blossom_data)[b].status = MATCHED;
1280 1174
          evenToMatched(b, tree);
1281 1175
        } else if ((*_blossom_data)[b].status == ODD) {
1282 1176
          (*_blossom_data)[b].status = MATCHED;
1283 1177
          oddToMatched(b);
1284 1178
        }
1285 1179
      }
1286 1180
      _tree_set->eraseClass(tree);
1287 1181
    }
1288 1182

	
1289 1183

	
1290 1184
    void unmatchNode(const Node& node) {
1291 1185
      int blossom = _blossom_set->find(node);
1292 1186
      int tree = _tree_set->find(blossom);
1293 1187

	
1294 1188
      alternatePath(blossom, tree);
1295 1189
      destroyTree(tree);
1296 1190

	
1297
      (*_blossom_data)[blossom].status = UNMATCHED;
1298 1191
      (*_blossom_data)[blossom].base = node;
1299
      matchedToUnmatched(blossom);
1192
      (*_blossom_data)[blossom].next = INVALID;
1300 1193
    }
1301 1194

	
1302

	
1303 1195
    void augmentOnEdge(const Edge& edge) {
1304 1196

	
1305 1197
      int left = _blossom_set->find(_graph.u(edge));
1306 1198
      int right = _blossom_set->find(_graph.v(edge));
1307 1199

	
1308
      if ((*_blossom_data)[left].status == EVEN) {
1309
        int left_tree = _tree_set->find(left);
1310
        alternatePath(left, left_tree);
1311
        destroyTree(left_tree);
1312
      } else {
1313
        (*_blossom_data)[left].status = MATCHED;
1314
        unmatchedToMatched(left);
1315
      }
1316

	
1317
      if ((*_blossom_data)[right].status == EVEN) {
1318
        int right_tree = _tree_set->find(right);
1319
        alternatePath(right, right_tree);
1320
        destroyTree(right_tree);
1321
      } else {
1322
        (*_blossom_data)[right].status = MATCHED;
1323
        unmatchedToMatched(right);
1324
      }
1200
      int left_tree = _tree_set->find(left);
1201
      alternatePath(left, left_tree);
1202
      destroyTree(left_tree);
1203

	
1204
      int right_tree = _tree_set->find(right);
1205
      alternatePath(right, right_tree);
1206
      destroyTree(right_tree);
1325 1207

	
1326 1208
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1327 1209
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1328 1210
    }
1329 1211

	
1212
    void augmentOnArc(const Arc& arc) {
1213

	
1214
      int left = _blossom_set->find(_graph.source(arc));
1215
      int right = _blossom_set->find(_graph.target(arc));
1216

	
1217
      (*_blossom_data)[left].status = MATCHED;
1218

	
1219
      int right_tree = _tree_set->find(right);
1220
      alternatePath(right, right_tree);
1221
      destroyTree(right_tree);
1222

	
1223
      (*_blossom_data)[left].next = arc;
1224
      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
1225
    }
1226

	
1330 1227
    void extendOnArc(const Arc& arc) {
1331 1228
      int base = _blossom_set->find(_graph.target(arc));
1332 1229
      int tree = _tree_set->find(base);
1333 1230

	
1334 1231
      int odd = _blossom_set->find(_graph.source(arc));
1335 1232
      _tree_set->insert(odd, tree);
1336 1233
      (*_blossom_data)[odd].status = ODD;
1337 1234
      matchedToOdd(odd);
1338 1235
      (*_blossom_data)[odd].pred = arc;
1339 1236

	
1340 1237
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1341 1238
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
1342 1239
      _tree_set->insert(even, tree);
1343 1240
      (*_blossom_data)[even].status = EVEN;
1344 1241
      matchedToEven(even, tree);
1345 1242
    }
1346 1243

	
1347 1244
    void shrinkOnEdge(const Edge& edge, int tree) {
1348 1245
      int nca = -1;
1349 1246
      std::vector<int> left_path, right_path;
1350 1247

	
1351 1248
      {
1352 1249
        std::set<int> left_set, right_set;
1353 1250
        int left = _blossom_set->find(_graph.u(edge));
1354 1251
        left_path.push_back(left);
1355 1252
        left_set.insert(left);
1356 1253

	
1357 1254
        int right = _blossom_set->find(_graph.v(edge));
1358 1255
        right_path.push_back(right);
1359 1256
        right_set.insert(right);
1360 1257

	
1361 1258
        while (true) {
1362 1259

	
1363 1260
          if ((*_blossom_data)[left].pred == INVALID) break;
1364 1261

	
1365 1262
          left =
1366 1263
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1367 1264
          left_path.push_back(left);
1368 1265
          left =
1369 1266
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1370 1267
          left_path.push_back(left);
1371 1268

	
1372 1269
          left_set.insert(left);
1373 1270

	
1374 1271
          if (right_set.find(left) != right_set.end()) {
1375 1272
            nca = left;
1376 1273
            break;
1377 1274
          }
1378 1275

	
1379 1276
          if ((*_blossom_data)[right].pred == INVALID) break;
1380 1277

	
1381 1278
          right =
1382 1279
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1383 1280
          right_path.push_back(right);
1384 1281
          right =
1385 1282
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1386 1283
          right_path.push_back(right);
1387 1284

	
1388 1285
          right_set.insert(right);
1389 1286

	
1390 1287
          if (left_set.find(right) != left_set.end()) {
1391 1288
            nca = right;
1392 1289
            break;
1393 1290
          }
1394 1291

	
1395 1292
        }
1396 1293

	
1397 1294
        if (nca == -1) {
1398 1295
          if ((*_blossom_data)[left].pred == INVALID) {
1399 1296
            nca = right;
1400 1297
            while (left_set.find(nca) == left_set.end()) {
1401 1298
              nca =
1402 1299
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1403 1300
              right_path.push_back(nca);
1404 1301
              nca =
1405 1302
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1406 1303
              right_path.push_back(nca);
1407 1304
            }
1408 1305
          } else {
1409 1306
            nca = left;
1410 1307
            while (right_set.find(nca) == right_set.end()) {
1411 1308
              nca =
1412 1309
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1413 1310
              left_path.push_back(nca);
1414 1311
              nca =
1415 1312
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1416 1313
              left_path.push_back(nca);
1417 1314
            }
1418 1315
          }
1419 1316
        }
1420 1317
      }
1421 1318

	
1422 1319
      std::vector<int> subblossoms;
1423 1320
      Arc prev;
1424 1321

	
1425 1322
      prev = _graph.direct(edge, true);
... ...
@@ -1436,899 +1333,1038 @@
1436 1333
      }
1437 1334

	
1438 1335
      int k = 0;
1439 1336
      while (right_path[k] != nca) ++k;
1440 1337

	
1441 1338
      subblossoms.push_back(nca);
1442 1339
      (*_blossom_data)[nca].next = prev;
1443 1340

	
1444 1341
      for (int i = k - 2; i >= 0; i -= 2) {
1445 1342
        subblossoms.push_back(right_path[i + 1]);
1446 1343
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
1447 1344
        oddToEven(right_path[i + 1], tree);
1448 1345
        _tree_set->erase(right_path[i + 1]);
1449 1346

	
1450 1347
        (*_blossom_data)[right_path[i + 1]].next =
1451 1348
          (*_blossom_data)[right_path[i + 1]].pred;
1452 1349

	
1453 1350
        subblossoms.push_back(right_path[i]);
1454 1351
        _tree_set->erase(right_path[i]);
1455 1352
      }
1456 1353

	
1457 1354
      int surface =
1458 1355
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
1459 1356

	
1460 1357
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1461 1358
        if (!_blossom_set->trivial(subblossoms[i])) {
1462 1359
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
1463 1360
        }
1464 1361
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
1465 1362
      }
1466 1363

	
1467 1364
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
1468 1365
      (*_blossom_data)[surface].offset = 0;
1469 1366
      (*_blossom_data)[surface].status = EVEN;
1470 1367
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
1471 1368
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
1472 1369

	
1473 1370
      _tree_set->insert(surface, tree);
1474 1371
      _tree_set->erase(nca);
1475 1372
    }
1476 1373

	
1477 1374
    void splitBlossom(int blossom) {
1478 1375
      Arc next = (*_blossom_data)[blossom].next;
1479 1376
      Arc pred = (*_blossom_data)[blossom].pred;
1480 1377

	
1481 1378
      int tree = _tree_set->find(blossom);
1482 1379

	
1483 1380
      (*_blossom_data)[blossom].status = MATCHED;
1484 1381
      oddToMatched(blossom);
1485 1382
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1486 1383
        _delta2->erase(blossom);
1487 1384
      }
1488 1385

	
1489 1386
      std::vector<int> subblossoms;
1490 1387
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
1491 1388

	
1492 1389
      Value offset = (*_blossom_data)[blossom].offset;
1493 1390
      int b = _blossom_set->find(_graph.source(pred));
1494 1391
      int d = _blossom_set->find(_graph.source(next));
1495 1392

	
1496 1393
      int ib = -1, id = -1;
1497 1394
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1498 1395
        if (subblossoms[i] == b) ib = i;
1499 1396
        if (subblossoms[i] == d) id = i;
1500 1397

	
1501 1398
        (*_blossom_data)[subblossoms[i]].offset = offset;
1502 1399
        if (!_blossom_set->trivial(subblossoms[i])) {
1503 1400
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
1504 1401
        }
1505 1402
        if (_blossom_set->classPrio(subblossoms[i]) !=
1506 1403
            std::numeric_limits<Value>::max()) {
1507 1404
          _delta2->push(subblossoms[i],
1508 1405
                        _blossom_set->classPrio(subblossoms[i]) -
1509 1406
                        (*_blossom_data)[subblossoms[i]].offset);
1510 1407
        }
1511 1408
      }
1512 1409

	
1513 1410
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1514 1411
        for (int i = (id + 1) % subblossoms.size();
1515 1412
             i != ib; i = (i + 2) % subblossoms.size()) {
1516 1413
          int sb = subblossoms[i];
1517 1414
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1518 1415
          (*_blossom_data)[sb].next =
1519 1416
            _graph.oppositeArc((*_blossom_data)[tb].next);
1520 1417
        }
1521 1418

	
1522 1419
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1523 1420
          int sb = subblossoms[i];
1524 1421
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1525 1422
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1526 1423

	
1527 1424
          (*_blossom_data)[sb].status = ODD;
1528 1425
          matchedToOdd(sb);
1529 1426
          _tree_set->insert(sb, tree);
1530 1427
          (*_blossom_data)[sb].pred = pred;
1531 1428
          (*_blossom_data)[sb].next =
1532
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1429
            _graph.oppositeArc((*_blossom_data)[tb].next);
1533 1430

	
1534 1431
          pred = (*_blossom_data)[ub].next;
1535 1432

	
1536 1433
          (*_blossom_data)[tb].status = EVEN;
1537 1434
          matchedToEven(tb, tree);
1538 1435
          _tree_set->insert(tb, tree);
1539 1436
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1540 1437
        }
1541 1438

	
1542 1439
        (*_blossom_data)[subblossoms[id]].status = ODD;
1543 1440
        matchedToOdd(subblossoms[id]);
1544 1441
        _tree_set->insert(subblossoms[id], tree);
1545 1442
        (*_blossom_data)[subblossoms[id]].next = next;
1546 1443
        (*_blossom_data)[subblossoms[id]].pred = pred;
1547 1444

	
1548 1445
      } else {
1549 1446

	
1550 1447
        for (int i = (ib + 1) % subblossoms.size();
1551 1448
             i != id; i = (i + 2) % subblossoms.size()) {
1552 1449
          int sb = subblossoms[i];
1553 1450
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1554 1451
          (*_blossom_data)[sb].next =
1555 1452
            _graph.oppositeArc((*_blossom_data)[tb].next);
1556 1453
        }
1557 1454

	
1558 1455
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
1559 1456
          int sb = subblossoms[i];
1560 1457
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1561 1458
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1562 1459

	
1563 1460
          (*_blossom_data)[sb].status = ODD;
1564 1461
          matchedToOdd(sb);
1565 1462
          _tree_set->insert(sb, tree);
1566 1463
          (*_blossom_data)[sb].next = next;
1567 1464
          (*_blossom_data)[sb].pred =
1568 1465
            _graph.oppositeArc((*_blossom_data)[tb].next);
1569 1466

	
1570 1467
          (*_blossom_data)[tb].status = EVEN;
1571 1468
          matchedToEven(tb, tree);
1572 1469
          _tree_set->insert(tb, tree);
1573 1470
          (*_blossom_data)[tb].pred =
1574 1471
            (*_blossom_data)[tb].next =
1575 1472
            _graph.oppositeArc((*_blossom_data)[ub].next);
1576 1473
          next = (*_blossom_data)[ub].next;
1577 1474
        }
1578 1475

	
1579 1476
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1580 1477
        matchedToOdd(subblossoms[ib]);
1581 1478
        _tree_set->insert(subblossoms[ib], tree);
1582 1479
        (*_blossom_data)[subblossoms[ib]].next = next;
1583 1480
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1584 1481
      }
1585 1482
      _tree_set->erase(blossom);
1586 1483
    }
1587 1484

	
1588 1485
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1589 1486
      if (_blossom_set->trivial(blossom)) {
1590 1487
        int bi = (*_node_index)[base];
1591 1488
        Value pot = (*_node_data)[bi].pot;
1592 1489

	
1593 1490
        (*_matching)[base] = matching;
1594 1491
        _blossom_node_list.push_back(base);
1595 1492
        (*_node_potential)[base] = pot;
1596 1493
      } else {
1597 1494

	
1598 1495
        Value pot = (*_blossom_data)[blossom].pot;
1599 1496
        int bn = _blossom_node_list.size();
1600 1497

	
1601 1498
        std::vector<int> subblossoms;
1602 1499
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1603 1500
        int b = _blossom_set->find(base);
1604 1501
        int ib = -1;
1605 1502
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1606 1503
          if (subblossoms[i] == b) { ib = i; break; }
1607 1504
        }
1608 1505

	
1609 1506
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1610 1507
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1611 1508
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1612 1509

	
1613 1510
          Arc m = (*_blossom_data)[tb].next;
1614 1511
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1615 1512
          extractBlossom(tb, _graph.source(m), m);
1616 1513
        }
1617 1514
        extractBlossom(subblossoms[ib], base, matching);
1618 1515

	
1619 1516
        int en = _blossom_node_list.size();
1620 1517

	
1621 1518
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1622 1519
      }
1623 1520
    }
1624 1521

	
1625 1522
    void extractMatching() {
1626 1523
      std::vector<int> blossoms;
1627 1524
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1628 1525
        blossoms.push_back(c);
1629 1526
      }
1630 1527

	
1631 1528
      for (int i = 0; i < int(blossoms.size()); ++i) {
1632
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1529
        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
1633 1530

	
1634 1531
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1635 1532
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1636 1533
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1637 1534
               n != INVALID; ++n) {
1638 1535
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1639 1536
          }
1640 1537

	
1641 1538
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1642 1539
          Node base = _graph.source(matching);
1643 1540
          extractBlossom(blossoms[i], base, matching);
1644 1541
        } else {
1645 1542
          Node base = (*_blossom_data)[blossoms[i]].base;
1646 1543
          extractBlossom(blossoms[i], base, INVALID);
1647 1544
        }
1648 1545
      }
1649 1546
    }
1650 1547

	
1651 1548
  public:
1652 1549

	
1653 1550
    /// \brief Constructor
1654 1551
    ///
1655 1552
    /// Constructor.
1656 1553
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1657 1554
      : _graph(graph), _weight(weight), _matching(0),
1658 1555
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1659 1556
        _node_num(0), _blossom_num(0),
1660 1557

	
1661 1558
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1662 1559
        _node_index(0), _node_heap_index(0), _node_data(0),
1663 1560
        _tree_set_index(0), _tree_set(0),
1664 1561

	
1665 1562
        _delta1_index(0), _delta1(0),
1666 1563
        _delta2_index(0), _delta2(0),
1667 1564
        _delta3_index(0), _delta3(0),
1668 1565
        _delta4_index(0), _delta4(0),
1669 1566

	
1670
        _delta_sum() {}
1567
        _delta_sum(), _unmatched(0),
1568

	
1569
        _fractional(0)
1570
    {}
1671 1571

	
1672 1572
    ~MaxWeightedMatching() {
1673 1573
      destroyStructures();
1574
      if (_fractional) {
1575
        delete _fractional;
1576
      }
1674 1577
    }
1675 1578

	
1676 1579
    /// \name Execution Control
1677 1580
    /// The simplest way to execute the algorithm is to use the
1678 1581
    /// \ref run() member function.
1679 1582

	
1680 1583
    ///@{
1681 1584

	
1682 1585
    /// \brief Initialize the algorithm
1683 1586
    ///
1684 1587
    /// This function initializes the algorithm.
1685 1588
    void init() {
1686 1589
      createStructures();
1687 1590

	
1688 1591
      for (ArcIt e(_graph); e != INVALID; ++e) {
1689 1592
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1690 1593
      }
1691 1594
      for (NodeIt n(_graph); n != INVALID; ++n) {
1692 1595
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1693 1596
      }
1694 1597
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1695 1598
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1696 1599
      }
1697 1600
      for (int i = 0; i < _blossom_num; ++i) {
1698 1601
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1699 1602
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1700 1603
      }
1701 1604

	
1605
      _unmatched = _node_num;
1606

	
1702 1607
      int index = 0;
1703 1608
      for (NodeIt n(_graph); n != INVALID; ++n) {
1704 1609
        Value max = 0;
1705 1610
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1706 1611
          if (_graph.target(e) == n) continue;
1707 1612
          if ((dualScale * _weight[e]) / 2 > max) {
1708 1613
            max = (dualScale * _weight[e]) / 2;
1709 1614
          }
1710 1615
        }
1711 1616
        (*_node_index)[n] = index;
1712 1617
        (*_node_data)[index].pot = max;
1713 1618
        _delta1->push(n, max);
1714 1619
        int blossom =
1715 1620
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1716 1621

	
1717 1622
        _tree_set->insert(blossom);
1718 1623

	
1719 1624
        (*_blossom_data)[blossom].status = EVEN;
1720 1625
        (*_blossom_data)[blossom].pred = INVALID;
1721 1626
        (*_blossom_data)[blossom].next = INVALID;
1722 1627
        (*_blossom_data)[blossom].pot = 0;
1723 1628
        (*_blossom_data)[blossom].offset = 0;
1724 1629
        ++index;
1725 1630
      }
1726 1631
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1727 1632
        int si = (*_node_index)[_graph.u(e)];
1728 1633
        int ti = (*_node_index)[_graph.v(e)];
1729 1634
        if (_graph.u(e) != _graph.v(e)) {
1730 1635
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1731 1636
                            dualScale * _weight[e]) / 2);
1732 1637
        }
1733 1638
      }
1734 1639
    }
1735 1640

	
1641
    /// \brief Initialize the algorithm with fractional matching
1642
    ///
1643
    /// This function initializes the algorithm with a fractional
1644
    /// matching. This initialization is also called jumpstart heuristic.
1645
    void fractionalInit() {
1646
      createStructures();
1647
      
1648
      if (_fractional == 0) {
1649
        _fractional = new FractionalMatching(_graph, _weight, false);
1650
      }
1651
      _fractional->run();
1652

	
1653
      for (ArcIt e(_graph); e != INVALID; ++e) {
1654
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1655
      }
1656
      for (NodeIt n(_graph); n != INVALID; ++n) {
1657
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1658
      }
1659
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1660
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1661
      }
1662
      for (int i = 0; i < _blossom_num; ++i) {
1663
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1664
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1665
      }
1666

	
1667
      _unmatched = 0;
1668

	
1669
      int index = 0;
1670
      for (NodeIt n(_graph); n != INVALID; ++n) {
1671
        Value pot = _fractional->nodeValue(n);
1672
        (*_node_index)[n] = index;
1673
        (*_node_data)[index].pot = pot;
1674
        int blossom =
1675
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1676

	
1677
        (*_blossom_data)[blossom].status = MATCHED;
1678
        (*_blossom_data)[blossom].pred = INVALID;
1679
        (*_blossom_data)[blossom].next = _fractional->matching(n);
1680
        if (_fractional->matching(n) == INVALID) {
1681
          (*_blossom_data)[blossom].base = n;
1682
        }
1683
        (*_blossom_data)[blossom].pot = 0;
1684
        (*_blossom_data)[blossom].offset = 0;
1685
        ++index;
1686
      }
1687

	
1688
      typename Graph::template NodeMap<bool> processed(_graph, false);
1689
      for (NodeIt n(_graph); n != INVALID; ++n) {
1690
        if (processed[n]) continue;
1691
        processed[n] = true;
1692
        if (_fractional->matching(n) == INVALID) continue;
1693
        int num = 1;
1694
        Node v = _graph.target(_fractional->matching(n));
1695
        while (n != v) {
1696
          processed[v] = true;
1697
          v = _graph.target(_fractional->matching(v));
1698
          ++num;
1699
        }
1700

	
1701
        if (num % 2 == 1) {
1702
          std::vector<int> subblossoms(num);
1703

	
1704
          subblossoms[--num] = _blossom_set->find(n);
1705
          _delta1->push(n, _fractional->nodeValue(n));
1706
          v = _graph.target(_fractional->matching(n));
1707
          while (n != v) {
1708
            subblossoms[--num] = _blossom_set->find(v);
1709
            _delta1->push(v, _fractional->nodeValue(v));
1710
            v = _graph.target(_fractional->matching(v));            
1711
          }
1712
          
1713
          int surface = 
1714
            _blossom_set->join(subblossoms.begin(), subblossoms.end());
1715
          (*_blossom_data)[surface].status = EVEN;
1716
          (*_blossom_data)[surface].pred = INVALID;
1717
          (*_blossom_data)[surface].next = INVALID;
1718
          (*_blossom_data)[surface].pot = 0;
1719
          (*_blossom_data)[surface].offset = 0;
1720
          
1721
          _tree_set->insert(surface);
1722
          ++_unmatched;
1723
        }
1724
      }
1725

	
1726
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1727
        int si = (*_node_index)[_graph.u(e)];
1728
        int sb = _blossom_set->find(_graph.u(e));
1729
        int ti = (*_node_index)[_graph.v(e)];
1730
        int tb = _blossom_set->find(_graph.v(e));
1731
        if ((*_blossom_data)[sb].status == EVEN &&
1732
            (*_blossom_data)[tb].status == EVEN && sb != tb) {
1733
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1734
                            dualScale * _weight[e]) / 2);
1735
        }
1736
      }
1737

	
1738
      for (NodeIt n(_graph); n != INVALID; ++n) {
1739
        int nb = _blossom_set->find(n);
1740
        if ((*_blossom_data)[nb].status != MATCHED) continue;
1741
        int ni = (*_node_index)[n];
1742

	
1743
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1744
          Node v = _graph.target(e);
1745
          int vb = _blossom_set->find(v);
1746
          int vi = (*_node_index)[v];
1747

	
1748
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1749
            dualScale * _weight[e];
1750

	
1751
          if ((*_blossom_data)[vb].status == EVEN) {
1752

	
1753
            int vt = _tree_set->find(vb);
1754

	
1755
            typename std::map<int, Arc>::iterator it =
1756
              (*_node_data)[ni].heap_index.find(vt);
1757

	
1758
            if (it != (*_node_data)[ni].heap_index.end()) {
1759
              if ((*_node_data)[ni].heap[it->second] > rw) {
1760
                (*_node_data)[ni].heap.replace(it->second, e);
1761
                (*_node_data)[ni].heap.decrease(e, rw);
1762
                it->second = e;
1763
              }
1764
            } else {
1765
              (*_node_data)[ni].heap.push(e, rw);
1766
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
1767
            }
1768
          }
1769
        }
1770
            
1771
        if (!(*_node_data)[ni].heap.empty()) {
1772
          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1773
          _delta2->push(nb, _blossom_set->classPrio(nb));
1774
        }
1775
      }
1776
    }
1777

	
1736 1778
    /// \brief Start the algorithm
1737 1779
    ///
1738 1780
    /// This function starts the algorithm.
1739 1781
    ///
1740
    /// \pre \ref init() must be called before using this function.
1782
    /// \pre \ref init() or \ref fractionalInit() must be called
1783
    /// before using this function.
1741 1784
    void start() {
1742 1785
      enum OpType {
1743 1786
        D1, D2, D3, D4
1744 1787
      };
1745 1788

	
1746
      int unmatched = _node_num;
1747
      while (unmatched > 0) {
1789
      while (_unmatched > 0) {
1748 1790
        Value d1 = !_delta1->empty() ?
1749 1791
          _delta1->prio() : std::numeric_limits<Value>::max();
1750 1792

	
1751 1793
        Value d2 = !_delta2->empty() ?
1752 1794
          _delta2->prio() : std::numeric_limits<Value>::max();
1753 1795

	
1754 1796
        Value d3 = !_delta3->empty() ?
1755 1797
          _delta3->prio() : std::numeric_limits<Value>::max();
1756 1798

	
1757 1799
        Value d4 = !_delta4->empty() ?
1758 1800
          _delta4->prio() : std::numeric_limits<Value>::max();
1759 1801

	
1760
        _delta_sum = d1; OpType ot = D1;
1802
        _delta_sum = d3; OpType ot = D3;
1803
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1761 1804
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1762
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1763 1805
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1764 1806

	
1765

	
1766 1807
        switch (ot) {
1767 1808
        case D1:
1768 1809
          {
1769 1810
            Node n = _delta1->top();
1770 1811
            unmatchNode(n);
1771
            --unmatched;
1812
            --_unmatched;
1772 1813
          }
1773 1814
          break;
1774 1815
        case D2:
1775 1816
          {
1776 1817
            int blossom = _delta2->top();
1777 1818
            Node n = _blossom_set->classTop(blossom);
1778
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1779
            extendOnArc(e);
1819
            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
1820
            if ((*_blossom_data)[blossom].next == INVALID) {
1821
              augmentOnArc(a);
1822
              --_unmatched;
1823
            } else {
1824
              extendOnArc(a);
1825
            }
1780 1826
          }
1781 1827
          break;
1782 1828
        case D3:
1783 1829
          {
1784 1830
            Edge e = _delta3->top();
1785 1831

	
1786 1832
            int left_blossom = _blossom_set->find(_graph.u(e));
1787 1833
            int right_blossom = _blossom_set->find(_graph.v(e));
1788 1834

	
1789 1835
            if (left_blossom == right_blossom) {
1790 1836
              _delta3->pop();
1791 1837
            } else {
1792
              int left_tree;
1793
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1794
                left_tree = _tree_set->find(left_blossom);
1795
              } else {
1796
                left_tree = -1;
1797
                ++unmatched;
1798
              }
1799
              int right_tree;
1800
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1801
                right_tree = _tree_set->find(right_blossom);
1802
              } else {
1803
                right_tree = -1;
1804
                ++unmatched;
1805
              }
1838
              int left_tree = _tree_set->find(left_blossom);
1839
              int right_tree = _tree_set->find(right_blossom);
1806 1840

	
1807 1841
              if (left_tree == right_tree) {
1808 1842
                shrinkOnEdge(e, left_tree);
1809 1843
              } else {
1810 1844
                augmentOnEdge(e);
1811
                unmatched -= 2;
1845
                _unmatched -= 2;
1812 1846
              }
1813 1847
            }
1814 1848
          } break;
1815 1849
        case D4:
1816 1850
          splitBlossom(_delta4->top());
1817 1851
          break;
1818 1852
        }
1819 1853
      }
1820 1854
      extractMatching();
1821 1855
    }
1822 1856

	
1823 1857
    /// \brief Run the algorithm.
1824 1858
    ///
1825 1859
    /// This method runs the \c %MaxWeightedMatching algorithm.
1826 1860
    ///
1827 1861
    /// \note mwm.run() is just a shortcut of the following code.
1828 1862
    /// \code
1829
    ///   mwm.init();
1863
    ///   mwm.fractionalInit();
1830 1864
    ///   mwm.start();
1831 1865
    /// \endcode
1832 1866
    void run() {
1833
      init();
1867
      fractionalInit();
1834 1868
      start();
1835 1869
    }
1836 1870

	
1837 1871
    /// @}
1838 1872

	
1839 1873
    /// \name Primal Solution
1840
    /// Functions to get the primal solution, i.e. the maximum weighted 
1874
    /// Functions to get the primal solution, i.e. the maximum weighted
1841 1875
    /// matching.\n
1842 1876
    /// Either \ref run() or \ref start() function should be called before
1843 1877
    /// using them.
1844 1878

	
1845 1879
    /// @{
1846 1880

	
1847 1881
    /// \brief Return the weight of the matching.
1848 1882
    ///
1849 1883
    /// This function returns the weight of the found matching.
1850 1884
    ///
1851 1885
    /// \pre Either run() or start() must be called before using this function.
1852 1886
    Value matchingWeight() const {
1853 1887
      Value sum = 0;
1854 1888
      for (NodeIt n(_graph); n != INVALID; ++n) {
1855 1889
        if ((*_matching)[n] != INVALID) {
1856 1890
          sum += _weight[(*_matching)[n]];
1857 1891
        }
1858 1892
      }
1859
      return sum /= 2;
1893
      return sum / 2;
1860 1894
    }
1861 1895

	
1862 1896
    /// \brief Return the size (cardinality) of the matching.
1863 1897
    ///
1864 1898
    /// This function returns the size (cardinality) of the found matching.
1865 1899
    ///
1866 1900
    /// \pre Either run() or start() must be called before using this function.
1867 1901
    int matchingSize() const {
1868 1902
      int num = 0;
1869 1903
      for (NodeIt n(_graph); n != INVALID; ++n) {
1870 1904
        if ((*_matching)[n] != INVALID) {
1871 1905
          ++num;
1872 1906
        }
1873 1907
      }
1874 1908
      return num /= 2;
1875 1909
    }
1876 1910

	
1877 1911
    /// \brief Return \c true if the given edge is in the matching.
1878 1912
    ///
1879
    /// This function returns \c true if the given edge is in the found 
1913
    /// This function returns \c true if the given edge is in the found
1880 1914
    /// matching.
1881 1915
    ///
1882 1916
    /// \pre Either run() or start() must be called before using this function.
1883 1917
    bool matching(const Edge& edge) const {
1884 1918
      return edge == (*_matching)[_graph.u(edge)];
1885 1919
    }
1886 1920

	
1887 1921
    /// \brief Return the matching arc (or edge) incident to the given node.
1888 1922
    ///
1889 1923
    /// This function returns the matching arc (or edge) incident to the
1890
    /// given node in the found matching or \c INVALID if the node is 
1924
    /// given node in the found matching or \c INVALID if the node is
1891 1925
    /// not covered by the matching.
1892 1926
    ///
1893 1927
    /// \pre Either run() or start() must be called before using this function.
1894 1928
    Arc matching(const Node& node) const {
1895 1929
      return (*_matching)[node];
1896 1930
    }
1897 1931

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

	
1906 1940
    /// \brief Return the mate of the given node.
1907 1941
    ///
1908
    /// This function returns the mate of the given node in the found 
1942
    /// This function returns the mate of the given node in the found
1909 1943
    /// matching or \c INVALID if the node is not covered by the matching.
1910 1944
    ///
1911 1945
    /// \pre Either run() or start() must be called before using this function.
1912 1946
    Node mate(const Node& node) const {
1913 1947
      return (*_matching)[node] != INVALID ?
1914 1948
        _graph.target((*_matching)[node]) : INVALID;
1915 1949
    }
1916 1950

	
1917 1951
    /// @}
1918 1952

	
1919 1953
    /// \name Dual Solution
1920 1954
    /// Functions to get the dual solution.\n
1921 1955
    /// Either \ref run() or \ref start() function should be called before
1922 1956
    /// using them.
1923 1957

	
1924 1958
    /// @{
1925 1959

	
1926 1960
    /// \brief Return the value of the dual solution.
1927 1961
    ///
1928
    /// This function returns the value of the dual solution. 
1929
    /// It should be equal to the primal value scaled by \ref dualScale 
1962
    /// This function returns the value of the dual solution.
1963
    /// It should be equal to the primal value scaled by \ref dualScale
1930 1964
    /// "dual scale".
1931 1965
    ///
1932 1966
    /// \pre Either run() or start() must be called before using this function.
1933 1967
    Value dualValue() const {
1934 1968
      Value sum = 0;
1935 1969
      for (NodeIt n(_graph); n != INVALID; ++n) {
1936 1970
        sum += nodeValue(n);
1937 1971
      }
1938 1972
      for (int i = 0; i < blossomNum(); ++i) {
1939 1973
        sum += blossomValue(i) * (blossomSize(i) / 2);
1940 1974
      }
1941 1975
      return sum;
1942 1976
    }
1943 1977

	
1944 1978
    /// \brief Return the dual value (potential) of the given node.
1945 1979
    ///
1946 1980
    /// This function returns the dual value (potential) of the given node.
1947 1981
    ///
1948 1982
    /// \pre Either run() or start() must be called before using this function.
1949 1983
    Value nodeValue(const Node& n) const {
1950 1984
      return (*_node_potential)[n];
1951 1985
    }
1952 1986

	
1953 1987
    /// \brief Return the number of the blossoms in the basis.
1954 1988
    ///
1955 1989
    /// This function returns the number of the blossoms in the basis.
1956 1990
    ///
1957 1991
    /// \pre Either run() or start() must be called before using this function.
1958 1992
    /// \see BlossomIt
1959 1993
    int blossomNum() const {
1960 1994
      return _blossom_potential.size();
1961 1995
    }
1962 1996

	
1963 1997
    /// \brief Return the number of the nodes in the given blossom.
1964 1998
    ///
1965 1999
    /// This function returns the number of the nodes in the given blossom.
1966 2000
    ///
1967 2001
    /// \pre Either run() or start() must be called before using this function.
1968 2002
    /// \see BlossomIt
1969 2003
    int blossomSize(int k) const {
1970 2004
      return _blossom_potential[k].end - _blossom_potential[k].begin;
1971 2005
    }
1972 2006

	
1973 2007
    /// \brief Return the dual value (ptential) of the given blossom.
1974 2008
    ///
1975 2009
    /// This function returns the dual value (ptential) of the given blossom.
1976 2010
    ///
1977 2011
    /// \pre Either run() or start() must be called before using this function.
1978 2012
    Value blossomValue(int k) const {
1979 2013
      return _blossom_potential[k].value;
1980 2014
    }
1981 2015

	
1982 2016
    /// \brief Iterator for obtaining the nodes of a blossom.
1983 2017
    ///
1984
    /// This class provides an iterator for obtaining the nodes of the 
2018
    /// This class provides an iterator for obtaining the nodes of the
1985 2019
    /// given blossom. It lists a subset of the nodes.
1986
    /// Before using this iterator, you must allocate a 
2020
    /// Before using this iterator, you must allocate a
1987 2021
    /// MaxWeightedMatching class and execute it.
1988 2022
    class BlossomIt {
1989 2023
    public:
1990 2024

	
1991 2025
      /// \brief Constructor.
1992 2026
      ///
1993 2027
      /// Constructor to get the nodes of the given variable.
1994 2028
      ///
1995
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
1996
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
2029
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
2030
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
1997 2031
      /// called before initializing this iterator.
1998 2032
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
1999 2033
        : _algorithm(&algorithm)
2000 2034
      {
2001 2035
        _index = _algorithm->_blossom_potential[variable].begin;
2002 2036
        _last = _algorithm->_blossom_potential[variable].end;
2003 2037
      }
2004 2038

	
2005 2039
      /// \brief Conversion to \c Node.
2006 2040
      ///
2007 2041
      /// Conversion to \c Node.
2008 2042
      operator Node() const {
2009 2043
        return _algorithm->_blossom_node_list[_index];
2010 2044
      }
2011 2045

	
2012 2046
      /// \brief Increment operator.
2013 2047
      ///
2014 2048
      /// Increment operator.
2015 2049
      BlossomIt& operator++() {
2016 2050
        ++_index;
2017 2051
        return *this;
2018 2052
      }
2019 2053

	
2020 2054
      /// \brief Validity checking
2021 2055
      ///
2022 2056
      /// Checks whether the iterator is invalid.
2023 2057
      bool operator==(Invalid) const { return _index == _last; }
2024 2058

	
2025 2059
      /// \brief Validity checking
2026 2060
      ///
2027 2061
      /// Checks whether the iterator is valid.
2028 2062
      bool operator!=(Invalid) const { return _index != _last; }
2029 2063

	
2030 2064
    private:
2031 2065
      const MaxWeightedMatching* _algorithm;
2032 2066
      int _last;
2033 2067
      int _index;
2034 2068
    };
2035 2069

	
2036 2070
    /// @}
2037 2071

	
2038 2072
  };
2039 2073

	
2040 2074
  /// \ingroup matching
2041 2075
  ///
2042 2076
  /// \brief Weighted perfect matching in general graphs
2043 2077
  ///
2044 2078
  /// This class provides an efficient implementation of Edmond's
2045 2079
  /// maximum weighted perfect matching algorithm. The implementation
2046 2080
  /// is based on extensive use of priority queues and provides
2047 2081
  /// \f$O(nm\log n)\f$ time complexity.
2048 2082
  ///
2049
  /// The maximum weighted perfect matching problem is to find a subset of 
2050
  /// the edges in an undirected graph with maximum overall weight for which 
2083
  /// The maximum weighted perfect matching problem is to find a subset of
2084
  /// the edges in an undirected graph with maximum overall weight for which
2051 2085
  /// each node has exactly one incident edge.
2052 2086
  /// It can be formulated with the following linear program.
2053 2087
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2054 2088
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2055 2089
      \quad \forall B\in\mathcal{O}\f] */
2056 2090
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2057 2091
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2058 2092
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2059 2093
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2060 2094
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2061 2095
  /// subsets of the nodes.
2062 2096
  ///
2063 2097
  /// The algorithm calculates an optimal matching and a proof of the
2064 2098
  /// optimality. The solution of the dual problem can be used to check
2065 2099
  /// the result of the algorithm. The dual linear problem is the
2066 2100
  /// following.
2067 2101
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2068 2102
      w_{uv} \quad \forall uv\in E\f] */
2069 2103
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2070 2104
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2071 2105
      \frac{\vert B \vert - 1}{2}z_B\f] */
2072 2106
  ///
2073
  /// The algorithm can be executed with the run() function. 
2107
  /// The algorithm can be executed with the run() function.
2074 2108
  /// After it the matching (the primal solution) and the dual solution
2075
  /// can be obtained using the query functions and the 
2076
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2077
  /// which is able to iterate on the nodes of a blossom. 
2109
  /// can be obtained using the query functions and the
2110
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
2111
  /// which is able to iterate on the nodes of a blossom.
2078 2112
  /// If the value type is integer, then the dual solution is multiplied
2079 2113
  /// by \ref MaxWeightedMatching::dualScale "4".
2080 2114
  ///
2081 2115
  /// \tparam GR The undirected graph type the algorithm runs on.
2082
  /// \tparam WM The type edge weight map. The default type is 
2116
  /// \tparam WM The type edge weight map. The default type is
2083 2117
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2084 2118
#ifdef DOXYGEN
2085 2119
  template <typename GR, typename WM>
2086 2120
#else
2087 2121
  template <typename GR,
2088 2122
            typename WM = typename GR::template EdgeMap<int> >
2089 2123
#endif
2090 2124
  class MaxWeightedPerfectMatching {
2091 2125
  public:
2092 2126

	
2093 2127
    /// The graph type of the algorithm
2094 2128
    typedef GR Graph;
2095 2129
    /// The type of the edge weight map
2096 2130
    typedef WM WeightMap;
2097 2131
    /// The value type of the edge weights
2098 2132
    typedef typename WeightMap::Value Value;
2099 2133

	
2100 2134
    /// \brief Scaling factor for dual solution
2101 2135
    ///
2102 2136
    /// Scaling factor for dual solution, it is equal to 4 or 1
2103 2137
    /// according to the value type.
2104 2138
    static const int dualScale =
2105 2139
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2106 2140

	
2107 2141
    /// The type of the matching map
2108 2142
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2109 2143
    MatchingMap;
2110 2144

	
2111 2145
  private:
2112 2146

	
2113 2147
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2114 2148

	
2115 2149
    typedef typename Graph::template NodeMap<Value> NodePotential;
2116 2150
    typedef std::vector<Node> BlossomNodeList;
2117 2151

	
2118 2152
    struct BlossomVariable {
2119 2153
      int begin, end;
2120 2154
      Value value;
2121 2155

	
2122 2156
      BlossomVariable(int _begin, int _end, Value _value)
2123 2157
        : begin(_begin), end(_end), value(_value) {}
2124 2158

	
2125 2159
    };
2126 2160

	
2127 2161
    typedef std::vector<BlossomVariable> BlossomPotential;
2128 2162

	
2129 2163
    const Graph& _graph;
2130 2164
    const WeightMap& _weight;
2131 2165

	
2132 2166
    MatchingMap* _matching;
2133 2167

	
2134 2168
    NodePotential* _node_potential;
2135 2169

	
2136 2170
    BlossomPotential _blossom_potential;
2137 2171
    BlossomNodeList _blossom_node_list;
2138 2172

	
2139 2173
    int _node_num;
2140 2174
    int _blossom_num;
2141 2175

	
2142 2176
    typedef RangeMap<int> IntIntMap;
2143 2177

	
2144 2178
    enum Status {
2145 2179
      EVEN = -1, MATCHED = 0, ODD = 1
2146 2180
    };
2147 2181

	
2148 2182
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2149 2183
    struct BlossomData {
2150 2184
      int tree;
2151 2185
      Status status;
2152 2186
      Arc pred, next;
2153 2187
      Value pot, offset;
2154 2188
    };
2155 2189

	
2156 2190
    IntNodeMap *_blossom_index;
2157 2191
    BlossomSet *_blossom_set;
2158 2192
    RangeMap<BlossomData>* _blossom_data;
2159 2193

	
2160 2194
    IntNodeMap *_node_index;
2161 2195
    IntArcMap *_node_heap_index;
2162 2196

	
2163 2197
    struct NodeData {
2164 2198

	
2165 2199
      NodeData(IntArcMap& node_heap_index)
2166 2200
        : heap(node_heap_index) {}
2167 2201

	
2168 2202
      int blossom;
2169 2203
      Value pot;
2170 2204
      BinHeap<Value, IntArcMap> heap;
2171 2205
      std::map<int, Arc> heap_index;
2172 2206

	
2173 2207
      int tree;
2174 2208
    };
2175 2209

	
2176 2210
    RangeMap<NodeData>* _node_data;
2177 2211

	
2178 2212
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2179 2213

	
2180 2214
    IntIntMap *_tree_set_index;
2181 2215
    TreeSet *_tree_set;
2182 2216

	
2183 2217
    IntIntMap *_delta2_index;
2184 2218
    BinHeap<Value, IntIntMap> *_delta2;
2185 2219

	
2186 2220
    IntEdgeMap *_delta3_index;
2187 2221
    BinHeap<Value, IntEdgeMap> *_delta3;
2188 2222

	
2189 2223
    IntIntMap *_delta4_index;
2190 2224
    BinHeap<Value, IntIntMap> *_delta4;
2191 2225

	
2192 2226
    Value _delta_sum;
2227
    int _unmatched;
2228

	
2229
    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap> 
2230
    FractionalMatching;
2231
    FractionalMatching *_fractional;
2193 2232

	
2194 2233
    void createStructures() {
2195 2234
      _node_num = countNodes(_graph);
2196 2235
      _blossom_num = _node_num * 3 / 2;
2197 2236

	
2198 2237
      if (!_matching) {
2199 2238
        _matching = new MatchingMap(_graph);
2200 2239
      }
2201 2240
      if (!_node_potential) {
2202 2241
        _node_potential = new NodePotential(_graph);
2203 2242
      }
2204 2243
      if (!_blossom_set) {
2205 2244
        _blossom_index = new IntNodeMap(_graph);
2206 2245
        _blossom_set = new BlossomSet(*_blossom_index);
2207 2246
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2208 2247
      }
2209 2248

	
2210 2249
      if (!_node_index) {
2211 2250
        _node_index = new IntNodeMap(_graph);
2212 2251
        _node_heap_index = new IntArcMap(_graph);
2213 2252
        _node_data = new RangeMap<NodeData>(_node_num,
2214 2253
                                            NodeData(*_node_heap_index));
2215 2254
      }
2216 2255

	
2217 2256
      if (!_tree_set) {
2218 2257
        _tree_set_index = new IntIntMap(_blossom_num);
2219 2258
        _tree_set = new TreeSet(*_tree_set_index);
2220 2259
      }
2221 2260
      if (!_delta2) {
2222 2261
        _delta2_index = new IntIntMap(_blossom_num);
2223 2262
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2224 2263
      }
2225 2264
      if (!_delta3) {
2226 2265
        _delta3_index = new IntEdgeMap(_graph);
2227 2266
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2228 2267
      }
2229 2268
      if (!_delta4) {
2230 2269
        _delta4_index = new IntIntMap(_blossom_num);
2231 2270
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2232 2271
      }
2233 2272
    }
2234 2273

	
2235 2274
    void destroyStructures() {
2236
      _node_num = countNodes(_graph);
2237
      _blossom_num = _node_num * 3 / 2;
2238

	
2239 2275
      if (_matching) {
2240 2276
        delete _matching;
2241 2277
      }
2242 2278
      if (_node_potential) {
2243 2279
        delete _node_potential;
2244 2280
      }
2245 2281
      if (_blossom_set) {
2246 2282
        delete _blossom_index;
2247 2283
        delete _blossom_set;
2248 2284
        delete _blossom_data;
2249 2285
      }
2250 2286

	
2251 2287
      if (_node_index) {
2252 2288
        delete _node_index;
2253 2289
        delete _node_heap_index;
2254 2290
        delete _node_data;
2255 2291
      }
2256 2292

	
2257 2293
      if (_tree_set) {
2258 2294
        delete _tree_set_index;
2259 2295
        delete _tree_set;
2260 2296
      }
2261 2297
      if (_delta2) {
2262 2298
        delete _delta2_index;
2263 2299
        delete _delta2;
2264 2300
      }
2265 2301
      if (_delta3) {
2266 2302
        delete _delta3_index;
2267 2303
        delete _delta3;
2268 2304
      }
2269 2305
      if (_delta4) {
2270 2306
        delete _delta4_index;
2271 2307
        delete _delta4;
2272 2308
      }
2273 2309
    }
2274 2310

	
2275 2311
    void matchedToEven(int blossom, int tree) {
2276 2312
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2277 2313
        _delta2->erase(blossom);
2278 2314
      }
2279 2315

	
2280 2316
      if (!_blossom_set->trivial(blossom)) {
2281 2317
        (*_blossom_data)[blossom].pot -=
2282 2318
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2283 2319
      }
2284 2320

	
2285 2321
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2286 2322
           n != INVALID; ++n) {
2287 2323

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

	
2291 2327
        (*_node_data)[ni].heap.clear();
2292 2328
        (*_node_data)[ni].heap_index.clear();
2293 2329

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

	
2296 2332
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2297 2333
          Node v = _graph.source(e);
2298 2334
          int vb = _blossom_set->find(v);
2299 2335
          int vi = (*_node_index)[v];
2300 2336

	
2301 2337
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2302 2338
            dualScale * _weight[e];
2303 2339

	
2304 2340
          if ((*_blossom_data)[vb].status == EVEN) {
2305 2341
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2306 2342
              _delta3->push(e, rw / 2);
2307 2343
            }
2308 2344
          } else {
2309 2345
            typename std::map<int, Arc>::iterator it =
2310 2346
              (*_node_data)[vi].heap_index.find(tree);
2311 2347

	
2312 2348
            if (it != (*_node_data)[vi].heap_index.end()) {
2313 2349
              if ((*_node_data)[vi].heap[it->second] > rw) {
2314 2350
                (*_node_data)[vi].heap.replace(it->second, e);
2315 2351
                (*_node_data)[vi].heap.decrease(e, rw);
2316 2352
                it->second = e;
2317 2353
              }
2318 2354
            } else {
2319 2355
              (*_node_data)[vi].heap.push(e, rw);
2320 2356
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2321 2357
            }
2322 2358

	
2323 2359
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2324 2360
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2325 2361

	
2326 2362
              if ((*_blossom_data)[vb].status == MATCHED) {
2327 2363
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2328 2364
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2329 2365
                               (*_blossom_data)[vb].offset);
2330 2366
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2331 2367
                           (*_blossom_data)[vb].offset){
2332 2368
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2333 2369
                                   (*_blossom_data)[vb].offset);
2334 2370
                }
... ...
@@ -2815,430 +2851,572 @@
2815 2851
            _graph.oppositeArc((*_blossom_data)[tb].next);
2816 2852

	
2817 2853
          (*_blossom_data)[tb].status = EVEN;
2818 2854
          matchedToEven(tb, tree);
2819 2855
          _tree_set->insert(tb, tree);
2820 2856
          (*_blossom_data)[tb].pred =
2821 2857
            (*_blossom_data)[tb].next =
2822 2858
            _graph.oppositeArc((*_blossom_data)[ub].next);
2823 2859
          next = (*_blossom_data)[ub].next;
2824 2860
        }
2825 2861

	
2826 2862
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2827 2863
        matchedToOdd(subblossoms[ib]);
2828 2864
        _tree_set->insert(subblossoms[ib], tree);
2829 2865
        (*_blossom_data)[subblossoms[ib]].next = next;
2830 2866
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2831 2867
      }
2832 2868
      _tree_set->erase(blossom);
2833 2869
    }
2834 2870

	
2835 2871
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2836 2872
      if (_blossom_set->trivial(blossom)) {
2837 2873
        int bi = (*_node_index)[base];
2838 2874
        Value pot = (*_node_data)[bi].pot;
2839 2875

	
2840 2876
        (*_matching)[base] = matching;
2841 2877
        _blossom_node_list.push_back(base);
2842 2878
        (*_node_potential)[base] = pot;
2843 2879
      } else {
2844 2880

	
2845 2881
        Value pot = (*_blossom_data)[blossom].pot;
2846 2882
        int bn = _blossom_node_list.size();
2847 2883

	
2848 2884
        std::vector<int> subblossoms;
2849 2885
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2850 2886
        int b = _blossom_set->find(base);
2851 2887
        int ib = -1;
2852 2888
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2853 2889
          if (subblossoms[i] == b) { ib = i; break; }
2854 2890
        }
2855 2891

	
2856 2892
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2857 2893
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2858 2894
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2859 2895

	
2860 2896
          Arc m = (*_blossom_data)[tb].next;
2861 2897
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2862 2898
          extractBlossom(tb, _graph.source(m), m);
2863 2899
        }
2864 2900
        extractBlossom(subblossoms[ib], base, matching);
2865 2901

	
2866 2902
        int en = _blossom_node_list.size();
2867 2903

	
2868 2904
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2869 2905
      }
2870 2906
    }
2871 2907

	
2872 2908
    void extractMatching() {
2873 2909
      std::vector<int> blossoms;
2874 2910
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2875 2911
        blossoms.push_back(c);
2876 2912
      }
2877 2913

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

	
2880 2916
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2881 2917
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2882 2918
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2883 2919
             n != INVALID; ++n) {
2884 2920
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2885 2921
        }
2886 2922

	
2887 2923
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2888 2924
        Node base = _graph.source(matching);
2889 2925
        extractBlossom(blossoms[i], base, matching);
2890 2926
      }
2891 2927
    }
2892 2928

	
2893 2929
  public:
2894 2930

	
2895 2931
    /// \brief Constructor
2896 2932
    ///
2897 2933
    /// Constructor.
2898 2934
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2899 2935
      : _graph(graph), _weight(weight), _matching(0),
2900 2936
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2901 2937
        _node_num(0), _blossom_num(0),
2902 2938

	
2903 2939
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2904 2940
        _node_index(0), _node_heap_index(0), _node_data(0),
2905 2941
        _tree_set_index(0), _tree_set(0),
2906 2942

	
2907 2943
        _delta2_index(0), _delta2(0),
2908 2944
        _delta3_index(0), _delta3(0),
2909 2945
        _delta4_index(0), _delta4(0),
2910 2946

	
2911
        _delta_sum() {}
2947
        _delta_sum(), _unmatched(0),
2948

	
2949
        _fractional(0)
2950
    {}
2912 2951

	
2913 2952
    ~MaxWeightedPerfectMatching() {
2914 2953
      destroyStructures();
2954
      if (_fractional) {
2955
        delete _fractional;
2956
      }
2915 2957
    }
2916 2958

	
2917 2959
    /// \name Execution Control
2918 2960
    /// The simplest way to execute the algorithm is to use the
2919 2961
    /// \ref run() member function.
2920 2962

	
2921 2963
    ///@{
2922 2964

	
2923 2965
    /// \brief Initialize the algorithm
2924 2966
    ///
2925 2967
    /// This function initializes the algorithm.
2926 2968
    void init() {
2927 2969
      createStructures();
2928 2970

	
2929 2971
      for (ArcIt e(_graph); e != INVALID; ++e) {
2930 2972
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
2931 2973
      }
2932 2974
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2933 2975
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
2934 2976
      }
2935 2977
      for (int i = 0; i < _blossom_num; ++i) {
2936 2978
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
2937 2979
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
2938 2980
      }
2939 2981

	
2982
      _unmatched = _node_num;
2983

	
2940 2984
      int index = 0;
2941 2985
      for (NodeIt n(_graph); n != INVALID; ++n) {
2942 2986
        Value max = - std::numeric_limits<Value>::max();
2943 2987
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2944 2988
          if (_graph.target(e) == n) continue;
2945 2989
          if ((dualScale * _weight[e]) / 2 > max) {
2946 2990
            max = (dualScale * _weight[e]) / 2;
2947 2991
          }
2948 2992
        }
2949 2993
        (*_node_index)[n] = index;
2950 2994
        (*_node_data)[index].pot = max;
2951 2995
        int blossom =
2952 2996
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
2953 2997

	
2954 2998
        _tree_set->insert(blossom);
2955 2999

	
2956 3000
        (*_blossom_data)[blossom].status = EVEN;
2957 3001
        (*_blossom_data)[blossom].pred = INVALID;
2958 3002
        (*_blossom_data)[blossom].next = INVALID;
2959 3003
        (*_blossom_data)[blossom].pot = 0;
2960 3004
        (*_blossom_data)[blossom].offset = 0;
2961 3005
        ++index;
2962 3006
      }
2963 3007
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2964 3008
        int si = (*_node_index)[_graph.u(e)];
2965 3009
        int ti = (*_node_index)[_graph.v(e)];
2966 3010
        if (_graph.u(e) != _graph.v(e)) {
2967 3011
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
2968 3012
                            dualScale * _weight[e]) / 2);
2969 3013
        }
2970 3014
      }
2971 3015
    }
2972 3016

	
3017
    /// \brief Initialize the algorithm with fractional matching
3018
    ///
3019
    /// This function initializes the algorithm with a fractional
3020
    /// matching. This initialization is also called jumpstart heuristic.
3021
    void fractionalInit() {
3022
      createStructures();
3023
      
3024
      if (_fractional == 0) {
3025
        _fractional = new FractionalMatching(_graph, _weight, false);
3026
      }
3027
      if (!_fractional->run()) {
3028
        _unmatched = -1;
3029
        return;
3030
      }
3031

	
3032
      for (ArcIt e(_graph); e != INVALID; ++e) {
3033
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
3034
      }
3035
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3036
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
3037
      }
3038
      for (int i = 0; i < _blossom_num; ++i) {
3039
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
3040
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
3041
      }
3042

	
3043
      _unmatched = 0;
3044

	
3045
      int index = 0;
3046
      for (NodeIt n(_graph); n != INVALID; ++n) {
3047
        Value pot = _fractional->nodeValue(n);
3048
        (*_node_index)[n] = index;
3049
        (*_node_data)[index].pot = pot;
3050
        int blossom =
3051
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
3052

	
3053
        (*_blossom_data)[blossom].status = MATCHED;
3054
        (*_blossom_data)[blossom].pred = INVALID;
3055
        (*_blossom_data)[blossom].next = _fractional->matching(n);
3056
        (*_blossom_data)[blossom].pot = 0;
3057
        (*_blossom_data)[blossom].offset = 0;
3058
        ++index;
3059
      }
3060

	
3061
      typename Graph::template NodeMap<bool> processed(_graph, false);
3062
      for (NodeIt n(_graph); n != INVALID; ++n) {
3063
        if (processed[n]) continue;
3064
        processed[n] = true;
3065
        if (_fractional->matching(n) == INVALID) continue;
3066
        int num = 1;
3067
        Node v = _graph.target(_fractional->matching(n));
3068
        while (n != v) {
3069
          processed[v] = true;
3070
          v = _graph.target(_fractional->matching(v));
3071
          ++num;
3072
        }
3073

	
3074
        if (num % 2 == 1) {
3075
          std::vector<int> subblossoms(num);
3076

	
3077
          subblossoms[--num] = _blossom_set->find(n);
3078
          v = _graph.target(_fractional->matching(n));
3079
          while (n != v) {
3080
            subblossoms[--num] = _blossom_set->find(v);
3081
            v = _graph.target(_fractional->matching(v));            
3082
          }
3083
          
3084
          int surface = 
3085
            _blossom_set->join(subblossoms.begin(), subblossoms.end());
3086
          (*_blossom_data)[surface].status = EVEN;
3087
          (*_blossom_data)[surface].pred = INVALID;
3088
          (*_blossom_data)[surface].next = INVALID;
3089
          (*_blossom_data)[surface].pot = 0;
3090
          (*_blossom_data)[surface].offset = 0;
3091
          
3092
          _tree_set->insert(surface);
3093
          ++_unmatched;
3094
        }
3095
      }
3096

	
3097
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3098
        int si = (*_node_index)[_graph.u(e)];
3099
        int sb = _blossom_set->find(_graph.u(e));
3100
        int ti = (*_node_index)[_graph.v(e)];
3101
        int tb = _blossom_set->find(_graph.v(e));
3102
        if ((*_blossom_data)[sb].status == EVEN &&
3103
            (*_blossom_data)[tb].status == EVEN && sb != tb) {
3104
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
3105
                            dualScale * _weight[e]) / 2);
3106
        }
3107
      }
3108

	
3109
      for (NodeIt n(_graph); n != INVALID; ++n) {
3110
        int nb = _blossom_set->find(n);
3111
        if ((*_blossom_data)[nb].status != MATCHED) continue;
3112
        int ni = (*_node_index)[n];
3113

	
3114
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
3115
          Node v = _graph.target(e);
3116
          int vb = _blossom_set->find(v);
3117
          int vi = (*_node_index)[v];
3118

	
3119
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
3120
            dualScale * _weight[e];
3121

	
3122
          if ((*_blossom_data)[vb].status == EVEN) {
3123

	
3124
            int vt = _tree_set->find(vb);
3125

	
3126
            typename std::map<int, Arc>::iterator it =
3127
              (*_node_data)[ni].heap_index.find(vt);
3128

	
3129
            if (it != (*_node_data)[ni].heap_index.end()) {
3130
              if ((*_node_data)[ni].heap[it->second] > rw) {
3131
                (*_node_data)[ni].heap.replace(it->second, e);
3132
                (*_node_data)[ni].heap.decrease(e, rw);
3133
                it->second = e;
3134
              }
3135
            } else {
3136
              (*_node_data)[ni].heap.push(e, rw);
3137
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
3138
            }
3139
          }
3140
        }
3141
            
3142
        if (!(*_node_data)[ni].heap.empty()) {
3143
          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
3144
          _delta2->push(nb, _blossom_set->classPrio(nb));
3145
        }
3146
      }
3147
    }
3148

	
2973 3149
    /// \brief Start the algorithm
2974 3150
    ///
2975 3151
    /// This function starts the algorithm.
2976 3152
    ///
2977
    /// \pre \ref init() must be called before using this function.
3153
    /// \pre \ref init() or \ref fractionalInit() must be called before
3154
    /// using this function.
2978 3155
    bool start() {
2979 3156
      enum OpType {
2980 3157
        D2, D3, D4
2981 3158
      };
2982 3159

	
2983
      int unmatched = _node_num;
2984
      while (unmatched > 0) {
3160
      if (_unmatched == -1) return false;
3161

	
3162
      while (_unmatched > 0) {
2985 3163
        Value d2 = !_delta2->empty() ?
2986 3164
          _delta2->prio() : std::numeric_limits<Value>::max();
2987 3165

	
2988 3166
        Value d3 = !_delta3->empty() ?
2989 3167
          _delta3->prio() : std::numeric_limits<Value>::max();
2990 3168

	
2991 3169
        Value d4 = !_delta4->empty() ?
2992 3170
          _delta4->prio() : std::numeric_limits<Value>::max();
2993 3171

	
2994
        _delta_sum = d2; OpType ot = D2;
2995
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
3172
        _delta_sum = d3; OpType ot = D3;
3173
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
2996 3174
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2997 3175

	
2998 3176
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2999 3177
          return false;
3000 3178
        }
3001 3179

	
3002 3180
        switch (ot) {
3003 3181
        case D2:
3004 3182
          {
3005 3183
            int blossom = _delta2->top();
3006 3184
            Node n = _blossom_set->classTop(blossom);
3007 3185
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3008 3186
            extendOnArc(e);
3009 3187
          }
3010 3188
          break;
3011 3189
        case D3:
3012 3190
          {
3013 3191
            Edge e = _delta3->top();
3014 3192

	
3015 3193
            int left_blossom = _blossom_set->find(_graph.u(e));
3016 3194
            int right_blossom = _blossom_set->find(_graph.v(e));
3017 3195

	
3018 3196
            if (left_blossom == right_blossom) {
3019 3197
              _delta3->pop();
3020 3198
            } else {
3021 3199
              int left_tree = _tree_set->find(left_blossom);
3022 3200
              int right_tree = _tree_set->find(right_blossom);
3023 3201

	
3024 3202
              if (left_tree == right_tree) {
3025 3203
                shrinkOnEdge(e, left_tree);
3026 3204
              } else {
3027 3205
                augmentOnEdge(e);
3028
                unmatched -= 2;
3206
                _unmatched -= 2;
3029 3207
              }
3030 3208
            }
3031 3209
          } break;
3032 3210
        case D4:
3033 3211
          splitBlossom(_delta4->top());
3034 3212
          break;
3035 3213
        }
3036 3214
      }
3037 3215
      extractMatching();
3038 3216
      return true;
3039 3217
    }
3040 3218

	
3041 3219
    /// \brief Run the algorithm.
3042 3220
    ///
3043 3221
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3044 3222
    ///
3045 3223
    /// \note mwpm.run() is just a shortcut of the following code.
3046 3224
    /// \code
3047
    ///   mwpm.init();
3225
    ///   mwpm.fractionalInit();
3048 3226
    ///   mwpm.start();
3049 3227
    /// \endcode
3050 3228
    bool run() {
3051
      init();
3229
      fractionalInit();
3052 3230
      return start();
3053 3231
    }
3054 3232

	
3055 3233
    /// @}
3056 3234

	
3057 3235
    /// \name Primal Solution
3058
    /// Functions to get the primal solution, i.e. the maximum weighted 
3236
    /// Functions to get the primal solution, i.e. the maximum weighted
3059 3237
    /// perfect matching.\n
3060 3238
    /// Either \ref run() or \ref start() function should be called before
3061 3239
    /// using them.
3062 3240

	
3063 3241
    /// @{
3064 3242

	
3065 3243
    /// \brief Return the weight of the matching.
3066 3244
    ///
3067 3245
    /// This function returns the weight of the found matching.
3068 3246
    ///
3069 3247
    /// \pre Either run() or start() must be called before using this function.
3070 3248
    Value matchingWeight() const {
3071 3249
      Value sum = 0;
3072 3250
      for (NodeIt n(_graph); n != INVALID; ++n) {
3073 3251
        if ((*_matching)[n] != INVALID) {
3074 3252
          sum += _weight[(*_matching)[n]];
3075 3253
        }
3076 3254
      }
3077
      return sum /= 2;
3255
      return sum / 2;
3078 3256
    }
3079 3257

	
3080 3258
    /// \brief Return \c true if the given edge is in the matching.
3081 3259
    ///
3082
    /// This function returns \c true if the given edge is in the found 
3260
    /// This function returns \c true if the given edge is in the found
3083 3261
    /// matching.
3084 3262
    ///
3085 3263
    /// \pre Either run() or start() must be called before using this function.
3086 3264
    bool matching(const Edge& edge) const {
3087 3265
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3088 3266
    }
3089 3267

	
3090 3268
    /// \brief Return the matching arc (or edge) incident to the given node.
3091 3269
    ///
3092 3270
    /// This function returns the matching arc (or edge) incident to the
3093
    /// given node in the found matching or \c INVALID if the node is 
3271
    /// given node in the found matching or \c INVALID if the node is
3094 3272
    /// not covered by the matching.
3095 3273
    ///
3096 3274
    /// \pre Either run() or start() must be called before using this function.
3097 3275
    Arc matching(const Node& node) const {
3098 3276
      return (*_matching)[node];
3099 3277
    }
3100 3278

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

	
3109 3287
    /// \brief Return the mate of the given node.
3110 3288
    ///
3111
    /// This function returns the mate of the given node in the found 
3289
    /// This function returns the mate of the given node in the found
3112 3290
    /// matching or \c INVALID if the node is not covered by the matching.
3113 3291
    ///
3114 3292
    /// \pre Either run() or start() must be called before using this function.
3115 3293
    Node mate(const Node& node) const {
3116 3294
      return _graph.target((*_matching)[node]);
3117 3295
    }
3118 3296

	
3119 3297
    /// @}
3120 3298

	
3121 3299
    /// \name Dual Solution
3122 3300
    /// Functions to get the dual solution.\n
3123 3301
    /// Either \ref run() or \ref start() function should be called before
3124 3302
    /// using them.
3125 3303

	
3126 3304
    /// @{
3127 3305

	
3128 3306
    /// \brief Return the value of the dual solution.
3129 3307
    ///
3130
    /// This function returns the value of the dual solution. 
3131
    /// It should be equal to the primal value scaled by \ref dualScale 
3308
    /// This function returns the value of the dual solution.
3309
    /// It should be equal to the primal value scaled by \ref dualScale
3132 3310
    /// "dual scale".
3133 3311
    ///
3134 3312
    /// \pre Either run() or start() must be called before using this function.
3135 3313
    Value dualValue() const {
3136 3314
      Value sum = 0;
3137 3315
      for (NodeIt n(_graph); n != INVALID; ++n) {
3138 3316
        sum += nodeValue(n);
3139 3317
      }
3140 3318
      for (int i = 0; i < blossomNum(); ++i) {
3141 3319
        sum += blossomValue(i) * (blossomSize(i) / 2);
3142 3320
      }
3143 3321
      return sum;
3144 3322
    }
3145 3323

	
3146 3324
    /// \brief Return the dual value (potential) of the given node.
3147 3325
    ///
3148 3326
    /// This function returns the dual value (potential) of the given node.
3149 3327
    ///
3150 3328
    /// \pre Either run() or start() must be called before using this function.
3151 3329
    Value nodeValue(const Node& n) const {
3152 3330
      return (*_node_potential)[n];
3153 3331
    }
3154 3332

	
3155 3333
    /// \brief Return the number of the blossoms in the basis.
3156 3334
    ///
3157 3335
    /// This function returns the number of the blossoms in the basis.
3158 3336
    ///
3159 3337
    /// \pre Either run() or start() must be called before using this function.
3160 3338
    /// \see BlossomIt
3161 3339
    int blossomNum() const {
3162 3340
      return _blossom_potential.size();
3163 3341
    }
3164 3342

	
3165 3343
    /// \brief Return the number of the nodes in the given blossom.
3166 3344
    ///
3167 3345
    /// This function returns the number of the nodes in the given blossom.
3168 3346
    ///
3169 3347
    /// \pre Either run() or start() must be called before using this function.
3170 3348
    /// \see BlossomIt
3171 3349
    int blossomSize(int k) const {
3172 3350
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3173 3351
    }
3174 3352

	
3175 3353
    /// \brief Return the dual value (ptential) of the given blossom.
3176 3354
    ///
3177 3355
    /// This function returns the dual value (ptential) of the given blossom.
3178 3356
    ///
3179 3357
    /// \pre Either run() or start() must be called before using this function.
3180 3358
    Value blossomValue(int k) const {
3181 3359
      return _blossom_potential[k].value;
3182 3360
    }
3183 3361

	
3184 3362
    /// \brief Iterator for obtaining the nodes of a blossom.
3185 3363
    ///
3186
    /// This class provides an iterator for obtaining the nodes of the 
3364
    /// This class provides an iterator for obtaining the nodes of the
3187 3365
    /// given blossom. It lists a subset of the nodes.
3188
    /// Before using this iterator, you must allocate a 
3366
    /// Before using this iterator, you must allocate a
3189 3367
    /// MaxWeightedPerfectMatching class and execute it.
3190 3368
    class BlossomIt {
3191 3369
    public:
3192 3370

	
3193 3371
      /// \brief Constructor.
3194 3372
      ///
3195 3373
      /// Constructor to get the nodes of the given variable.
3196 3374
      ///
3197
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
3198
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
3375
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
3376
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
3199 3377
      /// must be called before initializing this iterator.
3200 3378
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3201 3379
        : _algorithm(&algorithm)
3202 3380
      {
3203 3381
        _index = _algorithm->_blossom_potential[variable].begin;
3204 3382
        _last = _algorithm->_blossom_potential[variable].end;
3205 3383
      }
3206 3384

	
3207 3385
      /// \brief Conversion to \c Node.
3208 3386
      ///
3209 3387
      /// Conversion to \c Node.
3210 3388
      operator Node() const {
3211 3389
        return _algorithm->_blossom_node_list[_index];
3212 3390
      }
3213 3391

	
3214 3392
      /// \brief Increment operator.
3215 3393
      ///
3216 3394
      /// Increment operator.
3217 3395
      BlossomIt& operator++() {
3218 3396
        ++_index;
3219 3397
        return *this;
3220 3398
      }
3221 3399

	
3222 3400
      /// \brief Validity checking
3223 3401
      ///
3224 3402
      /// This function checks whether the iterator is invalid.
3225 3403
      bool operator==(Invalid) const { return _index == _last; }
3226 3404

	
3227 3405
      /// \brief Validity checking
3228 3406
      ///
3229 3407
      /// This function checks whether the iterator is valid.
3230 3408
      bool operator!=(Invalid) const { return _index != _last; }
3231 3409

	
3232 3410
    private:
3233 3411
      const MaxWeightedPerfectMatching* _algorithm;
3234 3412
      int _last;
3235 3413
      int _index;
3236 3414
    };
3237 3415

	
3238 3416
    /// @}
3239 3417

	
3240 3418
  };
3241 3419

	
3242 3420
} //END OF NAMESPACE LEMON
3243 3421

	
3244
#endif //LEMON_MAX_MATCHING_H
3422
#endif //LEMON_MATCHING_H
Ignore white space 192 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(
7 7
  ${PROJECT_BINARY_DIR}/lemon
8 8
)
9 9

	
10 10
SET(TESTS
11 11
  adaptors_test
12 12
  bellman_ford_test
13 13
  bfs_test
14 14
  circulation_test
15 15
  connectivity_test
16 16
  counter_test
17 17
  dfs_test
18 18
  digraph_test
19 19
  dijkstra_test
20 20
  dim_test
21 21
  edge_set_test
22 22
  error_test
23 23
  euler_test
24
  fractional_matching_test
24 25
  gomory_hu_test
25 26
  graph_copy_test
26 27
  graph_test
27 28
  graph_utils_test
28 29
  hao_orlin_test
29 30
  heap_test
30 31
  kruskal_test
31 32
  maps_test
32 33
  matching_test
33 34
  min_cost_arborescence_test
34 35
  min_cost_flow_test
35 36
  min_mean_cycle_test
36 37
  path_test
37 38
  planarity_test
38 39
  preflow_test
39 40
  radix_sort_test
40 41
  random_test
41 42
  suurballe_test
42 43
  time_measure_test
43 44
  unionfind_test
44 45
)
45 46

	
46 47
IF(LEMON_HAVE_LP)
47 48
  ADD_EXECUTABLE(lp_test lp_test.cc)
48 49
  SET(LP_TEST_LIBS lemon)
49 50

	
50 51
  IF(LEMON_HAVE_GLPK)
51 52
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
52 53
  ENDIF()
53 54
  IF(LEMON_HAVE_CPLEX)
54 55
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
55 56
  ENDIF()
56 57
  IF(LEMON_HAVE_CLP)
57 58
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
58 59
  ENDIF()
59 60

	
60 61
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
61 62
  ADD_TEST(lp_test lp_test)
62 63

	
63 64
  IF(WIN32 AND LEMON_HAVE_GLPK)
64 65
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
65 66
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
66 67
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
67 68
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
68 69
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
69 70
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
70 71
    )
71 72
  ENDIF()
72 73

	
73 74
  IF(WIN32 AND LEMON_HAVE_CPLEX)
74 75
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
75 76
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
76 77
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
77 78
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
78 79
    )
79 80
  ENDIF()
80 81
ENDIF()
81 82

	
82 83
IF(LEMON_HAVE_MIP)
83 84
  ADD_EXECUTABLE(mip_test mip_test.cc)
84 85
  SET(MIP_TEST_LIBS lemon)
85 86

	
86 87
  IF(LEMON_HAVE_GLPK)
87 88
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
88 89
  ENDIF()
89 90
  IF(LEMON_HAVE_CPLEX)
90 91
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
91 92
  ENDIF()
92 93
  IF(LEMON_HAVE_CBC)
93 94
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
94 95
  ENDIF()
95 96

	
96 97
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
97 98
  ADD_TEST(mip_test mip_test)
98 99

	
99 100
  IF(WIN32 AND LEMON_HAVE_GLPK)
100 101
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
101 102
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
102 103
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
103 104
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
104 105
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
105 106
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
106 107
    )
107 108
  ENDIF()
108 109

	
109 110
  IF(WIN32 AND LEMON_HAVE_CPLEX)
110 111
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
111 112
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
112 113
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
113 114
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
114 115
    )
115 116
  ENDIF()
116 117
ENDIF()
117 118

	
118 119
FOREACH(TEST_NAME ${TESTS})
119 120
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
Ignore white space 192 line context
1 1
if USE_VALGRIND
2 2
TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
3 3
endif
4 4

	
5 5
EXTRA_DIST += \
6 6
	test/CMakeLists.txt
7 7

	
8 8
noinst_HEADERS += \
9 9
	test/graph_test.h \
10 10
	test/test_tools.h
11 11

	
12 12
check_PROGRAMS += \
13 13
	test/adaptors_test \
14 14
	test/bellman_ford_test \
15 15
	test/bfs_test \
16 16
	test/circulation_test \
17 17
	test/connectivity_test \
18 18
	test/counter_test \
19 19
	test/dfs_test \
20 20
	test/digraph_test \
21 21
	test/dijkstra_test \
22 22
	test/dim_test \
23 23
	test/edge_set_test \
24 24
	test/error_test \
25 25
	test/euler_test \
26
	test/fractional_matching_test \
26 27
	test/gomory_hu_test \
27 28
	test/graph_copy_test \
28 29
	test/graph_test \
29 30
	test/graph_utils_test \
30 31
	test/hao_orlin_test \
31 32
	test/heap_test \
32 33
	test/kruskal_test \
33 34
	test/maps_test \
34 35
	test/matching_test \
35 36
	test/min_cost_arborescence_test \
36 37
	test/min_cost_flow_test \
37 38
	test/min_mean_cycle_test \
38 39
	test/path_test \
39 40
	test/planarity_test \
40 41
	test/preflow_test \
41 42
	test/radix_sort_test \
42 43
	test/random_test \
43 44
	test/suurballe_test \
44 45
	test/test_tools_fail \
45 46
	test/test_tools_pass \
46 47
	test/time_measure_test \
47 48
	test/unionfind_test
48 49

	
49 50
test_test_tools_pass_DEPENDENCIES = demo
50 51

	
51 52
if HAVE_LP
52 53
check_PROGRAMS += test/lp_test
53 54
endif HAVE_LP
54 55
if HAVE_MIP
55 56
check_PROGRAMS += test/mip_test
56 57
endif HAVE_MIP
57 58

	
58 59
TESTS += $(check_PROGRAMS)
59 60
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
60 61

	
61 62
test_adaptors_test_SOURCES = test/adaptors_test.cc
62 63
test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
63 64
test_bfs_test_SOURCES = test/bfs_test.cc
64 65
test_circulation_test_SOURCES = test/circulation_test.cc
65 66
test_counter_test_SOURCES = test/counter_test.cc
66 67
test_connectivity_test_SOURCES = test/connectivity_test.cc
67 68
test_dfs_test_SOURCES = test/dfs_test.cc
68 69
test_digraph_test_SOURCES = test/digraph_test.cc
69 70
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
70 71
test_dim_test_SOURCES = test/dim_test.cc
71 72
test_edge_set_test_SOURCES = test/edge_set_test.cc
72 73
test_error_test_SOURCES = test/error_test.cc
73 74
test_euler_test_SOURCES = test/euler_test.cc
75
test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
74 76
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
75 77
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
76 78
test_graph_test_SOURCES = test/graph_test.cc
77 79
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
78 80
test_heap_test_SOURCES = test/heap_test.cc
79 81
test_kruskal_test_SOURCES = test/kruskal_test.cc
80 82
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
81 83
test_lp_test_SOURCES = test/lp_test.cc
82 84
test_maps_test_SOURCES = test/maps_test.cc
83 85
test_mip_test_SOURCES = test/mip_test.cc
84 86
test_matching_test_SOURCES = test/matching_test.cc
85 87
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
86 88
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
87 89
test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
88 90
test_path_test_SOURCES = test/path_test.cc
89 91
test_planarity_test_SOURCES = test/planarity_test.cc
90 92
test_preflow_test_SOURCES = test/preflow_test.cc
91 93
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
92 94
test_suurballe_test_SOURCES = test/suurballe_test.cc
93 95
test_random_test_SOURCES = test/random_test.cc
94 96
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
95 97
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
96 98
test_time_measure_test_SOURCES = test/time_measure_test.cc
97 99
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 192 line context
... ...
@@ -308,117 +308,141 @@
308 308
          "Non-zero reduced weight on matching edge");
309 309
  }
310 310

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

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

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

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

	
339 339
  return;
340 340
}
341 341

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

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

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

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

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

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

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

	
390 390
  return;
391 391
}
392 392

	
393 393

	
394 394
int main() {
395 395

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

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

	
404
    MaxMatching<SmartGraph> mm(graph);
405
    mm.run();
406
    checkMatching(graph, mm);
404
    bool perfect;
405
    {
406
      MaxMatching<SmartGraph> mm(graph);
407
      mm.run();
408
      checkMatching(graph, mm);
409
      perfect = 2 * mm.matchingSize() == countNodes(graph);
410
    }
407 411

	
408
    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
409
    mwm.run();
410
    checkWeightedMatching(graph, weight, mwm);
412
    {
413
      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
414
      mwm.run();
415
      checkWeightedMatching(graph, weight, mwm);
416
    }
411 417

	
412
    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
413
    bool perfect = mwpm.run();
418
    {
419
      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
420
      mwm.init();
421
      mwm.start();
422
      checkWeightedMatching(graph, weight, mwm);
423
    }
414 424

	
415
    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
416
          "Perfect matching found");
425
    {
426
      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
427
      bool result = mwpm.run();
428
      
429
      check(result == perfect, "Perfect matching found");
430
      if (perfect) {
431
        checkWeightedPerfectMatching(graph, weight, mwpm);
432
      }
433
    }
417 434

	
418
    if (perfect) {
419
      checkWeightedPerfectMatching(graph, weight, mwpm);
435
    {
436
      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
437
      mwpm.init();
438
      bool result = mwpm.start();
439
      
440
      check(result == perfect, "Perfect matching found");
441
      if (perfect) {
442
        checkWeightedPerfectMatching(graph, weight, mwpm);
443
      }
420 444
    }
421 445
  }
422 446

	
423 447
  return 0;
424 448
}
0 comments (0 inline)