lemon/fractional_matching.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 04 Mar 2010 10:17:02 +0100
changeset 871 86613aa28a0c
parent 869 636dadefe1e6
child 872 41d7ac528c3a
permissions -rw-r--r--
Fix documentation issues (#314)
deba@869
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@869
     2
 *
deba@869
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@869
     4
 *
deba@869
     5
 * Copyright (C) 2003-2009
deba@869
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@869
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@869
     8
 *
deba@869
     9
 * Permission to use, modify and distribute this software is granted
deba@869
    10
 * provided that this copyright notice appears in all copies. For
deba@869
    11
 * precise terms see the accompanying LICENSE file.
deba@869
    12
 *
deba@869
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@869
    14
 * express or implied, and with no claim as to its suitability for any
deba@869
    15
 * purpose.
deba@869
    16
 *
deba@869
    17
 */
deba@869
    18
deba@869
    19
#ifndef LEMON_FRACTIONAL_MATCHING_H
deba@869
    20
#define LEMON_FRACTIONAL_MATCHING_H
deba@869
    21
deba@869
    22
#include <vector>
deba@869
    23
#include <queue>
deba@869
    24
#include <set>
deba@869
    25
#include <limits>
deba@869
    26
deba@869
    27
#include <lemon/core.h>
deba@869
    28
#include <lemon/unionfind.h>
deba@869
    29
#include <lemon/bin_heap.h>
deba@869
    30
#include <lemon/maps.h>
deba@869
    31
#include <lemon/assert.h>
deba@869
    32
#include <lemon/elevator.h>
deba@869
    33
deba@869
    34
///\ingroup matching
deba@869
    35
///\file
deba@869
    36
///\brief Fractional matching algorithms in general graphs.
deba@869
    37
deba@869
    38
namespace lemon {
deba@869
    39
deba@869
    40
  /// \brief Default traits class of MaxFractionalMatching class.
deba@869
    41
  ///
deba@869
    42
  /// Default traits class of MaxFractionalMatching class.
deba@869
    43
  /// \tparam GR Graph type.
deba@869
    44
  template <typename GR>
deba@869
    45
  struct MaxFractionalMatchingDefaultTraits {
deba@869
    46
deba@869
    47
    /// \brief The type of the graph the algorithm runs on.
deba@869
    48
    typedef GR Graph;
deba@869
    49
deba@869
    50
    /// \brief The type of the map that stores the matching.
deba@869
    51
    ///
deba@869
    52
    /// The type of the map that stores the matching arcs.
deba@869
    53
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
deba@869
    54
    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
deba@869
    55
deba@869
    56
    /// \brief Instantiates a MatchingMap.
deba@869
    57
    ///
deba@869
    58
    /// This function instantiates a \ref MatchingMap.
deba@869
    59
    /// \param graph The graph for which we would like to define
deba@869
    60
    /// the matching map.
deba@869
    61
    static MatchingMap* createMatchingMap(const Graph& graph) {
deba@869
    62
      return new MatchingMap(graph);
deba@869
    63
    }
deba@869
    64
deba@869
    65
    /// \brief The elevator type used by MaxFractionalMatching algorithm.
deba@869
    66
    ///
deba@869
    67
    /// The elevator type used by MaxFractionalMatching algorithm.
deba@869
    68
    ///
deba@869
    69
    /// \sa Elevator
deba@869
    70
    /// \sa LinkedElevator
deba@869
    71
    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
deba@869
    72
deba@869
    73
    /// \brief Instantiates an Elevator.
deba@869
    74
    ///
deba@869
    75
    /// This function instantiates an \ref Elevator.
deba@869
    76
    /// \param graph The graph for which we would like to define
deba@869
    77
    /// the elevator.
deba@869
    78
    /// \param max_level The maximum level of the elevator.
deba@869
    79
    static Elevator* createElevator(const Graph& graph, int max_level) {
deba@869
    80
      return new Elevator(graph, max_level);
deba@869
    81
    }
deba@869
    82
  };
deba@869
    83
deba@869
    84
  /// \ingroup matching
deba@869
    85
  ///
deba@869
    86
  /// \brief Max cardinality fractional matching
deba@869
    87
  ///
deba@869
    88
  /// This class provides an implementation of fractional matching
deba@869
    89
  /// algorithm based on push-relabel principle.
deba@869
    90
  ///
deba@869
    91
  /// The maximum cardinality fractional matching is a relaxation of the
deba@869
    92
  /// maximum cardinality matching problem where the odd set constraints
deba@869
    93
  /// are omitted.
deba@869
    94
  /// It can be formulated with the following linear program.
deba@869
    95
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
deba@869
    96
  /// \f[x_e \ge 0\quad \forall e\in E\f]
deba@869
    97
  /// \f[\max \sum_{e\in E}x_e\f]
deba@869
    98
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
deba@869
    99
  /// \f$X\f$. The result can be represented as the union of a
deba@869
   100
  /// matching with one value edges and a set of odd length cycles
deba@869
   101
  /// with half value edges.
deba@869
   102
  ///
deba@869
   103
  /// The algorithm calculates an optimal fractional matching and a
deba@869
   104
  /// barrier. The number of adjacents of any node set minus the size
deba@869
   105
  /// of node set is a lower bound on the uncovered nodes in the
deba@869
   106
  /// graph. For maximum matching a barrier is computed which
deba@869
   107
  /// maximizes this difference.
deba@869
   108
  ///
deba@869
   109
  /// The algorithm can be executed with the run() function.  After it
deba@869
   110
  /// the matching (the primal solution) and the barrier (the dual
deba@869
   111
  /// solution) can be obtained using the query functions.
deba@869
   112
  ///
deba@869
   113
  /// The primal solution is multiplied by
deba@871
   114
  /// \ref MaxFractionalMatching::primalScale "2".
deba@869
   115
  ///
deba@869
   116
  /// \tparam GR The undirected graph type the algorithm runs on.
deba@869
   117
#ifdef DOXYGEN
deba@869
   118
  template <typename GR, typename TR>
deba@869
   119
#else
deba@869
   120
  template <typename GR,
deba@869
   121
            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
deba@869
   122
#endif
deba@869
   123
  class MaxFractionalMatching {
deba@869
   124
  public:
deba@869
   125
deba@869
   126
    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
deba@869
   127
    /// class" of the algorithm.
deba@869
   128
    typedef TR Traits;
deba@869
   129
    /// The type of the graph the algorithm runs on.
deba@869
   130
    typedef typename TR::Graph Graph;
deba@869
   131
    /// The type of the matching map.
deba@869
   132
    typedef typename TR::MatchingMap MatchingMap;
deba@869
   133
    /// The type of the elevator.
deba@869
   134
    typedef typename TR::Elevator Elevator;
deba@869
   135
deba@869
   136
    /// \brief Scaling factor for primal solution
deba@869
   137
    ///
deba@869
   138
    /// Scaling factor for primal solution.
deba@869
   139
    static const int primalScale = 2;
deba@869
   140
deba@869
   141
  private:
deba@869
   142
deba@869
   143
    const Graph &_graph;
deba@869
   144
    int _node_num;
deba@869
   145
    bool _allow_loops;
deba@869
   146
    int _empty_level;
deba@869
   147
deba@869
   148
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
deba@869
   149
deba@869
   150
    bool _local_matching;
deba@869
   151
    MatchingMap *_matching;
deba@869
   152
deba@869
   153
    bool _local_level;
deba@869
   154
    Elevator *_level;
deba@869
   155
deba@869
   156
    typedef typename Graph::template NodeMap<int> InDegMap;
deba@869
   157
    InDegMap *_indeg;
deba@869
   158
deba@869
   159
    void createStructures() {
deba@869
   160
      _node_num = countNodes(_graph);
deba@869
   161
deba@869
   162
      if (!_matching) {
deba@869
   163
        _local_matching = true;
deba@869
   164
        _matching = Traits::createMatchingMap(_graph);
deba@869
   165
      }
deba@869
   166
      if (!_level) {
deba@869
   167
        _local_level = true;
deba@869
   168
        _level = Traits::createElevator(_graph, _node_num);
deba@869
   169
      }
deba@869
   170
      if (!_indeg) {
deba@869
   171
        _indeg = new InDegMap(_graph);
deba@869
   172
      }
deba@869
   173
    }
deba@869
   174
deba@869
   175
    void destroyStructures() {
deba@869
   176
      if (_local_matching) {
deba@869
   177
        delete _matching;
deba@869
   178
      }
deba@869
   179
      if (_local_level) {
deba@869
   180
        delete _level;
deba@869
   181
      }
deba@869
   182
      if (_indeg) {
deba@869
   183
        delete _indeg;
deba@869
   184
      }
deba@869
   185
    }
deba@869
   186
deba@869
   187
    void postprocessing() {
deba@869
   188
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   189
        if ((*_indeg)[n] != 0) continue;
deba@869
   190
        _indeg->set(n, -1);
deba@869
   191
        Node u = n;
deba@869
   192
        while ((*_matching)[u] != INVALID) {
deba@869
   193
          Node v = _graph.target((*_matching)[u]);
deba@869
   194
          _indeg->set(v, -1);
deba@869
   195
          Arc a = _graph.oppositeArc((*_matching)[u]);
deba@869
   196
          u = _graph.target((*_matching)[v]);
deba@869
   197
          _indeg->set(u, -1);
deba@869
   198
          _matching->set(v, a);
deba@869
   199
        }
deba@869
   200
      }
deba@869
   201
deba@869
   202
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   203
        if ((*_indeg)[n] != 1) continue;
deba@869
   204
        _indeg->set(n, -1);
deba@869
   205
deba@869
   206
        int num = 1;
deba@869
   207
        Node u = _graph.target((*_matching)[n]);
deba@869
   208
        while (u != n) {
deba@869
   209
          _indeg->set(u, -1);
deba@869
   210
          u = _graph.target((*_matching)[u]);
deba@869
   211
          ++num;
deba@869
   212
        }
deba@869
   213
        if (num % 2 == 0 && num > 2) {
deba@869
   214
          Arc prev = _graph.oppositeArc((*_matching)[n]);
deba@869
   215
          Node v = _graph.target((*_matching)[n]);
deba@869
   216
          u = _graph.target((*_matching)[v]);
deba@869
   217
          _matching->set(v, prev);
deba@869
   218
          while (u != n) {
deba@869
   219
            prev = _graph.oppositeArc((*_matching)[u]);
deba@869
   220
            v = _graph.target((*_matching)[u]);
deba@869
   221
            u = _graph.target((*_matching)[v]);
deba@869
   222
            _matching->set(v, prev);
deba@869
   223
          }
deba@869
   224
        }
deba@869
   225
      }
deba@869
   226
    }
deba@869
   227
deba@869
   228
  public:
deba@869
   229
deba@869
   230
    typedef MaxFractionalMatching Create;
deba@869
   231
deba@869
   232
    ///\name Named Template Parameters
deba@869
   233
deba@869
   234
    ///@{
deba@869
   235
deba@869
   236
    template <typename T>
deba@869
   237
    struct SetMatchingMapTraits : public Traits {
deba@869
   238
      typedef T MatchingMap;
deba@869
   239
      static MatchingMap *createMatchingMap(const Graph&) {
deba@869
   240
        LEMON_ASSERT(false, "MatchingMap is not initialized");
deba@869
   241
        return 0; // ignore warnings
deba@869
   242
      }
deba@869
   243
    };
deba@869
   244
deba@869
   245
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@869
   246
    /// MatchingMap type
deba@869
   247
    ///
deba@869
   248
    /// \ref named-templ-param "Named parameter" for setting MatchingMap
deba@869
   249
    /// type.
deba@869
   250
    template <typename T>
deba@869
   251
    struct SetMatchingMap
deba@869
   252
      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
deba@869
   253
      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
deba@869
   254
    };
deba@869
   255
deba@869
   256
    template <typename T>
deba@869
   257
    struct SetElevatorTraits : public Traits {
deba@869
   258
      typedef T Elevator;
deba@869
   259
      static Elevator *createElevator(const Graph&, int) {
deba@869
   260
        LEMON_ASSERT(false, "Elevator is not initialized");
deba@869
   261
        return 0; // ignore warnings
deba@869
   262
      }
deba@869
   263
    };
deba@869
   264
deba@869
   265
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@869
   266
    /// Elevator type
deba@869
   267
    ///
deba@869
   268
    /// \ref named-templ-param "Named parameter" for setting Elevator
deba@869
   269
    /// type. If this named parameter is used, then an external
deba@869
   270
    /// elevator object must be passed to the algorithm using the
deba@869
   271
    /// \ref elevator(Elevator&) "elevator()" function before calling
deba@869
   272
    /// \ref run() or \ref init().
deba@869
   273
    /// \sa SetStandardElevator
deba@869
   274
    template <typename T>
deba@869
   275
    struct SetElevator
deba@869
   276
      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
deba@869
   277
      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
deba@869
   278
    };
deba@869
   279
deba@869
   280
    template <typename T>
deba@869
   281
    struct SetStandardElevatorTraits : public Traits {
deba@869
   282
      typedef T Elevator;
deba@869
   283
      static Elevator *createElevator(const Graph& graph, int max_level) {
deba@869
   284
        return new Elevator(graph, max_level);
deba@869
   285
      }
deba@869
   286
    };
deba@869
   287
deba@869
   288
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@869
   289
    /// Elevator type with automatic allocation
deba@869
   290
    ///
deba@869
   291
    /// \ref named-templ-param "Named parameter" for setting Elevator
deba@869
   292
    /// type with automatic allocation.
deba@869
   293
    /// The Elevator should have standard constructor interface to be
deba@869
   294
    /// able to automatically created by the algorithm (i.e. the
deba@869
   295
    /// graph and the maximum level should be passed to it).
deba@869
   296
    /// However an external elevator object could also be passed to the
deba@869
   297
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
deba@869
   298
    /// before calling \ref run() or \ref init().
deba@869
   299
    /// \sa SetElevator
deba@869
   300
    template <typename T>
deba@869
   301
    struct SetStandardElevator
deba@869
   302
      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
deba@869
   303
      typedef MaxFractionalMatching<Graph,
deba@869
   304
                                    SetStandardElevatorTraits<T> > Create;
deba@869
   305
    };
deba@869
   306
deba@869
   307
    /// @}
deba@869
   308
deba@869
   309
  protected:
deba@869
   310
deba@869
   311
    MaxFractionalMatching() {}
deba@869
   312
deba@869
   313
  public:
deba@869
   314
deba@869
   315
    /// \brief Constructor
deba@869
   316
    ///
deba@869
   317
    /// Constructor.
deba@869
   318
    ///
deba@869
   319
    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
deba@869
   320
      : _graph(graph), _allow_loops(allow_loops),
deba@869
   321
        _local_matching(false), _matching(0),
deba@869
   322
        _local_level(false), _level(0),  _indeg(0)
deba@869
   323
    {}
deba@869
   324
deba@869
   325
    ~MaxFractionalMatching() {
deba@869
   326
      destroyStructures();
deba@869
   327
    }
deba@869
   328
deba@869
   329
    /// \brief Sets the matching map.
deba@869
   330
    ///
deba@869
   331
    /// Sets the matching map.
deba@869
   332
    /// If you don't use this function before calling \ref run() or
deba@869
   333
    /// \ref init(), an instance will be allocated automatically.
deba@869
   334
    /// The destructor deallocates this automatically allocated map,
deba@869
   335
    /// of course.
deba@869
   336
    /// \return <tt>(*this)</tt>
deba@869
   337
    MaxFractionalMatching& matchingMap(MatchingMap& map) {
deba@869
   338
      if (_local_matching) {
deba@869
   339
        delete _matching;
deba@869
   340
        _local_matching = false;
deba@869
   341
      }
deba@869
   342
      _matching = &map;
deba@869
   343
      return *this;
deba@869
   344
    }
deba@869
   345
deba@869
   346
    /// \brief Sets the elevator used by algorithm.
deba@869
   347
    ///
deba@869
   348
    /// Sets the elevator used by algorithm.
deba@869
   349
    /// If you don't use this function before calling \ref run() or
deba@869
   350
    /// \ref init(), an instance will be allocated automatically.
deba@869
   351
    /// The destructor deallocates this automatically allocated elevator,
deba@869
   352
    /// of course.
deba@869
   353
    /// \return <tt>(*this)</tt>
deba@869
   354
    MaxFractionalMatching& elevator(Elevator& elevator) {
deba@869
   355
      if (_local_level) {
deba@869
   356
        delete _level;
deba@869
   357
        _local_level = false;
deba@869
   358
      }
deba@869
   359
      _level = &elevator;
deba@869
   360
      return *this;
deba@869
   361
    }
deba@869
   362
deba@869
   363
    /// \brief Returns a const reference to the elevator.
deba@869
   364
    ///
deba@869
   365
    /// Returns a const reference to the elevator.
deba@869
   366
    ///
deba@869
   367
    /// \pre Either \ref run() or \ref init() must be called before
deba@869
   368
    /// using this function.
deba@869
   369
    const Elevator& elevator() const {
deba@869
   370
      return *_level;
deba@869
   371
    }
deba@869
   372
deba@869
   373
    /// \name Execution control
deba@869
   374
    /// The simplest way to execute the algorithm is to use one of the
deba@869
   375
    /// member functions called \c run(). \n
deba@869
   376
    /// If you need more control on the execution, first
deba@869
   377
    /// you must call \ref init() and then one variant of the start()
deba@869
   378
    /// member.
deba@869
   379
deba@869
   380
    /// @{
deba@869
   381
deba@869
   382
    /// \brief Initializes the internal data structures.
deba@869
   383
    ///
deba@869
   384
    /// Initializes the internal data structures and sets the initial
deba@869
   385
    /// matching.
deba@869
   386
    void init() {
deba@869
   387
      createStructures();
deba@869
   388
deba@869
   389
      _level->initStart();
deba@869
   390
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   391
        _indeg->set(n, 0);
deba@869
   392
        _matching->set(n, INVALID);
deba@869
   393
        _level->initAddItem(n);
deba@869
   394
      }
deba@869
   395
      _level->initFinish();
deba@869
   396
deba@869
   397
      _empty_level = _node_num;
deba@869
   398
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   399
        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
deba@869
   400
          if (_graph.target(a) == n && !_allow_loops) continue;
deba@869
   401
          _matching->set(n, a);
deba@869
   402
          Node v = _graph.target((*_matching)[n]);
deba@869
   403
          _indeg->set(v, (*_indeg)[v] + 1);
deba@869
   404
          break;
deba@869
   405
        }
deba@869
   406
      }
deba@869
   407
deba@869
   408
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   409
        if ((*_indeg)[n] == 0) {
deba@869
   410
          _level->activate(n);
deba@869
   411
        }
deba@869
   412
      }
deba@869
   413
    }
deba@869
   414
deba@869
   415
    /// \brief Starts the algorithm and computes a fractional matching
deba@869
   416
    ///
deba@869
   417
    /// The algorithm computes a maximum fractional matching.
deba@869
   418
    ///
deba@869
   419
    /// \param postprocess The algorithm computes first a matching
deba@869
   420
    /// which is a union of a matching with one value edges, cycles
deba@869
   421
    /// with half value edges and even length paths with half value
deba@869
   422
    /// edges. If the parameter is true, then after the push-relabel
deba@869
   423
    /// algorithm it postprocesses the matching to contain only
deba@869
   424
    /// matching edges and half value odd cycles.
deba@869
   425
    void start(bool postprocess = true) {
deba@869
   426
      Node n;
deba@869
   427
      while ((n = _level->highestActive()) != INVALID) {
deba@869
   428
        int level = _level->highestActiveLevel();
deba@869
   429
        int new_level = _level->maxLevel();
deba@869
   430
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
deba@869
   431
          Node u = _graph.source(a);
deba@869
   432
          if (n == u && !_allow_loops) continue;
deba@869
   433
          Node v = _graph.target((*_matching)[u]);
deba@869
   434
          if ((*_level)[v] < level) {
deba@869
   435
            _indeg->set(v, (*_indeg)[v] - 1);
deba@869
   436
            if ((*_indeg)[v] == 0) {
deba@869
   437
              _level->activate(v);
deba@869
   438
            }
deba@869
   439
            _matching->set(u, a);
deba@869
   440
            _indeg->set(n, (*_indeg)[n] + 1);
deba@869
   441
            _level->deactivate(n);
deba@869
   442
            goto no_more_push;
deba@869
   443
          } else if (new_level > (*_level)[v]) {
deba@869
   444
            new_level = (*_level)[v];
deba@869
   445
          }
deba@869
   446
        }
deba@869
   447
deba@869
   448
        if (new_level + 1 < _level->maxLevel()) {
deba@869
   449
          _level->liftHighestActive(new_level + 1);
deba@869
   450
        } else {
deba@869
   451
          _level->liftHighestActiveToTop();
deba@869
   452
        }
deba@869
   453
        if (_level->emptyLevel(level)) {
deba@869
   454
          _level->liftToTop(level);
deba@869
   455
        }
deba@869
   456
      no_more_push:
deba@869
   457
        ;
deba@869
   458
      }
deba@869
   459
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   460
        if ((*_matching)[n] == INVALID) continue;
deba@869
   461
        Node u = _graph.target((*_matching)[n]);
deba@869
   462
        if ((*_indeg)[u] > 1) {
deba@869
   463
          _indeg->set(u, (*_indeg)[u] - 1);
deba@869
   464
          _matching->set(n, INVALID);
deba@869
   465
        }
deba@869
   466
      }
deba@869
   467
      if (postprocess) {
deba@869
   468
        postprocessing();
deba@869
   469
      }
deba@869
   470
    }
deba@869
   471
deba@869
   472
    /// \brief Starts the algorithm and computes a perfect fractional
deba@869
   473
    /// matching
deba@869
   474
    ///
deba@869
   475
    /// The algorithm computes a perfect fractional matching. If it
deba@869
   476
    /// does not exists, then the algorithm returns false and the
deba@869
   477
    /// matching is undefined and the barrier.
deba@869
   478
    ///
deba@869
   479
    /// \param postprocess The algorithm computes first a matching
deba@869
   480
    /// which is a union of a matching with one value edges, cycles
deba@869
   481
    /// with half value edges and even length paths with half value
deba@869
   482
    /// edges. If the parameter is true, then after the push-relabel
deba@869
   483
    /// algorithm it postprocesses the matching to contain only
deba@869
   484
    /// matching edges and half value odd cycles.
deba@869
   485
    bool startPerfect(bool postprocess = true) {
deba@869
   486
      Node n;
deba@869
   487
      while ((n = _level->highestActive()) != INVALID) {
deba@869
   488
        int level = _level->highestActiveLevel();
deba@869
   489
        int new_level = _level->maxLevel();
deba@869
   490
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
deba@869
   491
          Node u = _graph.source(a);
deba@869
   492
          if (n == u && !_allow_loops) continue;
deba@869
   493
          Node v = _graph.target((*_matching)[u]);
deba@869
   494
          if ((*_level)[v] < level) {
deba@869
   495
            _indeg->set(v, (*_indeg)[v] - 1);
deba@869
   496
            if ((*_indeg)[v] == 0) {
deba@869
   497
              _level->activate(v);
deba@869
   498
            }
deba@869
   499
            _matching->set(u, a);
deba@869
   500
            _indeg->set(n, (*_indeg)[n] + 1);
deba@869
   501
            _level->deactivate(n);
deba@869
   502
            goto no_more_push;
deba@869
   503
          } else if (new_level > (*_level)[v]) {
deba@869
   504
            new_level = (*_level)[v];
deba@869
   505
          }
deba@869
   506
        }
deba@869
   507
deba@869
   508
        if (new_level + 1 < _level->maxLevel()) {
deba@869
   509
          _level->liftHighestActive(new_level + 1);
deba@869
   510
        } else {
deba@869
   511
          _level->liftHighestActiveToTop();
deba@869
   512
          _empty_level = _level->maxLevel() - 1;
deba@869
   513
          return false;
deba@869
   514
        }
deba@869
   515
        if (_level->emptyLevel(level)) {
deba@869
   516
          _level->liftToTop(level);
deba@869
   517
          _empty_level = level;
deba@869
   518
          return false;
deba@869
   519
        }
deba@869
   520
      no_more_push:
deba@869
   521
        ;
deba@869
   522
      }
deba@869
   523
      if (postprocess) {
deba@869
   524
        postprocessing();
deba@869
   525
      }
deba@869
   526
      return true;
deba@869
   527
    }
deba@869
   528
deba@869
   529
    /// \brief Runs the algorithm
deba@869
   530
    ///
deba@869
   531
    /// Just a shortcut for the next code:
deba@869
   532
    ///\code
deba@869
   533
    /// init();
deba@869
   534
    /// start();
deba@869
   535
    ///\endcode
deba@869
   536
    void run(bool postprocess = true) {
deba@869
   537
      init();
deba@869
   538
      start(postprocess);
deba@869
   539
    }
deba@869
   540
deba@869
   541
    /// \brief Runs the algorithm to find a perfect fractional matching
deba@869
   542
    ///
deba@869
   543
    /// Just a shortcut for the next code:
deba@869
   544
    ///\code
deba@869
   545
    /// init();
deba@869
   546
    /// startPerfect();
deba@869
   547
    ///\endcode
deba@869
   548
    bool runPerfect(bool postprocess = true) {
deba@869
   549
      init();
deba@869
   550
      return startPerfect(postprocess);
deba@869
   551
    }
deba@869
   552
deba@869
   553
    ///@}
deba@869
   554
deba@869
   555
    /// \name Query Functions
deba@869
   556
    /// The result of the %Matching algorithm can be obtained using these
deba@869
   557
    /// functions.\n
deba@869
   558
    /// Before the use of these functions,
deba@869
   559
    /// either run() or start() must be called.
deba@869
   560
    ///@{
deba@869
   561
deba@869
   562
deba@869
   563
    /// \brief Return the number of covered nodes in the matching.
deba@869
   564
    ///
deba@869
   565
    /// This function returns the number of covered nodes in the matching.
deba@869
   566
    ///
deba@869
   567
    /// \pre Either run() or start() must be called before using this function.
deba@869
   568
    int matchingSize() const {
deba@869
   569
      int num = 0;
deba@869
   570
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
   571
        if ((*_matching)[n] != INVALID) {
deba@869
   572
          ++num;
deba@869
   573
        }
deba@869
   574
      }
deba@869
   575
      return num;
deba@869
   576
    }
deba@869
   577
deba@869
   578
    /// \brief Returns a const reference to the matching map.
deba@869
   579
    ///
deba@869
   580
    /// Returns a const reference to the node map storing the found
deba@869
   581
    /// fractional matching. This method can be called after
deba@869
   582
    /// running the algorithm.
deba@869
   583
    ///
deba@869
   584
    /// \pre Either \ref run() or \ref init() must be called before
deba@869
   585
    /// using this function.
deba@869
   586
    const MatchingMap& matchingMap() const {
deba@869
   587
      return *_matching;
deba@869
   588
    }
deba@869
   589
deba@869
   590
    /// \brief Return \c true if the given edge is in the matching.
deba@869
   591
    ///
deba@869
   592
    /// This function returns \c true if the given edge is in the
deba@869
   593
    /// found matching. The result is scaled by \ref primalScale
deba@869
   594
    /// "primal scale".
deba@869
   595
    ///
deba@869
   596
    /// \pre Either run() or start() must be called before using this function.
deba@869
   597
    int matching(const Edge& edge) const {
deba@869
   598
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
deba@869
   599
        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
deba@869
   600
    }
deba@869
   601
deba@869
   602
    /// \brief Return the fractional matching arc (or edge) incident
deba@869
   603
    /// to the given node.
deba@869
   604
    ///
deba@869
   605
    /// This function returns one of the fractional matching arc (or
deba@869
   606
    /// edge) incident to the given node in the found matching or \c
deba@869
   607
    /// INVALID if the node is not covered by the matching or if the
deba@869
   608
    /// node is on an odd length cycle then it is the successor edge
deba@869
   609
    /// on the cycle.
deba@869
   610
    ///
deba@869
   611
    /// \pre Either run() or start() must be called before using this function.
deba@869
   612
    Arc matching(const Node& node) const {
deba@869
   613
      return (*_matching)[node];
deba@869
   614
    }
deba@869
   615
deba@869
   616
    /// \brief Returns true if the node is in the barrier
deba@869
   617
    ///
deba@869
   618
    /// The barrier is a subset of the nodes. If the nodes in the
deba@869
   619
    /// barrier have less adjacent nodes than the size of the barrier,
deba@869
   620
    /// then at least as much nodes cannot be covered as the
deba@869
   621
    /// difference of the two subsets.
deba@869
   622
    bool barrier(const Node& node) const {
deba@869
   623
      return (*_level)[node] >= _empty_level;
deba@869
   624
    }
deba@869
   625
deba@869
   626
    /// @}
deba@869
   627
deba@869
   628
  };
deba@869
   629
deba@869
   630
  /// \ingroup matching
deba@869
   631
  ///
deba@869
   632
  /// \brief Weighted fractional matching in general graphs
deba@869
   633
  ///
deba@869
   634
  /// This class provides an efficient implementation of fractional
deba@871
   635
  /// matching algorithm. The implementation uses priority queues and
deba@871
   636
  /// provides \f$O(nm\log n)\f$ time complexity.
deba@869
   637
  ///
deba@869
   638
  /// The maximum weighted fractional matching is a relaxation of the
deba@869
   639
  /// maximum weighted matching problem where the odd set constraints
deba@869
   640
  /// are omitted.
deba@869
   641
  /// It can be formulated with the following linear program.
deba@869
   642
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
deba@869
   643
  /// \f[x_e \ge 0\quad \forall e\in E\f]
deba@869
   644
  /// \f[\max \sum_{e\in E}x_ew_e\f]
deba@869
   645
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
deba@869
   646
  /// \f$X\f$. The result must be the union of a matching with one
deba@869
   647
  /// value edges and a set of odd length cycles with half value edges.
deba@869
   648
  ///
deba@869
   649
  /// The algorithm calculates an optimal fractional matching and a
deba@869
   650
  /// proof of the optimality. The solution of the dual problem can be
deba@869
   651
  /// used to check the result of the algorithm. The dual linear
deba@869
   652
  /// problem is the following.
deba@869
   653
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
deba@869
   654
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
deba@871
   655
  /// \f[\min \sum_{u \in V}y_u \f]
deba@869
   656
  ///
deba@869
   657
  /// The algorithm can be executed with the run() function.
deba@869
   658
  /// After it the matching (the primal solution) and the dual solution
deba@869
   659
  /// can be obtained using the query functions.
deba@869
   660
  ///
deba@869
   661
  /// If the value type is integer, then the primal and the dual
deba@869
   662
  /// solutions are multiplied by
deba@871
   663
  /// \ref MaxWeightedFractionalMatching::primalScale "2" and
deba@871
   664
  /// \ref MaxWeightedFractionalMatching::dualScale "4" respectively.
deba@869
   665
  ///
deba@869
   666
  /// \tparam GR The undirected graph type the algorithm runs on.
deba@869
   667
  /// \tparam WM The type edge weight map. The default type is
deba@869
   668
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
deba@869
   669
#ifdef DOXYGEN
deba@869
   670
  template <typename GR, typename WM>
deba@869
   671
#else
deba@869
   672
  template <typename GR,
deba@869
   673
            typename WM = typename GR::template EdgeMap<int> >
deba@869
   674
#endif
deba@869
   675
  class MaxWeightedFractionalMatching {
deba@869
   676
  public:
deba@869
   677
deba@869
   678
    /// The graph type of the algorithm
deba@869
   679
    typedef GR Graph;
deba@869
   680
    /// The type of the edge weight map
deba@869
   681
    typedef WM WeightMap;
deba@869
   682
    /// The value type of the edge weights
deba@869
   683
    typedef typename WeightMap::Value Value;
deba@869
   684
deba@869
   685
    /// The type of the matching map
deba@869
   686
    typedef typename Graph::template NodeMap<typename Graph::Arc>
deba@869
   687
    MatchingMap;
deba@869
   688
deba@869
   689
    /// \brief Scaling factor for primal solution
deba@869
   690
    ///
deba@869
   691
    /// Scaling factor for primal solution. It is equal to 2 or 1
deba@869
   692
    /// according to the value type.
deba@869
   693
    static const int primalScale =
deba@869
   694
      std::numeric_limits<Value>::is_integer ? 2 : 1;
deba@869
   695
deba@869
   696
    /// \brief Scaling factor for dual solution
deba@869
   697
    ///
deba@869
   698
    /// Scaling factor for dual solution. It is equal to 4 or 1
deba@869
   699
    /// according to the value type.
deba@869
   700
    static const int dualScale =
deba@869
   701
      std::numeric_limits<Value>::is_integer ? 4 : 1;
deba@869
   702
deba@869
   703
  private:
deba@869
   704
deba@869
   705
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
deba@869
   706
deba@869
   707
    typedef typename Graph::template NodeMap<Value> NodePotential;
deba@869
   708
deba@869
   709
    const Graph& _graph;
deba@869
   710
    const WeightMap& _weight;
deba@869
   711
deba@869
   712
    MatchingMap* _matching;
deba@869
   713
    NodePotential* _node_potential;
deba@869
   714
deba@869
   715
    int _node_num;
deba@869
   716
    bool _allow_loops;
deba@869
   717
deba@869
   718
    enum Status {
deba@869
   719
      EVEN = -1, MATCHED = 0, ODD = 1
deba@869
   720
    };
deba@869
   721
deba@869
   722
    typedef typename Graph::template NodeMap<Status> StatusMap;
deba@869
   723
    StatusMap* _status;
deba@869
   724
deba@869
   725
    typedef typename Graph::template NodeMap<Arc> PredMap;
deba@869
   726
    PredMap* _pred;
deba@869
   727
deba@869
   728
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
deba@869
   729
deba@869
   730
    IntNodeMap *_tree_set_index;
deba@869
   731
    TreeSet *_tree_set;
deba@869
   732
deba@869
   733
    IntNodeMap *_delta1_index;
deba@869
   734
    BinHeap<Value, IntNodeMap> *_delta1;
deba@869
   735
deba@869
   736
    IntNodeMap *_delta2_index;
deba@869
   737
    BinHeap<Value, IntNodeMap> *_delta2;
deba@869
   738
deba@869
   739
    IntEdgeMap *_delta3_index;
deba@869
   740
    BinHeap<Value, IntEdgeMap> *_delta3;
deba@869
   741
deba@869
   742
    Value _delta_sum;
deba@869
   743
deba@869
   744
    void createStructures() {
deba@869
   745
      _node_num = countNodes(_graph);
deba@869
   746
deba@869
   747
      if (!_matching) {
deba@869
   748
        _matching = new MatchingMap(_graph);
deba@869
   749
      }
deba@869
   750
      if (!_node_potential) {
deba@869
   751
        _node_potential = new NodePotential(_graph);
deba@869
   752
      }
deba@869
   753
      if (!_status) {
deba@869
   754
        _status = new StatusMap(_graph);
deba@869
   755
      }
deba@869
   756
      if (!_pred) {
deba@869
   757
        _pred = new PredMap(_graph);
deba@869
   758
      }
deba@869
   759
      if (!_tree_set) {
deba@869
   760
        _tree_set_index = new IntNodeMap(_graph);
deba@869
   761
        _tree_set = new TreeSet(*_tree_set_index);
deba@869
   762
      }
deba@869
   763
      if (!_delta1) {
deba@869
   764
        _delta1_index = new IntNodeMap(_graph);
deba@869
   765
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
deba@869
   766
      }
deba@869
   767
      if (!_delta2) {
deba@869
   768
        _delta2_index = new IntNodeMap(_graph);
deba@869
   769
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
deba@869
   770
      }
deba@869
   771
      if (!_delta3) {
deba@869
   772
        _delta3_index = new IntEdgeMap(_graph);
deba@869
   773
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
deba@869
   774
      }
deba@869
   775
    }
deba@869
   776
deba@869
   777
    void destroyStructures() {
deba@869
   778
      if (_matching) {
deba@869
   779
        delete _matching;
deba@869
   780
      }
deba@869
   781
      if (_node_potential) {
deba@869
   782
        delete _node_potential;
deba@869
   783
      }
deba@869
   784
      if (_status) {
deba@869
   785
        delete _status;
deba@869
   786
      }
deba@869
   787
      if (_pred) {
deba@869
   788
        delete _pred;
deba@869
   789
      }
deba@869
   790
      if (_tree_set) {
deba@869
   791
        delete _tree_set_index;
deba@869
   792
        delete _tree_set;
deba@869
   793
      }
deba@869
   794
      if (_delta1) {
deba@869
   795
        delete _delta1_index;
deba@869
   796
        delete _delta1;
deba@869
   797
      }
deba@869
   798
      if (_delta2) {
deba@869
   799
        delete _delta2_index;
deba@869
   800
        delete _delta2;
deba@869
   801
      }
deba@869
   802
      if (_delta3) {
deba@869
   803
        delete _delta3_index;
deba@869
   804
        delete _delta3;
deba@869
   805
      }
deba@869
   806
    }
deba@869
   807
deba@869
   808
    void matchedToEven(Node node, int tree) {
deba@869
   809
      _tree_set->insert(node, tree);
deba@869
   810
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
   811
      _delta1->push(node, (*_node_potential)[node]);
deba@869
   812
deba@869
   813
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
   814
        _delta2->erase(node);
deba@869
   815
      }
deba@869
   816
deba@869
   817
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
   818
        Node v = _graph.source(a);
deba@869
   819
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
   820
          dualScale * _weight[a];
deba@869
   821
        if (node == v) {
deba@869
   822
          if (_allow_loops && _graph.direction(a)) {
deba@869
   823
            _delta3->push(a, rw / 2);
deba@869
   824
          }
deba@869
   825
        } else if ((*_status)[v] == EVEN) {
deba@869
   826
          _delta3->push(a, rw / 2);
deba@869
   827
        } else if ((*_status)[v] == MATCHED) {
deba@869
   828
          if (_delta2->state(v) != _delta2->IN_HEAP) {
deba@869
   829
            _pred->set(v, a);
deba@869
   830
            _delta2->push(v, rw);
deba@869
   831
          } else if ((*_delta2)[v] > rw) {
deba@869
   832
            _pred->set(v, a);
deba@869
   833
            _delta2->decrease(v, rw);
deba@869
   834
          }
deba@869
   835
        }
deba@869
   836
      }
deba@869
   837
    }
deba@869
   838
deba@869
   839
    void matchedToOdd(Node node, int tree) {
deba@869
   840
      _tree_set->insert(node, tree);
deba@869
   841
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
   842
deba@869
   843
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
   844
        _delta2->erase(node);
deba@869
   845
      }
deba@869
   846
    }
deba@869
   847
deba@869
   848
    void evenToMatched(Node node, int tree) {
deba@869
   849
      _delta1->erase(node);
deba@869
   850
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
   851
      Arc min = INVALID;
deba@869
   852
      Value minrw = std::numeric_limits<Value>::max();
deba@869
   853
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
   854
        Node v = _graph.source(a);
deba@869
   855
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
   856
          dualScale * _weight[a];
deba@869
   857
deba@869
   858
        if (node == v) {
deba@869
   859
          if (_allow_loops && _graph.direction(a)) {
deba@869
   860
            _delta3->erase(a);
deba@869
   861
          }
deba@869
   862
        } else if ((*_status)[v] == EVEN) {
deba@869
   863
          _delta3->erase(a);
deba@869
   864
          if (minrw > rw) {
deba@869
   865
            min = _graph.oppositeArc(a);
deba@869
   866
            minrw = rw;
deba@869
   867
          }
deba@869
   868
        } else if ((*_status)[v]  == MATCHED) {
deba@869
   869
          if ((*_pred)[v] == a) {
deba@869
   870
            Arc mina = INVALID;
deba@869
   871
            Value minrwa = std::numeric_limits<Value>::max();
deba@869
   872
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
deba@869
   873
              Node va = _graph.target(aa);
deba@869
   874
              if ((*_status)[va] != EVEN ||
deba@869
   875
                  _tree_set->find(va) == tree) continue;
deba@869
   876
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
deba@869
   877
                dualScale * _weight[aa];
deba@869
   878
              if (minrwa > rwa) {
deba@869
   879
                minrwa = rwa;
deba@869
   880
                mina = aa;
deba@869
   881
              }
deba@869
   882
            }
deba@869
   883
            if (mina != INVALID) {
deba@869
   884
              _pred->set(v, mina);
deba@869
   885
              _delta2->increase(v, minrwa);
deba@869
   886
            } else {
deba@869
   887
              _pred->set(v, INVALID);
deba@869
   888
              _delta2->erase(v);
deba@869
   889
            }
deba@869
   890
          }
deba@869
   891
        }
deba@869
   892
      }
deba@869
   893
      if (min != INVALID) {
deba@869
   894
        _pred->set(node, min);
deba@869
   895
        _delta2->push(node, minrw);
deba@869
   896
      } else {
deba@869
   897
        _pred->set(node, INVALID);
deba@869
   898
      }
deba@869
   899
    }
deba@869
   900
deba@869
   901
    void oddToMatched(Node node) {
deba@869
   902
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
   903
      Arc min = INVALID;
deba@869
   904
      Value minrw = std::numeric_limits<Value>::max();
deba@869
   905
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
   906
        Node v = _graph.source(a);
deba@869
   907
        if ((*_status)[v] != EVEN) continue;
deba@869
   908
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
   909
          dualScale * _weight[a];
deba@869
   910
deba@869
   911
        if (minrw > rw) {
deba@869
   912
          min = _graph.oppositeArc(a);
deba@869
   913
          minrw = rw;
deba@869
   914
        }
deba@869
   915
      }
deba@869
   916
      if (min != INVALID) {
deba@869
   917
        _pred->set(node, min);
deba@869
   918
        _delta2->push(node, minrw);
deba@869
   919
      } else {
deba@869
   920
        _pred->set(node, INVALID);
deba@869
   921
      }
deba@869
   922
    }
deba@869
   923
deba@869
   924
    void alternatePath(Node even, int tree) {
deba@869
   925
      Node odd;
deba@869
   926
deba@869
   927
      _status->set(even, MATCHED);
deba@869
   928
      evenToMatched(even, tree);
deba@869
   929
deba@869
   930
      Arc prev = (*_matching)[even];
deba@869
   931
      while (prev != INVALID) {
deba@869
   932
        odd = _graph.target(prev);
deba@869
   933
        even = _graph.target((*_pred)[odd]);
deba@869
   934
        _matching->set(odd, (*_pred)[odd]);
deba@869
   935
        _status->set(odd, MATCHED);
deba@869
   936
        oddToMatched(odd);
deba@869
   937
deba@869
   938
        prev = (*_matching)[even];
deba@869
   939
        _status->set(even, MATCHED);
deba@869
   940
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
deba@869
   941
        evenToMatched(even, tree);
deba@869
   942
      }
deba@869
   943
    }
deba@869
   944
deba@869
   945
    void destroyTree(int tree) {
deba@869
   946
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
deba@869
   947
        if ((*_status)[n] == EVEN) {
deba@869
   948
          _status->set(n, MATCHED);
deba@869
   949
          evenToMatched(n, tree);
deba@869
   950
        } else if ((*_status)[n] == ODD) {
deba@869
   951
          _status->set(n, MATCHED);
deba@869
   952
          oddToMatched(n);
deba@869
   953
        }
deba@869
   954
      }
deba@869
   955
      _tree_set->eraseClass(tree);
deba@869
   956
    }
deba@869
   957
deba@869
   958
deba@869
   959
    void unmatchNode(const Node& node) {
deba@869
   960
      int tree = _tree_set->find(node);
deba@869
   961
deba@869
   962
      alternatePath(node, tree);
deba@869
   963
      destroyTree(tree);
deba@869
   964
deba@869
   965
      _matching->set(node, INVALID);
deba@869
   966
    }
deba@869
   967
deba@869
   968
deba@869
   969
    void augmentOnEdge(const Edge& edge) {
deba@869
   970
      Node left = _graph.u(edge);
deba@869
   971
      int left_tree = _tree_set->find(left);
deba@869
   972
deba@869
   973
      alternatePath(left, left_tree);
deba@869
   974
      destroyTree(left_tree);
deba@869
   975
      _matching->set(left, _graph.direct(edge, true));
deba@869
   976
deba@869
   977
      Node right = _graph.v(edge);
deba@869
   978
      int right_tree = _tree_set->find(right);
deba@869
   979
deba@869
   980
      alternatePath(right, right_tree);
deba@869
   981
      destroyTree(right_tree);
deba@869
   982
      _matching->set(right, _graph.direct(edge, false));
deba@869
   983
    }
deba@869
   984
deba@869
   985
    void augmentOnArc(const Arc& arc) {
deba@869
   986
      Node left = _graph.source(arc);
deba@869
   987
      _status->set(left, MATCHED);
deba@869
   988
      _matching->set(left, arc);
deba@869
   989
      _pred->set(left, arc);
deba@869
   990
deba@869
   991
      Node right = _graph.target(arc);
deba@869
   992
      int right_tree = _tree_set->find(right);
deba@869
   993
deba@869
   994
      alternatePath(right, right_tree);
deba@869
   995
      destroyTree(right_tree);
deba@869
   996
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
   997
    }
deba@869
   998
deba@869
   999
    void extendOnArc(const Arc& arc) {
deba@869
  1000
      Node base = _graph.target(arc);
deba@869
  1001
      int tree = _tree_set->find(base);
deba@869
  1002
deba@869
  1003
      Node odd = _graph.source(arc);
deba@869
  1004
      _tree_set->insert(odd, tree);
deba@869
  1005
      _status->set(odd, ODD);
deba@869
  1006
      matchedToOdd(odd, tree);
deba@869
  1007
      _pred->set(odd, arc);
deba@869
  1008
deba@869
  1009
      Node even = _graph.target((*_matching)[odd]);
deba@869
  1010
      _tree_set->insert(even, tree);
deba@869
  1011
      _status->set(even, EVEN);
deba@869
  1012
      matchedToEven(even, tree);
deba@869
  1013
    }
deba@869
  1014
deba@869
  1015
    void cycleOnEdge(const Edge& edge, int tree) {
deba@869
  1016
      Node nca = INVALID;
deba@869
  1017
      std::vector<Node> left_path, right_path;
deba@869
  1018
deba@869
  1019
      {
deba@869
  1020
        std::set<Node> left_set, right_set;
deba@869
  1021
        Node left = _graph.u(edge);
deba@869
  1022
        left_path.push_back(left);
deba@869
  1023
        left_set.insert(left);
deba@869
  1024
deba@869
  1025
        Node right = _graph.v(edge);
deba@869
  1026
        right_path.push_back(right);
deba@869
  1027
        right_set.insert(right);
deba@869
  1028
deba@869
  1029
        while (true) {
deba@869
  1030
deba@869
  1031
          if (left_set.find(right) != left_set.end()) {
deba@869
  1032
            nca = right;
deba@869
  1033
            break;
deba@869
  1034
          }
deba@869
  1035
deba@869
  1036
          if ((*_matching)[left] == INVALID) break;
deba@869
  1037
deba@869
  1038
          left = _graph.target((*_matching)[left]);
deba@869
  1039
          left_path.push_back(left);
deba@869
  1040
          left = _graph.target((*_pred)[left]);
deba@869
  1041
          left_path.push_back(left);
deba@869
  1042
deba@869
  1043
          left_set.insert(left);
deba@869
  1044
deba@869
  1045
          if (right_set.find(left) != right_set.end()) {
deba@869
  1046
            nca = left;
deba@869
  1047
            break;
deba@869
  1048
          }
deba@869
  1049
deba@869
  1050
          if ((*_matching)[right] == INVALID) break;
deba@869
  1051
deba@869
  1052
          right = _graph.target((*_matching)[right]);
deba@869
  1053
          right_path.push_back(right);
deba@869
  1054
          right = _graph.target((*_pred)[right]);
deba@869
  1055
          right_path.push_back(right);
deba@869
  1056
deba@869
  1057
          right_set.insert(right);
deba@869
  1058
deba@869
  1059
        }
deba@869
  1060
deba@869
  1061
        if (nca == INVALID) {
deba@869
  1062
          if ((*_matching)[left] == INVALID) {
deba@869
  1063
            nca = right;
deba@869
  1064
            while (left_set.find(nca) == left_set.end()) {
deba@869
  1065
              nca = _graph.target((*_matching)[nca]);
deba@869
  1066
              right_path.push_back(nca);
deba@869
  1067
              nca = _graph.target((*_pred)[nca]);
deba@869
  1068
              right_path.push_back(nca);
deba@869
  1069
            }
deba@869
  1070
          } else {
deba@869
  1071
            nca = left;
deba@869
  1072
            while (right_set.find(nca) == right_set.end()) {
deba@869
  1073
              nca = _graph.target((*_matching)[nca]);
deba@869
  1074
              left_path.push_back(nca);
deba@869
  1075
              nca = _graph.target((*_pred)[nca]);
deba@869
  1076
              left_path.push_back(nca);
deba@869
  1077
            }
deba@869
  1078
          }
deba@869
  1079
        }
deba@869
  1080
      }
deba@869
  1081
deba@869
  1082
      alternatePath(nca, tree);
deba@869
  1083
      Arc prev;
deba@869
  1084
deba@869
  1085
      prev = _graph.direct(edge, true);
deba@869
  1086
      for (int i = 0; left_path[i] != nca; i += 2) {
deba@869
  1087
        _matching->set(left_path[i], prev);
deba@869
  1088
        _status->set(left_path[i], MATCHED);
deba@869
  1089
        evenToMatched(left_path[i], tree);
deba@869
  1090
deba@869
  1091
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
deba@869
  1092
        _status->set(left_path[i + 1], MATCHED);
deba@869
  1093
        oddToMatched(left_path[i + 1]);
deba@869
  1094
      }
deba@869
  1095
      _matching->set(nca, prev);
deba@869
  1096
deba@869
  1097
      for (int i = 0; right_path[i] != nca; i += 2) {
deba@869
  1098
        _status->set(right_path[i], MATCHED);
deba@869
  1099
        evenToMatched(right_path[i], tree);
deba@869
  1100
deba@869
  1101
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
deba@869
  1102
        _status->set(right_path[i + 1], MATCHED);
deba@869
  1103
        oddToMatched(right_path[i + 1]);
deba@869
  1104
      }
deba@869
  1105
deba@869
  1106
      destroyTree(tree);
deba@869
  1107
    }
deba@869
  1108
deba@869
  1109
    void extractCycle(const Arc &arc) {
deba@869
  1110
      Node left = _graph.source(arc);
deba@869
  1111
      Node odd = _graph.target((*_matching)[left]);
deba@869
  1112
      Arc prev;
deba@869
  1113
      while (odd != left) {
deba@869
  1114
        Node even = _graph.target((*_matching)[odd]);
deba@869
  1115
        prev = (*_matching)[odd];
deba@869
  1116
        odd = _graph.target((*_matching)[even]);
deba@869
  1117
        _matching->set(even, _graph.oppositeArc(prev));
deba@869
  1118
      }
deba@869
  1119
      _matching->set(left, arc);
deba@869
  1120
deba@869
  1121
      Node right = _graph.target(arc);
deba@869
  1122
      int right_tree = _tree_set->find(right);
deba@869
  1123
      alternatePath(right, right_tree);
deba@869
  1124
      destroyTree(right_tree);
deba@869
  1125
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
  1126
    }
deba@869
  1127
deba@869
  1128
  public:
deba@869
  1129
deba@869
  1130
    /// \brief Constructor
deba@869
  1131
    ///
deba@869
  1132
    /// Constructor.
deba@869
  1133
    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
deba@869
  1134
                                  bool allow_loops = true)
deba@869
  1135
      : _graph(graph), _weight(weight), _matching(0),
deba@869
  1136
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
deba@869
  1137
      _status(0),  _pred(0),
deba@869
  1138
      _tree_set_index(0), _tree_set(0),
deba@869
  1139
deba@869
  1140
      _delta1_index(0), _delta1(0),
deba@869
  1141
      _delta2_index(0), _delta2(0),
deba@869
  1142
      _delta3_index(0), _delta3(0),
deba@869
  1143
deba@869
  1144
      _delta_sum() {}
deba@869
  1145
deba@869
  1146
    ~MaxWeightedFractionalMatching() {
deba@869
  1147
      destroyStructures();
deba@869
  1148
    }
deba@869
  1149
deba@869
  1150
    /// \name Execution Control
deba@869
  1151
    /// The simplest way to execute the algorithm is to use the
deba@869
  1152
    /// \ref run() member function.
deba@869
  1153
deba@869
  1154
    ///@{
deba@869
  1155
deba@869
  1156
    /// \brief Initialize the algorithm
deba@869
  1157
    ///
deba@869
  1158
    /// This function initializes the algorithm.
deba@869
  1159
    void init() {
deba@869
  1160
      createStructures();
deba@869
  1161
deba@869
  1162
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1163
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
deba@869
  1164
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
deba@869
  1165
      }
deba@869
  1166
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1167
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
deba@869
  1168
      }
deba@869
  1169
deba@869
  1170
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1171
        Value max = 0;
deba@869
  1172
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@869
  1173
          if (_graph.target(e) == n && !_allow_loops) continue;
deba@869
  1174
          if ((dualScale * _weight[e]) / 2 > max) {
deba@869
  1175
            max = (dualScale * _weight[e]) / 2;
deba@869
  1176
          }
deba@869
  1177
        }
deba@869
  1178
        _node_potential->set(n, max);
deba@869
  1179
        _delta1->push(n, max);
deba@869
  1180
deba@869
  1181
        _tree_set->insert(n);
deba@869
  1182
deba@869
  1183
        _matching->set(n, INVALID);
deba@869
  1184
        _status->set(n, EVEN);
deba@869
  1185
      }
deba@869
  1186
deba@869
  1187
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1188
        Node left = _graph.u(e);
deba@869
  1189
        Node right = _graph.v(e);
deba@869
  1190
        if (left == right && !_allow_loops) continue;
deba@869
  1191
        _delta3->push(e, ((*_node_potential)[left] +
deba@869
  1192
                          (*_node_potential)[right] -
deba@869
  1193
                          dualScale * _weight[e]) / 2);
deba@869
  1194
      }
deba@869
  1195
    }
deba@869
  1196
deba@869
  1197
    /// \brief Start the algorithm
deba@869
  1198
    ///
deba@869
  1199
    /// This function starts the algorithm.
deba@869
  1200
    ///
deba@869
  1201
    /// \pre \ref init() must be called before using this function.
deba@869
  1202
    void start() {
deba@869
  1203
      enum OpType {
deba@869
  1204
        D1, D2, D3
deba@869
  1205
      };
deba@869
  1206
deba@869
  1207
      int unmatched = _node_num;
deba@869
  1208
      while (unmatched > 0) {
deba@869
  1209
        Value d1 = !_delta1->empty() ?
deba@869
  1210
          _delta1->prio() : std::numeric_limits<Value>::max();
deba@869
  1211
deba@869
  1212
        Value d2 = !_delta2->empty() ?
deba@869
  1213
          _delta2->prio() : std::numeric_limits<Value>::max();
deba@869
  1214
deba@869
  1215
        Value d3 = !_delta3->empty() ?
deba@869
  1216
          _delta3->prio() : std::numeric_limits<Value>::max();
deba@869
  1217
deba@869
  1218
        _delta_sum = d3; OpType ot = D3;
deba@869
  1219
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
deba@869
  1220
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
deba@869
  1221
deba@869
  1222
        switch (ot) {
deba@869
  1223
        case D1:
deba@869
  1224
          {
deba@869
  1225
            Node n = _delta1->top();
deba@869
  1226
            unmatchNode(n);
deba@869
  1227
            --unmatched;
deba@869
  1228
          }
deba@869
  1229
          break;
deba@869
  1230
        case D2:
deba@869
  1231
          {
deba@869
  1232
            Node n = _delta2->top();
deba@869
  1233
            Arc a = (*_pred)[n];
deba@869
  1234
            if ((*_matching)[n] == INVALID) {
deba@869
  1235
              augmentOnArc(a);
deba@869
  1236
              --unmatched;
deba@869
  1237
            } else {
deba@869
  1238
              Node v = _graph.target((*_matching)[n]);
deba@869
  1239
              if ((*_matching)[n] !=
deba@869
  1240
                  _graph.oppositeArc((*_matching)[v])) {
deba@869
  1241
                extractCycle(a);
deba@869
  1242
                --unmatched;
deba@869
  1243
              } else {
deba@869
  1244
                extendOnArc(a);
deba@869
  1245
              }
deba@869
  1246
            }
deba@869
  1247
          } break;
deba@869
  1248
        case D3:
deba@869
  1249
          {
deba@869
  1250
            Edge e = _delta3->top();
deba@869
  1251
deba@869
  1252
            Node left = _graph.u(e);
deba@869
  1253
            Node right = _graph.v(e);
deba@869
  1254
deba@869
  1255
            int left_tree = _tree_set->find(left);
deba@869
  1256
            int right_tree = _tree_set->find(right);
deba@869
  1257
deba@869
  1258
            if (left_tree == right_tree) {
deba@869
  1259
              cycleOnEdge(e, left_tree);
deba@869
  1260
              --unmatched;
deba@869
  1261
            } else {
deba@869
  1262
              augmentOnEdge(e);
deba@869
  1263
              unmatched -= 2;
deba@869
  1264
            }
deba@869
  1265
          } break;
deba@869
  1266
        }
deba@869
  1267
      }
deba@869
  1268
    }
deba@869
  1269
deba@869
  1270
    /// \brief Run the algorithm.
deba@869
  1271
    ///
deba@871
  1272
    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
deba@869
  1273
    ///
deba@869
  1274
    /// \note mwfm.run() is just a shortcut of the following code.
deba@869
  1275
    /// \code
deba@869
  1276
    ///   mwfm.init();
deba@869
  1277
    ///   mwfm.start();
deba@869
  1278
    /// \endcode
deba@869
  1279
    void run() {
deba@869
  1280
      init();
deba@869
  1281
      start();
deba@869
  1282
    }
deba@869
  1283
deba@869
  1284
    /// @}
deba@869
  1285
deba@869
  1286
    /// \name Primal Solution
deba@869
  1287
    /// Functions to get the primal solution, i.e. the maximum weighted
deba@869
  1288
    /// matching.\n
deba@869
  1289
    /// Either \ref run() or \ref start() function should be called before
deba@869
  1290
    /// using them.
deba@869
  1291
deba@869
  1292
    /// @{
deba@869
  1293
deba@869
  1294
    /// \brief Return the weight of the matching.
deba@869
  1295
    ///
deba@869
  1296
    /// This function returns the weight of the found matching. This
deba@869
  1297
    /// value is scaled by \ref primalScale "primal scale".
deba@869
  1298
    ///
deba@869
  1299
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1300
    Value matchingWeight() const {
deba@869
  1301
      Value sum = 0;
deba@869
  1302
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1303
        if ((*_matching)[n] != INVALID) {
deba@869
  1304
          sum += _weight[(*_matching)[n]];
deba@869
  1305
        }
deba@869
  1306
      }
deba@869
  1307
      return sum * primalScale / 2;
deba@869
  1308
    }
deba@869
  1309
deba@869
  1310
    /// \brief Return the number of covered nodes in the matching.
deba@869
  1311
    ///
deba@869
  1312
    /// This function returns the number of covered nodes in the matching.
deba@869
  1313
    ///
deba@869
  1314
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1315
    int matchingSize() const {
deba@869
  1316
      int num = 0;
deba@869
  1317
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1318
        if ((*_matching)[n] != INVALID) {
deba@869
  1319
          ++num;
deba@869
  1320
        }
deba@869
  1321
      }
deba@869
  1322
      return num;
deba@869
  1323
    }
deba@869
  1324
deba@869
  1325
    /// \brief Return \c true if the given edge is in the matching.
deba@869
  1326
    ///
deba@869
  1327
    /// This function returns \c true if the given edge is in the
deba@869
  1328
    /// found matching. The result is scaled by \ref primalScale
deba@869
  1329
    /// "primal scale".
deba@869
  1330
    ///
deba@869
  1331
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1332
    Value matching(const Edge& edge) const {
deba@869
  1333
      return Value(edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
deba@869
  1334
        * primalScale / 2 + Value(edge == (*_matching)[_graph.v(edge)] ? 1 : 0)
deba@869
  1335
        * primalScale / 2;
deba@869
  1336
    }
deba@869
  1337
deba@869
  1338
    /// \brief Return the fractional matching arc (or edge) incident
deba@869
  1339
    /// to the given node.
deba@869
  1340
    ///
deba@869
  1341
    /// This function returns one of the fractional matching arc (or
deba@869
  1342
    /// edge) incident to the given node in the found matching or \c
deba@869
  1343
    /// INVALID if the node is not covered by the matching or if the
deba@869
  1344
    /// node is on an odd length cycle then it is the successor edge
deba@869
  1345
    /// on the cycle.
deba@869
  1346
    ///
deba@869
  1347
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1348
    Arc matching(const Node& node) const {
deba@869
  1349
      return (*_matching)[node];
deba@869
  1350
    }
deba@869
  1351
deba@869
  1352
    /// \brief Return a const reference to the matching map.
deba@869
  1353
    ///
deba@869
  1354
    /// This function returns a const reference to a node map that stores
deba@869
  1355
    /// the matching arc (or edge) incident to each node.
deba@869
  1356
    const MatchingMap& matchingMap() const {
deba@869
  1357
      return *_matching;
deba@869
  1358
    }
deba@869
  1359
deba@869
  1360
    /// @}
deba@869
  1361
deba@869
  1362
    /// \name Dual Solution
deba@869
  1363
    /// Functions to get the dual solution.\n
deba@869
  1364
    /// Either \ref run() or \ref start() function should be called before
deba@869
  1365
    /// using them.
deba@869
  1366
deba@869
  1367
    /// @{
deba@869
  1368
deba@869
  1369
    /// \brief Return the value of the dual solution.
deba@869
  1370
    ///
deba@869
  1371
    /// This function returns the value of the dual solution.
deba@869
  1372
    /// It should be equal to the primal value scaled by \ref dualScale
deba@869
  1373
    /// "dual scale".
deba@869
  1374
    ///
deba@869
  1375
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1376
    Value dualValue() const {
deba@869
  1377
      Value sum = 0;
deba@869
  1378
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1379
        sum += nodeValue(n);
deba@869
  1380
      }
deba@869
  1381
      return sum;
deba@869
  1382
    }
deba@869
  1383
deba@869
  1384
    /// \brief Return the dual value (potential) of the given node.
deba@869
  1385
    ///
deba@869
  1386
    /// This function returns the dual value (potential) of the given node.
deba@869
  1387
    ///
deba@869
  1388
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1389
    Value nodeValue(const Node& n) const {
deba@869
  1390
      return (*_node_potential)[n];
deba@869
  1391
    }
deba@869
  1392
deba@869
  1393
    /// @}
deba@869
  1394
deba@869
  1395
  };
deba@869
  1396
deba@869
  1397
  /// \ingroup matching
deba@869
  1398
  ///
deba@869
  1399
  /// \brief Weighted fractional perfect matching in general graphs
deba@869
  1400
  ///
deba@869
  1401
  /// This class provides an efficient implementation of fractional
deba@871
  1402
  /// matching algorithm. The implementation uses priority queues and
deba@871
  1403
  /// provides \f$O(nm\log n)\f$ time complexity.
deba@869
  1404
  ///
deba@869
  1405
  /// The maximum weighted fractional perfect matching is a relaxation
deba@869
  1406
  /// of the maximum weighted perfect matching problem where the odd
deba@869
  1407
  /// set constraints are omitted.
deba@869
  1408
  /// It can be formulated with the following linear program.
deba@869
  1409
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
deba@869
  1410
  /// \f[x_e \ge 0\quad \forall e\in E\f]
deba@869
  1411
  /// \f[\max \sum_{e\in E}x_ew_e\f]
deba@869
  1412
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
deba@869
  1413
  /// \f$X\f$. The result must be the union of a matching with one
deba@869
  1414
  /// value edges and a set of odd length cycles with half value edges.
deba@869
  1415
  ///
deba@869
  1416
  /// The algorithm calculates an optimal fractional matching and a
deba@869
  1417
  /// proof of the optimality. The solution of the dual problem can be
deba@869
  1418
  /// used to check the result of the algorithm. The dual linear
deba@869
  1419
  /// problem is the following.
deba@869
  1420
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
deba@871
  1421
  /// \f[\min \sum_{u \in V}y_u \f]
deba@869
  1422
  ///
deba@869
  1423
  /// The algorithm can be executed with the run() function.
deba@869
  1424
  /// After it the matching (the primal solution) and the dual solution
deba@869
  1425
  /// can be obtained using the query functions.
deba@869
  1426
deba@869
  1427
  /// If the value type is integer, then the primal and the dual
deba@869
  1428
  /// solutions are multiplied by
deba@871
  1429
  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2" and
deba@871
  1430
  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4" respectively.
deba@869
  1431
  ///
deba@869
  1432
  /// \tparam GR The undirected graph type the algorithm runs on.
deba@869
  1433
  /// \tparam WM The type edge weight map. The default type is
deba@869
  1434
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
deba@869
  1435
#ifdef DOXYGEN
deba@869
  1436
  template <typename GR, typename WM>
deba@869
  1437
#else
deba@869
  1438
  template <typename GR,
deba@869
  1439
            typename WM = typename GR::template EdgeMap<int> >
deba@869
  1440
#endif
deba@869
  1441
  class MaxWeightedPerfectFractionalMatching {
deba@869
  1442
  public:
deba@869
  1443
deba@869
  1444
    /// The graph type of the algorithm
deba@869
  1445
    typedef GR Graph;
deba@869
  1446
    /// The type of the edge weight map
deba@869
  1447
    typedef WM WeightMap;
deba@869
  1448
    /// The value type of the edge weights
deba@869
  1449
    typedef typename WeightMap::Value Value;
deba@869
  1450
deba@869
  1451
    /// The type of the matching map
deba@869
  1452
    typedef typename Graph::template NodeMap<typename Graph::Arc>
deba@869
  1453
    MatchingMap;
deba@869
  1454
deba@869
  1455
    /// \brief Scaling factor for primal solution
deba@869
  1456
    ///
deba@869
  1457
    /// Scaling factor for primal solution. It is equal to 2 or 1
deba@869
  1458
    /// according to the value type.
deba@869
  1459
    static const int primalScale =
deba@869
  1460
      std::numeric_limits<Value>::is_integer ? 2 : 1;
deba@869
  1461
deba@869
  1462
    /// \brief Scaling factor for dual solution
deba@869
  1463
    ///
deba@869
  1464
    /// Scaling factor for dual solution. It is equal to 4 or 1
deba@869
  1465
    /// according to the value type.
deba@869
  1466
    static const int dualScale =
deba@869
  1467
      std::numeric_limits<Value>::is_integer ? 4 : 1;
deba@869
  1468
deba@869
  1469
  private:
deba@869
  1470
deba@869
  1471
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
deba@869
  1472
deba@869
  1473
    typedef typename Graph::template NodeMap<Value> NodePotential;
deba@869
  1474
deba@869
  1475
    const Graph& _graph;
deba@869
  1476
    const WeightMap& _weight;
deba@869
  1477
deba@869
  1478
    MatchingMap* _matching;
deba@869
  1479
    NodePotential* _node_potential;
deba@869
  1480
deba@869
  1481
    int _node_num;
deba@869
  1482
    bool _allow_loops;
deba@869
  1483
deba@869
  1484
    enum Status {
deba@869
  1485
      EVEN = -1, MATCHED = 0, ODD = 1
deba@869
  1486
    };
deba@869
  1487
deba@869
  1488
    typedef typename Graph::template NodeMap<Status> StatusMap;
deba@869
  1489
    StatusMap* _status;
deba@869
  1490
deba@869
  1491
    typedef typename Graph::template NodeMap<Arc> PredMap;
deba@869
  1492
    PredMap* _pred;
deba@869
  1493
deba@869
  1494
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
deba@869
  1495
deba@869
  1496
    IntNodeMap *_tree_set_index;
deba@869
  1497
    TreeSet *_tree_set;
deba@869
  1498
deba@869
  1499
    IntNodeMap *_delta2_index;
deba@869
  1500
    BinHeap<Value, IntNodeMap> *_delta2;
deba@869
  1501
deba@869
  1502
    IntEdgeMap *_delta3_index;
deba@869
  1503
    BinHeap<Value, IntEdgeMap> *_delta3;
deba@869
  1504
deba@869
  1505
    Value _delta_sum;
deba@869
  1506
deba@869
  1507
    void createStructures() {
deba@869
  1508
      _node_num = countNodes(_graph);
deba@869
  1509
deba@869
  1510
      if (!_matching) {
deba@869
  1511
        _matching = new MatchingMap(_graph);
deba@869
  1512
      }
deba@869
  1513
      if (!_node_potential) {
deba@869
  1514
        _node_potential = new NodePotential(_graph);
deba@869
  1515
      }
deba@869
  1516
      if (!_status) {
deba@869
  1517
        _status = new StatusMap(_graph);
deba@869
  1518
      }
deba@869
  1519
      if (!_pred) {
deba@869
  1520
        _pred = new PredMap(_graph);
deba@869
  1521
      }
deba@869
  1522
      if (!_tree_set) {
deba@869
  1523
        _tree_set_index = new IntNodeMap(_graph);
deba@869
  1524
        _tree_set = new TreeSet(*_tree_set_index);
deba@869
  1525
      }
deba@869
  1526
      if (!_delta2) {
deba@869
  1527
        _delta2_index = new IntNodeMap(_graph);
deba@869
  1528
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
deba@869
  1529
      }
deba@869
  1530
      if (!_delta3) {
deba@869
  1531
        _delta3_index = new IntEdgeMap(_graph);
deba@869
  1532
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
deba@869
  1533
      }
deba@869
  1534
    }
deba@869
  1535
deba@869
  1536
    void destroyStructures() {
deba@869
  1537
      if (_matching) {
deba@869
  1538
        delete _matching;
deba@869
  1539
      }
deba@869
  1540
      if (_node_potential) {
deba@869
  1541
        delete _node_potential;
deba@869
  1542
      }
deba@869
  1543
      if (_status) {
deba@869
  1544
        delete _status;
deba@869
  1545
      }
deba@869
  1546
      if (_pred) {
deba@869
  1547
        delete _pred;
deba@869
  1548
      }
deba@869
  1549
      if (_tree_set) {
deba@869
  1550
        delete _tree_set_index;
deba@869
  1551
        delete _tree_set;
deba@869
  1552
      }
deba@869
  1553
      if (_delta2) {
deba@869
  1554
        delete _delta2_index;
deba@869
  1555
        delete _delta2;
deba@869
  1556
      }
deba@869
  1557
      if (_delta3) {
deba@869
  1558
        delete _delta3_index;
deba@869
  1559
        delete _delta3;
deba@869
  1560
      }
deba@869
  1561
    }
deba@869
  1562
deba@869
  1563
    void matchedToEven(Node node, int tree) {
deba@869
  1564
      _tree_set->insert(node, tree);
deba@869
  1565
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
  1566
deba@869
  1567
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
  1568
        _delta2->erase(node);
deba@869
  1569
      }
deba@869
  1570
deba@869
  1571
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
  1572
        Node v = _graph.source(a);
deba@869
  1573
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
  1574
          dualScale * _weight[a];
deba@869
  1575
        if (node == v) {
deba@869
  1576
          if (_allow_loops && _graph.direction(a)) {
deba@869
  1577
            _delta3->push(a, rw / 2);
deba@869
  1578
          }
deba@869
  1579
        } else if ((*_status)[v] == EVEN) {
deba@869
  1580
          _delta3->push(a, rw / 2);
deba@869
  1581
        } else if ((*_status)[v] == MATCHED) {
deba@869
  1582
          if (_delta2->state(v) != _delta2->IN_HEAP) {
deba@869
  1583
            _pred->set(v, a);
deba@869
  1584
            _delta2->push(v, rw);
deba@869
  1585
          } else if ((*_delta2)[v] > rw) {
deba@869
  1586
            _pred->set(v, a);
deba@869
  1587
            _delta2->decrease(v, rw);
deba@869
  1588
          }
deba@869
  1589
        }
deba@869
  1590
      }
deba@869
  1591
    }
deba@869
  1592
deba@869
  1593
    void matchedToOdd(Node node, int tree) {
deba@869
  1594
      _tree_set->insert(node, tree);
deba@869
  1595
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
  1596
deba@869
  1597
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
  1598
        _delta2->erase(node);
deba@869
  1599
      }
deba@869
  1600
    }
deba@869
  1601
deba@869
  1602
    void evenToMatched(Node node, int tree) {
deba@869
  1603
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
  1604
      Arc min = INVALID;
deba@869
  1605
      Value minrw = std::numeric_limits<Value>::max();
deba@869
  1606
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
  1607
        Node v = _graph.source(a);
deba@869
  1608
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
  1609
          dualScale * _weight[a];
deba@869
  1610
deba@869
  1611
        if (node == v) {
deba@869
  1612
          if (_allow_loops && _graph.direction(a)) {
deba@869
  1613
            _delta3->erase(a);
deba@869
  1614
          }
deba@869
  1615
        } else if ((*_status)[v] == EVEN) {
deba@869
  1616
          _delta3->erase(a);
deba@869
  1617
          if (minrw > rw) {
deba@869
  1618
            min = _graph.oppositeArc(a);
deba@869
  1619
            minrw = rw;
deba@869
  1620
          }
deba@869
  1621
        } else if ((*_status)[v]  == MATCHED) {
deba@869
  1622
          if ((*_pred)[v] == a) {
deba@869
  1623
            Arc mina = INVALID;
deba@869
  1624
            Value minrwa = std::numeric_limits<Value>::max();
deba@869
  1625
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
deba@869
  1626
              Node va = _graph.target(aa);
deba@869
  1627
              if ((*_status)[va] != EVEN ||
deba@869
  1628
                  _tree_set->find(va) == tree) continue;
deba@869
  1629
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
deba@869
  1630
                dualScale * _weight[aa];
deba@869
  1631
              if (minrwa > rwa) {
deba@869
  1632
                minrwa = rwa;
deba@869
  1633
                mina = aa;
deba@869
  1634
              }
deba@869
  1635
            }
deba@869
  1636
            if (mina != INVALID) {
deba@869
  1637
              _pred->set(v, mina);
deba@869
  1638
              _delta2->increase(v, minrwa);
deba@869
  1639
            } else {
deba@869
  1640
              _pred->set(v, INVALID);
deba@869
  1641
              _delta2->erase(v);
deba@869
  1642
            }
deba@869
  1643
          }
deba@869
  1644
        }
deba@869
  1645
      }
deba@869
  1646
      if (min != INVALID) {
deba@869
  1647
        _pred->set(node, min);
deba@869
  1648
        _delta2->push(node, minrw);
deba@869
  1649
      } else {
deba@869
  1650
        _pred->set(node, INVALID);
deba@869
  1651
      }
deba@869
  1652
    }
deba@869
  1653
deba@869
  1654
    void oddToMatched(Node node) {
deba@869
  1655
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
  1656
      Arc min = INVALID;
deba@869
  1657
      Value minrw = std::numeric_limits<Value>::max();
deba@869
  1658
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
  1659
        Node v = _graph.source(a);
deba@869
  1660
        if ((*_status)[v] != EVEN) continue;
deba@869
  1661
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
  1662
          dualScale * _weight[a];
deba@869
  1663
deba@869
  1664
        if (minrw > rw) {
deba@869
  1665
          min = _graph.oppositeArc(a);
deba@869
  1666
          minrw = rw;
deba@869
  1667
        }
deba@869
  1668
      }
deba@869
  1669
      if (min != INVALID) {
deba@869
  1670
        _pred->set(node, min);
deba@869
  1671
        _delta2->push(node, minrw);
deba@869
  1672
      } else {
deba@869
  1673
        _pred->set(node, INVALID);
deba@869
  1674
      }
deba@869
  1675
    }
deba@869
  1676
deba@869
  1677
    void alternatePath(Node even, int tree) {
deba@869
  1678
      Node odd;
deba@869
  1679
deba@869
  1680
      _status->set(even, MATCHED);
deba@869
  1681
      evenToMatched(even, tree);
deba@869
  1682
deba@869
  1683
      Arc prev = (*_matching)[even];
deba@869
  1684
      while (prev != INVALID) {
deba@869
  1685
        odd = _graph.target(prev);
deba@869
  1686
        even = _graph.target((*_pred)[odd]);
deba@869
  1687
        _matching->set(odd, (*_pred)[odd]);
deba@869
  1688
        _status->set(odd, MATCHED);
deba@869
  1689
        oddToMatched(odd);
deba@869
  1690
deba@869
  1691
        prev = (*_matching)[even];
deba@869
  1692
        _status->set(even, MATCHED);
deba@869
  1693
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
deba@869
  1694
        evenToMatched(even, tree);
deba@869
  1695
      }
deba@869
  1696
    }
deba@869
  1697
deba@869
  1698
    void destroyTree(int tree) {
deba@869
  1699
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
deba@869
  1700
        if ((*_status)[n] == EVEN) {
deba@869
  1701
          _status->set(n, MATCHED);
deba@869
  1702
          evenToMatched(n, tree);
deba@869
  1703
        } else if ((*_status)[n] == ODD) {
deba@869
  1704
          _status->set(n, MATCHED);
deba@869
  1705
          oddToMatched(n);
deba@869
  1706
        }
deba@869
  1707
      }
deba@869
  1708
      _tree_set->eraseClass(tree);
deba@869
  1709
    }
deba@869
  1710
deba@869
  1711
    void augmentOnEdge(const Edge& edge) {
deba@869
  1712
      Node left = _graph.u(edge);
deba@869
  1713
      int left_tree = _tree_set->find(left);
deba@869
  1714
deba@869
  1715
      alternatePath(left, left_tree);
deba@869
  1716
      destroyTree(left_tree);
deba@869
  1717
      _matching->set(left, _graph.direct(edge, true));
deba@869
  1718
deba@869
  1719
      Node right = _graph.v(edge);
deba@869
  1720
      int right_tree = _tree_set->find(right);
deba@869
  1721
deba@869
  1722
      alternatePath(right, right_tree);
deba@869
  1723
      destroyTree(right_tree);
deba@869
  1724
      _matching->set(right, _graph.direct(edge, false));
deba@869
  1725
    }
deba@869
  1726
deba@869
  1727
    void augmentOnArc(const Arc& arc) {
deba@869
  1728
      Node left = _graph.source(arc);
deba@869
  1729
      _status->set(left, MATCHED);
deba@869
  1730
      _matching->set(left, arc);
deba@869
  1731
      _pred->set(left, arc);
deba@869
  1732
deba@869
  1733
      Node right = _graph.target(arc);
deba@869
  1734
      int right_tree = _tree_set->find(right);
deba@869
  1735
deba@869
  1736
      alternatePath(right, right_tree);
deba@869
  1737
      destroyTree(right_tree);
deba@869
  1738
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
  1739
    }
deba@869
  1740
deba@869
  1741
    void extendOnArc(const Arc& arc) {
deba@869
  1742
      Node base = _graph.target(arc);
deba@869
  1743
      int tree = _tree_set->find(base);
deba@869
  1744
deba@869
  1745
      Node odd = _graph.source(arc);
deba@869
  1746
      _tree_set->insert(odd, tree);
deba@869
  1747
      _status->set(odd, ODD);
deba@869
  1748
      matchedToOdd(odd, tree);
deba@869
  1749
      _pred->set(odd, arc);
deba@869
  1750
deba@869
  1751
      Node even = _graph.target((*_matching)[odd]);
deba@869
  1752
      _tree_set->insert(even, tree);
deba@869
  1753
      _status->set(even, EVEN);
deba@869
  1754
      matchedToEven(even, tree);
deba@869
  1755
    }
deba@869
  1756
deba@869
  1757
    void cycleOnEdge(const Edge& edge, int tree) {
deba@869
  1758
      Node nca = INVALID;
deba@869
  1759
      std::vector<Node> left_path, right_path;
deba@869
  1760
deba@869
  1761
      {
deba@869
  1762
        std::set<Node> left_set, right_set;
deba@869
  1763
        Node left = _graph.u(edge);
deba@869
  1764
        left_path.push_back(left);
deba@869
  1765
        left_set.insert(left);
deba@869
  1766
deba@869
  1767
        Node right = _graph.v(edge);
deba@869
  1768
        right_path.push_back(right);
deba@869
  1769
        right_set.insert(right);
deba@869
  1770
deba@869
  1771
        while (true) {
deba@869
  1772
deba@869
  1773
          if (left_set.find(right) != left_set.end()) {
deba@869
  1774
            nca = right;
deba@869
  1775
            break;
deba@869
  1776
          }
deba@869
  1777
deba@869
  1778
          if ((*_matching)[left] == INVALID) break;
deba@869
  1779
deba@869
  1780
          left = _graph.target((*_matching)[left]);
deba@869
  1781
          left_path.push_back(left);
deba@869
  1782
          left = _graph.target((*_pred)[left]);
deba@869
  1783
          left_path.push_back(left);
deba@869
  1784
deba@869
  1785
          left_set.insert(left);
deba@869
  1786
deba@869
  1787
          if (right_set.find(left) != right_set.end()) {
deba@869
  1788
            nca = left;
deba@869
  1789
            break;
deba@869
  1790
          }
deba@869
  1791
deba@869
  1792
          if ((*_matching)[right] == INVALID) break;
deba@869
  1793
deba@869
  1794
          right = _graph.target((*_matching)[right]);
deba@869
  1795
          right_path.push_back(right);
deba@869
  1796
          right = _graph.target((*_pred)[right]);
deba@869
  1797
          right_path.push_back(right);
deba@869
  1798
deba@869
  1799
          right_set.insert(right);
deba@869
  1800
deba@869
  1801
        }
deba@869
  1802
deba@869
  1803
        if (nca == INVALID) {
deba@869
  1804
          if ((*_matching)[left] == INVALID) {
deba@869
  1805
            nca = right;
deba@869
  1806
            while (left_set.find(nca) == left_set.end()) {
deba@869
  1807
              nca = _graph.target((*_matching)[nca]);
deba@869
  1808
              right_path.push_back(nca);
deba@869
  1809
              nca = _graph.target((*_pred)[nca]);
deba@869
  1810
              right_path.push_back(nca);
deba@869
  1811
            }
deba@869
  1812
          } else {
deba@869
  1813
            nca = left;
deba@869
  1814
            while (right_set.find(nca) == right_set.end()) {
deba@869
  1815
              nca = _graph.target((*_matching)[nca]);
deba@869
  1816
              left_path.push_back(nca);
deba@869
  1817
              nca = _graph.target((*_pred)[nca]);
deba@869
  1818
              left_path.push_back(nca);
deba@869
  1819
            }
deba@869
  1820
          }
deba@869
  1821
        }
deba@869
  1822
      }
deba@869
  1823
deba@869
  1824
      alternatePath(nca, tree);
deba@869
  1825
      Arc prev;
deba@869
  1826
deba@869
  1827
      prev = _graph.direct(edge, true);
deba@869
  1828
      for (int i = 0; left_path[i] != nca; i += 2) {
deba@869
  1829
        _matching->set(left_path[i], prev);
deba@869
  1830
        _status->set(left_path[i], MATCHED);
deba@869
  1831
        evenToMatched(left_path[i], tree);
deba@869
  1832
deba@869
  1833
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
deba@869
  1834
        _status->set(left_path[i + 1], MATCHED);
deba@869
  1835
        oddToMatched(left_path[i + 1]);
deba@869
  1836
      }
deba@869
  1837
      _matching->set(nca, prev);
deba@869
  1838
deba@869
  1839
      for (int i = 0; right_path[i] != nca; i += 2) {
deba@869
  1840
        _status->set(right_path[i], MATCHED);
deba@869
  1841
        evenToMatched(right_path[i], tree);
deba@869
  1842
deba@869
  1843
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
deba@869
  1844
        _status->set(right_path[i + 1], MATCHED);
deba@869
  1845
        oddToMatched(right_path[i + 1]);
deba@869
  1846
      }
deba@869
  1847
deba@869
  1848
      destroyTree(tree);
deba@869
  1849
    }
deba@869
  1850
deba@869
  1851
    void extractCycle(const Arc &arc) {
deba@869
  1852
      Node left = _graph.source(arc);
deba@869
  1853
      Node odd = _graph.target((*_matching)[left]);
deba@869
  1854
      Arc prev;
deba@869
  1855
      while (odd != left) {
deba@869
  1856
        Node even = _graph.target((*_matching)[odd]);
deba@869
  1857
        prev = (*_matching)[odd];
deba@869
  1858
        odd = _graph.target((*_matching)[even]);
deba@869
  1859
        _matching->set(even, _graph.oppositeArc(prev));
deba@869
  1860
      }
deba@869
  1861
      _matching->set(left, arc);
deba@869
  1862
deba@869
  1863
      Node right = _graph.target(arc);
deba@869
  1864
      int right_tree = _tree_set->find(right);
deba@869
  1865
      alternatePath(right, right_tree);
deba@869
  1866
      destroyTree(right_tree);
deba@869
  1867
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
  1868
    }
deba@869
  1869
deba@869
  1870
  public:
deba@869
  1871
deba@869
  1872
    /// \brief Constructor
deba@869
  1873
    ///
deba@869
  1874
    /// Constructor.
deba@869
  1875
    MaxWeightedPerfectFractionalMatching(const Graph& graph,
deba@869
  1876
                                         const WeightMap& weight,
deba@869
  1877
                                         bool allow_loops = true)
deba@869
  1878
      : _graph(graph), _weight(weight), _matching(0),
deba@869
  1879
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
deba@869
  1880
      _status(0),  _pred(0),
deba@869
  1881
      _tree_set_index(0), _tree_set(0),
deba@869
  1882
deba@869
  1883
      _delta2_index(0), _delta2(0),
deba@869
  1884
      _delta3_index(0), _delta3(0),
deba@869
  1885
deba@869
  1886
      _delta_sum() {}
deba@869
  1887
deba@869
  1888
    ~MaxWeightedPerfectFractionalMatching() {
deba@869
  1889
      destroyStructures();
deba@869
  1890
    }
deba@869
  1891
deba@869
  1892
    /// \name Execution Control
deba@869
  1893
    /// The simplest way to execute the algorithm is to use the
deba@869
  1894
    /// \ref run() member function.
deba@869
  1895
deba@869
  1896
    ///@{
deba@869
  1897
deba@869
  1898
    /// \brief Initialize the algorithm
deba@869
  1899
    ///
deba@869
  1900
    /// This function initializes the algorithm.
deba@869
  1901
    void init() {
deba@869
  1902
      createStructures();
deba@869
  1903
deba@869
  1904
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1905
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
deba@869
  1906
      }
deba@869
  1907
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1908
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
deba@869
  1909
      }
deba@869
  1910
deba@869
  1911
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1912
        Value max = - std::numeric_limits<Value>::max();
deba@869
  1913
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@869
  1914
          if (_graph.target(e) == n && !_allow_loops) continue;
deba@869
  1915
          if ((dualScale * _weight[e]) / 2 > max) {
deba@869
  1916
            max = (dualScale * _weight[e]) / 2;
deba@869
  1917
          }
deba@869
  1918
        }
deba@869
  1919
        _node_potential->set(n, max);
deba@869
  1920
deba@869
  1921
        _tree_set->insert(n);
deba@869
  1922
deba@869
  1923
        _matching->set(n, INVALID);
deba@869
  1924
        _status->set(n, EVEN);
deba@869
  1925
      }
deba@869
  1926
deba@869
  1927
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1928
        Node left = _graph.u(e);
deba@869
  1929
        Node right = _graph.v(e);
deba@869
  1930
        if (left == right && !_allow_loops) continue;
deba@869
  1931
        _delta3->push(e, ((*_node_potential)[left] +
deba@869
  1932
                          (*_node_potential)[right] -
deba@869
  1933
                          dualScale * _weight[e]) / 2);
deba@869
  1934
      }
deba@869
  1935
    }
deba@869
  1936
deba@869
  1937
    /// \brief Start the algorithm
deba@869
  1938
    ///
deba@869
  1939
    /// This function starts the algorithm.
deba@869
  1940
    ///
deba@869
  1941
    /// \pre \ref init() must be called before using this function.
deba@869
  1942
    bool start() {
deba@869
  1943
      enum OpType {
deba@869
  1944
        D2, D3
deba@869
  1945
      };
deba@869
  1946
deba@869
  1947
      int unmatched = _node_num;
deba@869
  1948
      while (unmatched > 0) {
deba@869
  1949
        Value d2 = !_delta2->empty() ?
deba@869
  1950
          _delta2->prio() : std::numeric_limits<Value>::max();
deba@869
  1951
deba@869
  1952
        Value d3 = !_delta3->empty() ?
deba@869
  1953
          _delta3->prio() : std::numeric_limits<Value>::max();
deba@869
  1954
deba@869
  1955
        _delta_sum = d3; OpType ot = D3;
deba@869
  1956
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
deba@869
  1957
deba@869
  1958
        if (_delta_sum == std::numeric_limits<Value>::max()) {
deba@869
  1959
          return false;
deba@869
  1960
        }
deba@869
  1961
deba@869
  1962
        switch (ot) {
deba@869
  1963
        case D2:
deba@869
  1964
          {
deba@869
  1965
            Node n = _delta2->top();
deba@869
  1966
            Arc a = (*_pred)[n];
deba@869
  1967
            if ((*_matching)[n] == INVALID) {
deba@869
  1968
              augmentOnArc(a);
deba@869
  1969
              --unmatched;
deba@869
  1970
            } else {
deba@869
  1971
              Node v = _graph.target((*_matching)[n]);
deba@869
  1972
              if ((*_matching)[n] !=
deba@869
  1973
                  _graph.oppositeArc((*_matching)[v])) {
deba@869
  1974
                extractCycle(a);
deba@869
  1975
                --unmatched;
deba@869
  1976
              } else {
deba@869
  1977
                extendOnArc(a);
deba@869
  1978
              }
deba@869
  1979
            }
deba@869
  1980
          } break;
deba@869
  1981
        case D3:
deba@869
  1982
          {
deba@869
  1983
            Edge e = _delta3->top();
deba@869
  1984
deba@869
  1985
            Node left = _graph.u(e);
deba@869
  1986
            Node right = _graph.v(e);
deba@869
  1987
deba@869
  1988
            int left_tree = _tree_set->find(left);
deba@869
  1989
            int right_tree = _tree_set->find(right);
deba@869
  1990
deba@869
  1991
            if (left_tree == right_tree) {
deba@869
  1992
              cycleOnEdge(e, left_tree);
deba@869
  1993
              --unmatched;
deba@869
  1994
            } else {
deba@869
  1995
              augmentOnEdge(e);
deba@869
  1996
              unmatched -= 2;
deba@869
  1997
            }
deba@869
  1998
          } break;
deba@869
  1999
        }
deba@869
  2000
      }
deba@869
  2001
      return true;
deba@869
  2002
    }
deba@869
  2003
deba@869
  2004
    /// \brief Run the algorithm.
deba@869
  2005
    ///
deba@871
  2006
    /// This method runs the \c %MaxWeightedPerfectFractionalMatching 
deba@871
  2007
    /// algorithm.
deba@869
  2008
    ///
deba@869
  2009
    /// \note mwfm.run() is just a shortcut of the following code.
deba@869
  2010
    /// \code
deba@869
  2011
    ///   mwpfm.init();
deba@869
  2012
    ///   mwpfm.start();
deba@869
  2013
    /// \endcode
deba@869
  2014
    bool run() {
deba@869
  2015
      init();
deba@869
  2016
      return start();
deba@869
  2017
    }
deba@869
  2018
deba@869
  2019
    /// @}
deba@869
  2020
deba@869
  2021
    /// \name Primal Solution
deba@869
  2022
    /// Functions to get the primal solution, i.e. the maximum weighted
deba@869
  2023
    /// matching.\n
deba@869
  2024
    /// Either \ref run() or \ref start() function should be called before
deba@869
  2025
    /// using them.
deba@869
  2026
deba@869
  2027
    /// @{
deba@869
  2028
deba@869
  2029
    /// \brief Return the weight of the matching.
deba@869
  2030
    ///
deba@869
  2031
    /// This function returns the weight of the found matching. This
deba@869
  2032
    /// value is scaled by \ref primalScale "primal scale".
deba@869
  2033
    ///
deba@869
  2034
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2035
    Value matchingWeight() const {
deba@869
  2036
      Value sum = 0;
deba@869
  2037
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  2038
        if ((*_matching)[n] != INVALID) {
deba@869
  2039
          sum += _weight[(*_matching)[n]];
deba@869
  2040
        }
deba@869
  2041
      }
deba@869
  2042
      return sum * primalScale / 2;
deba@869
  2043
    }
deba@869
  2044
deba@869
  2045
    /// \brief Return the number of covered nodes in the matching.
deba@869
  2046
    ///
deba@869
  2047
    /// This function returns the number of covered nodes in the matching.
deba@869
  2048
    ///
deba@869
  2049
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2050
    int matchingSize() const {
deba@869
  2051
      int num = 0;
deba@869
  2052
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  2053
        if ((*_matching)[n] != INVALID) {
deba@869
  2054
          ++num;
deba@869
  2055
        }
deba@869
  2056
      }
deba@869
  2057
      return num;
deba@869
  2058
    }
deba@869
  2059
deba@869
  2060
    /// \brief Return \c true if the given edge is in the matching.
deba@869
  2061
    ///
deba@869
  2062
    /// This function returns \c true if the given edge is in the
deba@869
  2063
    /// found matching. The result is scaled by \ref primalScale
deba@869
  2064
    /// "primal scale".
deba@869
  2065
    ///
deba@869
  2066
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2067
    Value matching(const Edge& edge) const {
deba@869
  2068
      return Value(edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
deba@869
  2069
        * primalScale / 2 + Value(edge == (*_matching)[_graph.v(edge)] ? 1 : 0)
deba@869
  2070
        * primalScale / 2;
deba@869
  2071
    }
deba@869
  2072
deba@869
  2073
    /// \brief Return the fractional matching arc (or edge) incident
deba@869
  2074
    /// to the given node.
deba@869
  2075
    ///
deba@869
  2076
    /// This function returns one of the fractional matching arc (or
deba@869
  2077
    /// edge) incident to the given node in the found matching or \c
deba@869
  2078
    /// INVALID if the node is not covered by the matching or if the
deba@869
  2079
    /// node is on an odd length cycle then it is the successor edge
deba@869
  2080
    /// on the cycle.
deba@869
  2081
    ///
deba@869
  2082
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2083
    Arc matching(const Node& node) const {
deba@869
  2084
      return (*_matching)[node];
deba@869
  2085
    }
deba@869
  2086
deba@869
  2087
    /// \brief Return a const reference to the matching map.
deba@869
  2088
    ///
deba@869
  2089
    /// This function returns a const reference to a node map that stores
deba@869
  2090
    /// the matching arc (or edge) incident to each node.
deba@869
  2091
    const MatchingMap& matchingMap() const {
deba@869
  2092
      return *_matching;
deba@869
  2093
    }
deba@869
  2094
deba@869
  2095
    /// @}
deba@869
  2096
deba@869
  2097
    /// \name Dual Solution
deba@869
  2098
    /// Functions to get the dual solution.\n
deba@869
  2099
    /// Either \ref run() or \ref start() function should be called before
deba@869
  2100
    /// using them.
deba@869
  2101
deba@869
  2102
    /// @{
deba@869
  2103
deba@869
  2104
    /// \brief Return the value of the dual solution.
deba@869
  2105
    ///
deba@869
  2106
    /// This function returns the value of the dual solution.
deba@869
  2107
    /// It should be equal to the primal value scaled by \ref dualScale
deba@869
  2108
    /// "dual scale".
deba@869
  2109
    ///
deba@869
  2110
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2111
    Value dualValue() const {
deba@869
  2112
      Value sum = 0;
deba@869
  2113
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  2114
        sum += nodeValue(n);
deba@869
  2115
      }
deba@869
  2116
      return sum;
deba@869
  2117
    }
deba@869
  2118
deba@869
  2119
    /// \brief Return the dual value (potential) of the given node.
deba@869
  2120
    ///
deba@869
  2121
    /// This function returns the dual value (potential) of the given node.
deba@869
  2122
    ///
deba@869
  2123
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2124
    Value nodeValue(const Node& n) const {
deba@869
  2125
      return (*_node_potential)[n];
deba@869
  2126
    }
deba@869
  2127
deba@869
  2128
    /// @}
deba@869
  2129
deba@869
  2130
  };
deba@869
  2131
deba@869
  2132
} //END OF NAMESPACE LEMON
deba@869
  2133
deba@869
  2134
#endif //LEMON_FRACTIONAL_MATCHING_H