lemon/fractional_matching.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 876 7f6e2bd76654
child 1074 97d978243703
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
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
 *
alpar@877
     5
 * Copyright (C) 2003-2010
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@872
   661
  /// The primal solution is multiplied by
deba@872
   662
  /// \ref MaxWeightedFractionalMatching::primalScale "2".
deba@872
   663
  /// If the value type is integer, then the dual
deba@872
   664
  /// solution is scaled by
deba@872
   665
  /// \ref MaxWeightedFractionalMatching::dualScale "4".
deba@869
   666
  ///
deba@869
   667
  /// \tparam GR The undirected graph type the algorithm runs on.
deba@869
   668
  /// \tparam WM The type edge weight map. The default type is
deba@869
   669
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
deba@869
   670
#ifdef DOXYGEN
deba@869
   671
  template <typename GR, typename WM>
deba@869
   672
#else
deba@869
   673
  template <typename GR,
deba@869
   674
            typename WM = typename GR::template EdgeMap<int> >
deba@869
   675
#endif
deba@869
   676
  class MaxWeightedFractionalMatching {
deba@869
   677
  public:
deba@869
   678
deba@869
   679
    /// The graph type of the algorithm
deba@869
   680
    typedef GR Graph;
deba@869
   681
    /// The type of the edge weight map
deba@869
   682
    typedef WM WeightMap;
deba@869
   683
    /// The value type of the edge weights
deba@869
   684
    typedef typename WeightMap::Value Value;
deba@869
   685
deba@869
   686
    /// The type of the matching map
deba@869
   687
    typedef typename Graph::template NodeMap<typename Graph::Arc>
deba@869
   688
    MatchingMap;
deba@869
   689
deba@869
   690
    /// \brief Scaling factor for primal solution
deba@869
   691
    ///
deba@872
   692
    /// Scaling factor for primal solution.
deba@872
   693
    static const int primalScale = 2;
deba@869
   694
deba@869
   695
    /// \brief Scaling factor for dual solution
deba@869
   696
    ///
deba@869
   697
    /// Scaling factor for dual solution. It is equal to 4 or 1
deba@869
   698
    /// according to the value type.
deba@869
   699
    static const int dualScale =
deba@869
   700
      std::numeric_limits<Value>::is_integer ? 4 : 1;
deba@869
   701
deba@869
   702
  private:
deba@869
   703
deba@869
   704
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
deba@869
   705
deba@869
   706
    typedef typename Graph::template NodeMap<Value> NodePotential;
deba@869
   707
deba@869
   708
    const Graph& _graph;
deba@869
   709
    const WeightMap& _weight;
deba@869
   710
deba@869
   711
    MatchingMap* _matching;
deba@869
   712
    NodePotential* _node_potential;
deba@869
   713
deba@869
   714
    int _node_num;
deba@869
   715
    bool _allow_loops;
deba@869
   716
deba@869
   717
    enum Status {
deba@869
   718
      EVEN = -1, MATCHED = 0, ODD = 1
deba@869
   719
    };
deba@869
   720
deba@869
   721
    typedef typename Graph::template NodeMap<Status> StatusMap;
deba@869
   722
    StatusMap* _status;
deba@869
   723
deba@869
   724
    typedef typename Graph::template NodeMap<Arc> PredMap;
deba@869
   725
    PredMap* _pred;
deba@869
   726
deba@869
   727
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
deba@869
   728
deba@869
   729
    IntNodeMap *_tree_set_index;
deba@869
   730
    TreeSet *_tree_set;
deba@869
   731
deba@869
   732
    IntNodeMap *_delta1_index;
deba@869
   733
    BinHeap<Value, IntNodeMap> *_delta1;
deba@869
   734
deba@869
   735
    IntNodeMap *_delta2_index;
deba@869
   736
    BinHeap<Value, IntNodeMap> *_delta2;
deba@869
   737
deba@869
   738
    IntEdgeMap *_delta3_index;
deba@869
   739
    BinHeap<Value, IntEdgeMap> *_delta3;
deba@869
   740
deba@869
   741
    Value _delta_sum;
deba@869
   742
deba@869
   743
    void createStructures() {
deba@869
   744
      _node_num = countNodes(_graph);
deba@869
   745
deba@869
   746
      if (!_matching) {
deba@869
   747
        _matching = new MatchingMap(_graph);
deba@869
   748
      }
deba@869
   749
      if (!_node_potential) {
deba@869
   750
        _node_potential = new NodePotential(_graph);
deba@869
   751
      }
deba@869
   752
      if (!_status) {
deba@869
   753
        _status = new StatusMap(_graph);
deba@869
   754
      }
deba@869
   755
      if (!_pred) {
deba@869
   756
        _pred = new PredMap(_graph);
deba@869
   757
      }
deba@869
   758
      if (!_tree_set) {
deba@869
   759
        _tree_set_index = new IntNodeMap(_graph);
deba@869
   760
        _tree_set = new TreeSet(*_tree_set_index);
deba@869
   761
      }
deba@869
   762
      if (!_delta1) {
deba@869
   763
        _delta1_index = new IntNodeMap(_graph);
deba@869
   764
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
deba@869
   765
      }
deba@869
   766
      if (!_delta2) {
deba@869
   767
        _delta2_index = new IntNodeMap(_graph);
deba@869
   768
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
deba@869
   769
      }
deba@869
   770
      if (!_delta3) {
deba@869
   771
        _delta3_index = new IntEdgeMap(_graph);
deba@869
   772
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
deba@869
   773
      }
deba@869
   774
    }
deba@869
   775
deba@869
   776
    void destroyStructures() {
deba@869
   777
      if (_matching) {
deba@869
   778
        delete _matching;
deba@869
   779
      }
deba@869
   780
      if (_node_potential) {
deba@869
   781
        delete _node_potential;
deba@869
   782
      }
deba@869
   783
      if (_status) {
deba@869
   784
        delete _status;
deba@869
   785
      }
deba@869
   786
      if (_pred) {
deba@869
   787
        delete _pred;
deba@869
   788
      }
deba@869
   789
      if (_tree_set) {
deba@869
   790
        delete _tree_set_index;
deba@869
   791
        delete _tree_set;
deba@869
   792
      }
deba@869
   793
      if (_delta1) {
deba@869
   794
        delete _delta1_index;
deba@869
   795
        delete _delta1;
deba@869
   796
      }
deba@869
   797
      if (_delta2) {
deba@869
   798
        delete _delta2_index;
deba@869
   799
        delete _delta2;
deba@869
   800
      }
deba@869
   801
      if (_delta3) {
deba@869
   802
        delete _delta3_index;
deba@869
   803
        delete _delta3;
deba@869
   804
      }
deba@869
   805
    }
deba@869
   806
deba@869
   807
    void matchedToEven(Node node, int tree) {
deba@869
   808
      _tree_set->insert(node, tree);
deba@869
   809
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
   810
      _delta1->push(node, (*_node_potential)[node]);
deba@869
   811
deba@869
   812
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
   813
        _delta2->erase(node);
deba@869
   814
      }
deba@869
   815
deba@869
   816
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
   817
        Node v = _graph.source(a);
deba@869
   818
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
   819
          dualScale * _weight[a];
deba@869
   820
        if (node == v) {
deba@869
   821
          if (_allow_loops && _graph.direction(a)) {
deba@869
   822
            _delta3->push(a, rw / 2);
deba@869
   823
          }
deba@869
   824
        } else if ((*_status)[v] == EVEN) {
deba@869
   825
          _delta3->push(a, rw / 2);
deba@869
   826
        } else if ((*_status)[v] == MATCHED) {
deba@869
   827
          if (_delta2->state(v) != _delta2->IN_HEAP) {
deba@869
   828
            _pred->set(v, a);
deba@869
   829
            _delta2->push(v, rw);
deba@869
   830
          } else if ((*_delta2)[v] > rw) {
deba@869
   831
            _pred->set(v, a);
deba@869
   832
            _delta2->decrease(v, rw);
deba@869
   833
          }
deba@869
   834
        }
deba@869
   835
      }
deba@869
   836
    }
deba@869
   837
deba@869
   838
    void matchedToOdd(Node node, int tree) {
deba@869
   839
      _tree_set->insert(node, tree);
deba@869
   840
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
   841
deba@869
   842
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
   843
        _delta2->erase(node);
deba@869
   844
      }
deba@869
   845
    }
deba@869
   846
deba@869
   847
    void evenToMatched(Node node, int tree) {
deba@869
   848
      _delta1->erase(node);
deba@869
   849
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
   850
      Arc min = INVALID;
deba@869
   851
      Value minrw = std::numeric_limits<Value>::max();
deba@869
   852
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
   853
        Node v = _graph.source(a);
deba@869
   854
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
   855
          dualScale * _weight[a];
deba@869
   856
deba@869
   857
        if (node == v) {
deba@869
   858
          if (_allow_loops && _graph.direction(a)) {
deba@869
   859
            _delta3->erase(a);
deba@869
   860
          }
deba@869
   861
        } else if ((*_status)[v] == EVEN) {
deba@869
   862
          _delta3->erase(a);
deba@869
   863
          if (minrw > rw) {
deba@869
   864
            min = _graph.oppositeArc(a);
deba@869
   865
            minrw = rw;
deba@869
   866
          }
deba@869
   867
        } else if ((*_status)[v]  == MATCHED) {
deba@869
   868
          if ((*_pred)[v] == a) {
deba@869
   869
            Arc mina = INVALID;
deba@869
   870
            Value minrwa = std::numeric_limits<Value>::max();
deba@869
   871
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
deba@869
   872
              Node va = _graph.target(aa);
deba@869
   873
              if ((*_status)[va] != EVEN ||
deba@869
   874
                  _tree_set->find(va) == tree) continue;
deba@869
   875
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
deba@869
   876
                dualScale * _weight[aa];
deba@869
   877
              if (minrwa > rwa) {
deba@869
   878
                minrwa = rwa;
deba@869
   879
                mina = aa;
deba@869
   880
              }
deba@869
   881
            }
deba@869
   882
            if (mina != INVALID) {
deba@869
   883
              _pred->set(v, mina);
deba@869
   884
              _delta2->increase(v, minrwa);
deba@869
   885
            } else {
deba@869
   886
              _pred->set(v, INVALID);
deba@869
   887
              _delta2->erase(v);
deba@869
   888
            }
deba@869
   889
          }
deba@869
   890
        }
deba@869
   891
      }
deba@869
   892
      if (min != INVALID) {
deba@869
   893
        _pred->set(node, min);
deba@869
   894
        _delta2->push(node, minrw);
deba@869
   895
      } else {
deba@869
   896
        _pred->set(node, INVALID);
deba@869
   897
      }
deba@869
   898
    }
deba@869
   899
deba@869
   900
    void oddToMatched(Node node) {
deba@869
   901
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
   902
      Arc min = INVALID;
deba@869
   903
      Value minrw = std::numeric_limits<Value>::max();
deba@869
   904
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
   905
        Node v = _graph.source(a);
deba@869
   906
        if ((*_status)[v] != EVEN) continue;
deba@869
   907
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
   908
          dualScale * _weight[a];
deba@869
   909
deba@869
   910
        if (minrw > rw) {
deba@869
   911
          min = _graph.oppositeArc(a);
deba@869
   912
          minrw = rw;
deba@869
   913
        }
deba@869
   914
      }
deba@869
   915
      if (min != INVALID) {
deba@869
   916
        _pred->set(node, min);
deba@869
   917
        _delta2->push(node, minrw);
deba@869
   918
      } else {
deba@869
   919
        _pred->set(node, INVALID);
deba@869
   920
      }
deba@869
   921
    }
deba@869
   922
deba@869
   923
    void alternatePath(Node even, int tree) {
deba@869
   924
      Node odd;
deba@869
   925
deba@869
   926
      _status->set(even, MATCHED);
deba@869
   927
      evenToMatched(even, tree);
deba@869
   928
deba@869
   929
      Arc prev = (*_matching)[even];
deba@869
   930
      while (prev != INVALID) {
deba@869
   931
        odd = _graph.target(prev);
deba@869
   932
        even = _graph.target((*_pred)[odd]);
deba@869
   933
        _matching->set(odd, (*_pred)[odd]);
deba@869
   934
        _status->set(odd, MATCHED);
deba@869
   935
        oddToMatched(odd);
deba@869
   936
deba@869
   937
        prev = (*_matching)[even];
deba@869
   938
        _status->set(even, MATCHED);
deba@869
   939
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
deba@869
   940
        evenToMatched(even, tree);
deba@869
   941
      }
deba@869
   942
    }
deba@869
   943
deba@869
   944
    void destroyTree(int tree) {
deba@869
   945
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
deba@869
   946
        if ((*_status)[n] == EVEN) {
deba@869
   947
          _status->set(n, MATCHED);
deba@869
   948
          evenToMatched(n, tree);
deba@869
   949
        } else if ((*_status)[n] == ODD) {
deba@869
   950
          _status->set(n, MATCHED);
deba@869
   951
          oddToMatched(n);
deba@869
   952
        }
deba@869
   953
      }
deba@869
   954
      _tree_set->eraseClass(tree);
deba@869
   955
    }
deba@869
   956
deba@869
   957
deba@869
   958
    void unmatchNode(const Node& node) {
deba@869
   959
      int tree = _tree_set->find(node);
deba@869
   960
deba@869
   961
      alternatePath(node, tree);
deba@869
   962
      destroyTree(tree);
deba@869
   963
deba@869
   964
      _matching->set(node, INVALID);
deba@869
   965
    }
deba@869
   966
deba@869
   967
deba@869
   968
    void augmentOnEdge(const Edge& edge) {
deba@869
   969
      Node left = _graph.u(edge);
deba@869
   970
      int left_tree = _tree_set->find(left);
deba@869
   971
deba@869
   972
      alternatePath(left, left_tree);
deba@869
   973
      destroyTree(left_tree);
deba@869
   974
      _matching->set(left, _graph.direct(edge, true));
deba@869
   975
deba@869
   976
      Node right = _graph.v(edge);
deba@869
   977
      int right_tree = _tree_set->find(right);
deba@869
   978
deba@869
   979
      alternatePath(right, right_tree);
deba@869
   980
      destroyTree(right_tree);
deba@869
   981
      _matching->set(right, _graph.direct(edge, false));
deba@869
   982
    }
deba@869
   983
deba@869
   984
    void augmentOnArc(const Arc& arc) {
deba@869
   985
      Node left = _graph.source(arc);
deba@869
   986
      _status->set(left, MATCHED);
deba@869
   987
      _matching->set(left, arc);
deba@869
   988
      _pred->set(left, arc);
deba@869
   989
deba@869
   990
      Node right = _graph.target(arc);
deba@869
   991
      int right_tree = _tree_set->find(right);
deba@869
   992
deba@869
   993
      alternatePath(right, right_tree);
deba@869
   994
      destroyTree(right_tree);
deba@869
   995
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
   996
    }
deba@869
   997
deba@869
   998
    void extendOnArc(const Arc& arc) {
deba@869
   999
      Node base = _graph.target(arc);
deba@869
  1000
      int tree = _tree_set->find(base);
deba@869
  1001
deba@869
  1002
      Node odd = _graph.source(arc);
deba@869
  1003
      _tree_set->insert(odd, tree);
deba@869
  1004
      _status->set(odd, ODD);
deba@869
  1005
      matchedToOdd(odd, tree);
deba@869
  1006
      _pred->set(odd, arc);
deba@869
  1007
deba@869
  1008
      Node even = _graph.target((*_matching)[odd]);
deba@869
  1009
      _tree_set->insert(even, tree);
deba@869
  1010
      _status->set(even, EVEN);
deba@869
  1011
      matchedToEven(even, tree);
deba@869
  1012
    }
deba@869
  1013
deba@869
  1014
    void cycleOnEdge(const Edge& edge, int tree) {
deba@869
  1015
      Node nca = INVALID;
deba@869
  1016
      std::vector<Node> left_path, right_path;
deba@869
  1017
deba@869
  1018
      {
deba@869
  1019
        std::set<Node> left_set, right_set;
deba@869
  1020
        Node left = _graph.u(edge);
deba@869
  1021
        left_path.push_back(left);
deba@869
  1022
        left_set.insert(left);
deba@869
  1023
deba@869
  1024
        Node right = _graph.v(edge);
deba@869
  1025
        right_path.push_back(right);
deba@869
  1026
        right_set.insert(right);
deba@869
  1027
deba@869
  1028
        while (true) {
deba@869
  1029
deba@869
  1030
          if (left_set.find(right) != left_set.end()) {
deba@869
  1031
            nca = right;
deba@869
  1032
            break;
deba@869
  1033
          }
deba@869
  1034
deba@869
  1035
          if ((*_matching)[left] == INVALID) break;
deba@869
  1036
deba@869
  1037
          left = _graph.target((*_matching)[left]);
deba@869
  1038
          left_path.push_back(left);
deba@869
  1039
          left = _graph.target((*_pred)[left]);
deba@869
  1040
          left_path.push_back(left);
deba@869
  1041
deba@869
  1042
          left_set.insert(left);
deba@869
  1043
deba@869
  1044
          if (right_set.find(left) != right_set.end()) {
deba@869
  1045
            nca = left;
deba@869
  1046
            break;
deba@869
  1047
          }
deba@869
  1048
deba@869
  1049
          if ((*_matching)[right] == INVALID) break;
deba@869
  1050
deba@869
  1051
          right = _graph.target((*_matching)[right]);
deba@869
  1052
          right_path.push_back(right);
deba@869
  1053
          right = _graph.target((*_pred)[right]);
deba@869
  1054
          right_path.push_back(right);
deba@869
  1055
deba@869
  1056
          right_set.insert(right);
deba@869
  1057
deba@869
  1058
        }
deba@869
  1059
deba@869
  1060
        if (nca == INVALID) {
deba@869
  1061
          if ((*_matching)[left] == INVALID) {
deba@869
  1062
            nca = right;
deba@869
  1063
            while (left_set.find(nca) == left_set.end()) {
deba@869
  1064
              nca = _graph.target((*_matching)[nca]);
deba@869
  1065
              right_path.push_back(nca);
deba@869
  1066
              nca = _graph.target((*_pred)[nca]);
deba@869
  1067
              right_path.push_back(nca);
deba@869
  1068
            }
deba@869
  1069
          } else {
deba@869
  1070
            nca = left;
deba@869
  1071
            while (right_set.find(nca) == right_set.end()) {
deba@869
  1072
              nca = _graph.target((*_matching)[nca]);
deba@869
  1073
              left_path.push_back(nca);
deba@869
  1074
              nca = _graph.target((*_pred)[nca]);
deba@869
  1075
              left_path.push_back(nca);
deba@869
  1076
            }
deba@869
  1077
          }
deba@869
  1078
        }
deba@869
  1079
      }
deba@869
  1080
deba@869
  1081
      alternatePath(nca, tree);
deba@869
  1082
      Arc prev;
deba@869
  1083
deba@869
  1084
      prev = _graph.direct(edge, true);
deba@869
  1085
      for (int i = 0; left_path[i] != nca; i += 2) {
deba@869
  1086
        _matching->set(left_path[i], prev);
deba@869
  1087
        _status->set(left_path[i], MATCHED);
deba@869
  1088
        evenToMatched(left_path[i], tree);
deba@869
  1089
deba@869
  1090
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
deba@869
  1091
        _status->set(left_path[i + 1], MATCHED);
deba@869
  1092
        oddToMatched(left_path[i + 1]);
deba@869
  1093
      }
deba@869
  1094
      _matching->set(nca, prev);
deba@869
  1095
deba@869
  1096
      for (int i = 0; right_path[i] != nca; i += 2) {
deba@869
  1097
        _status->set(right_path[i], MATCHED);
deba@869
  1098
        evenToMatched(right_path[i], tree);
deba@869
  1099
deba@869
  1100
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
deba@869
  1101
        _status->set(right_path[i + 1], MATCHED);
deba@869
  1102
        oddToMatched(right_path[i + 1]);
deba@869
  1103
      }
deba@869
  1104
deba@869
  1105
      destroyTree(tree);
deba@869
  1106
    }
deba@869
  1107
deba@869
  1108
    void extractCycle(const Arc &arc) {
deba@869
  1109
      Node left = _graph.source(arc);
deba@869
  1110
      Node odd = _graph.target((*_matching)[left]);
deba@869
  1111
      Arc prev;
deba@869
  1112
      while (odd != left) {
deba@869
  1113
        Node even = _graph.target((*_matching)[odd]);
deba@869
  1114
        prev = (*_matching)[odd];
deba@869
  1115
        odd = _graph.target((*_matching)[even]);
deba@869
  1116
        _matching->set(even, _graph.oppositeArc(prev));
deba@869
  1117
      }
deba@869
  1118
      _matching->set(left, arc);
deba@869
  1119
deba@869
  1120
      Node right = _graph.target(arc);
deba@869
  1121
      int right_tree = _tree_set->find(right);
deba@869
  1122
      alternatePath(right, right_tree);
deba@869
  1123
      destroyTree(right_tree);
deba@869
  1124
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
  1125
    }
deba@869
  1126
deba@869
  1127
  public:
deba@869
  1128
deba@869
  1129
    /// \brief Constructor
deba@869
  1130
    ///
deba@869
  1131
    /// Constructor.
deba@869
  1132
    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
deba@869
  1133
                                  bool allow_loops = true)
deba@869
  1134
      : _graph(graph), _weight(weight), _matching(0),
deba@869
  1135
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
deba@869
  1136
      _status(0),  _pred(0),
deba@869
  1137
      _tree_set_index(0), _tree_set(0),
deba@869
  1138
deba@869
  1139
      _delta1_index(0), _delta1(0),
deba@869
  1140
      _delta2_index(0), _delta2(0),
deba@869
  1141
      _delta3_index(0), _delta3(0),
deba@869
  1142
deba@869
  1143
      _delta_sum() {}
deba@869
  1144
deba@869
  1145
    ~MaxWeightedFractionalMatching() {
deba@869
  1146
      destroyStructures();
deba@869
  1147
    }
deba@869
  1148
deba@869
  1149
    /// \name Execution Control
deba@869
  1150
    /// The simplest way to execute the algorithm is to use the
deba@869
  1151
    /// \ref run() member function.
deba@869
  1152
deba@869
  1153
    ///@{
deba@869
  1154
deba@869
  1155
    /// \brief Initialize the algorithm
deba@869
  1156
    ///
deba@869
  1157
    /// This function initializes the algorithm.
deba@869
  1158
    void init() {
deba@869
  1159
      createStructures();
deba@869
  1160
deba@869
  1161
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1162
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
deba@869
  1163
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
deba@869
  1164
      }
deba@869
  1165
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1166
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
deba@869
  1167
      }
deba@869
  1168
deba@876
  1169
      _delta1->clear();
deba@876
  1170
      _delta2->clear();
deba@876
  1171
      _delta3->clear();
deba@876
  1172
      _tree_set->clear();
deba@876
  1173
deba@869
  1174
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1175
        Value max = 0;
deba@869
  1176
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@869
  1177
          if (_graph.target(e) == n && !_allow_loops) continue;
deba@869
  1178
          if ((dualScale * _weight[e]) / 2 > max) {
deba@869
  1179
            max = (dualScale * _weight[e]) / 2;
deba@869
  1180
          }
deba@869
  1181
        }
deba@869
  1182
        _node_potential->set(n, max);
deba@869
  1183
        _delta1->push(n, max);
deba@869
  1184
deba@869
  1185
        _tree_set->insert(n);
deba@869
  1186
deba@869
  1187
        _matching->set(n, INVALID);
deba@869
  1188
        _status->set(n, EVEN);
deba@869
  1189
      }
deba@869
  1190
deba@869
  1191
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1192
        Node left = _graph.u(e);
deba@869
  1193
        Node right = _graph.v(e);
deba@869
  1194
        if (left == right && !_allow_loops) continue;
deba@869
  1195
        _delta3->push(e, ((*_node_potential)[left] +
deba@869
  1196
                          (*_node_potential)[right] -
deba@869
  1197
                          dualScale * _weight[e]) / 2);
deba@869
  1198
      }
deba@869
  1199
    }
deba@869
  1200
deba@869
  1201
    /// \brief Start the algorithm
deba@869
  1202
    ///
deba@869
  1203
    /// This function starts the algorithm.
deba@869
  1204
    ///
deba@869
  1205
    /// \pre \ref init() must be called before using this function.
deba@869
  1206
    void start() {
deba@869
  1207
      enum OpType {
deba@869
  1208
        D1, D2, D3
deba@869
  1209
      };
deba@869
  1210
deba@869
  1211
      int unmatched = _node_num;
deba@869
  1212
      while (unmatched > 0) {
deba@869
  1213
        Value d1 = !_delta1->empty() ?
deba@869
  1214
          _delta1->prio() : std::numeric_limits<Value>::max();
deba@869
  1215
deba@869
  1216
        Value d2 = !_delta2->empty() ?
deba@869
  1217
          _delta2->prio() : std::numeric_limits<Value>::max();
deba@869
  1218
deba@869
  1219
        Value d3 = !_delta3->empty() ?
deba@869
  1220
          _delta3->prio() : std::numeric_limits<Value>::max();
deba@869
  1221
deba@869
  1222
        _delta_sum = d3; OpType ot = D3;
deba@869
  1223
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
deba@869
  1224
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
deba@869
  1225
deba@869
  1226
        switch (ot) {
deba@869
  1227
        case D1:
deba@869
  1228
          {
deba@869
  1229
            Node n = _delta1->top();
deba@869
  1230
            unmatchNode(n);
deba@869
  1231
            --unmatched;
deba@869
  1232
          }
deba@869
  1233
          break;
deba@869
  1234
        case D2:
deba@869
  1235
          {
deba@869
  1236
            Node n = _delta2->top();
deba@869
  1237
            Arc a = (*_pred)[n];
deba@869
  1238
            if ((*_matching)[n] == INVALID) {
deba@869
  1239
              augmentOnArc(a);
deba@869
  1240
              --unmatched;
deba@869
  1241
            } else {
deba@869
  1242
              Node v = _graph.target((*_matching)[n]);
deba@869
  1243
              if ((*_matching)[n] !=
deba@869
  1244
                  _graph.oppositeArc((*_matching)[v])) {
deba@869
  1245
                extractCycle(a);
deba@869
  1246
                --unmatched;
deba@869
  1247
              } else {
deba@869
  1248
                extendOnArc(a);
deba@869
  1249
              }
deba@869
  1250
            }
deba@869
  1251
          } break;
deba@869
  1252
        case D3:
deba@869
  1253
          {
deba@869
  1254
            Edge e = _delta3->top();
deba@869
  1255
deba@869
  1256
            Node left = _graph.u(e);
deba@869
  1257
            Node right = _graph.v(e);
deba@869
  1258
deba@869
  1259
            int left_tree = _tree_set->find(left);
deba@869
  1260
            int right_tree = _tree_set->find(right);
deba@869
  1261
deba@869
  1262
            if (left_tree == right_tree) {
deba@869
  1263
              cycleOnEdge(e, left_tree);
deba@869
  1264
              --unmatched;
deba@869
  1265
            } else {
deba@869
  1266
              augmentOnEdge(e);
deba@869
  1267
              unmatched -= 2;
deba@869
  1268
            }
deba@869
  1269
          } break;
deba@869
  1270
        }
deba@869
  1271
      }
deba@869
  1272
    }
deba@869
  1273
deba@869
  1274
    /// \brief Run the algorithm.
deba@869
  1275
    ///
deba@871
  1276
    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
deba@869
  1277
    ///
deba@869
  1278
    /// \note mwfm.run() is just a shortcut of the following code.
deba@869
  1279
    /// \code
deba@869
  1280
    ///   mwfm.init();
deba@869
  1281
    ///   mwfm.start();
deba@869
  1282
    /// \endcode
deba@869
  1283
    void run() {
deba@869
  1284
      init();
deba@869
  1285
      start();
deba@869
  1286
    }
deba@869
  1287
deba@869
  1288
    /// @}
deba@869
  1289
deba@869
  1290
    /// \name Primal Solution
deba@869
  1291
    /// Functions to get the primal solution, i.e. the maximum weighted
deba@869
  1292
    /// matching.\n
deba@869
  1293
    /// Either \ref run() or \ref start() function should be called before
deba@869
  1294
    /// using them.
deba@869
  1295
deba@869
  1296
    /// @{
deba@869
  1297
deba@869
  1298
    /// \brief Return the weight of the matching.
deba@869
  1299
    ///
deba@869
  1300
    /// This function returns the weight of the found matching. This
deba@869
  1301
    /// value is scaled by \ref primalScale "primal scale".
deba@869
  1302
    ///
deba@869
  1303
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1304
    Value matchingWeight() const {
deba@869
  1305
      Value sum = 0;
deba@869
  1306
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1307
        if ((*_matching)[n] != INVALID) {
deba@869
  1308
          sum += _weight[(*_matching)[n]];
deba@869
  1309
        }
deba@869
  1310
      }
deba@869
  1311
      return sum * primalScale / 2;
deba@869
  1312
    }
deba@869
  1313
deba@869
  1314
    /// \brief Return the number of covered nodes in the matching.
deba@869
  1315
    ///
deba@869
  1316
    /// This function returns the number of covered nodes in the matching.
deba@869
  1317
    ///
deba@869
  1318
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1319
    int matchingSize() const {
deba@869
  1320
      int num = 0;
deba@869
  1321
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1322
        if ((*_matching)[n] != INVALID) {
deba@869
  1323
          ++num;
deba@869
  1324
        }
deba@869
  1325
      }
deba@869
  1326
      return num;
deba@869
  1327
    }
deba@869
  1328
deba@869
  1329
    /// \brief Return \c true if the given edge is in the matching.
deba@869
  1330
    ///
deba@869
  1331
    /// This function returns \c true if the given edge is in the
deba@869
  1332
    /// found matching. The result is scaled by \ref primalScale
deba@869
  1333
    /// "primal scale".
deba@869
  1334
    ///
deba@869
  1335
    /// \pre Either run() or start() must be called before using this function.
deba@872
  1336
    int matching(const Edge& edge) const {
deba@872
  1337
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
deba@872
  1338
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
deba@869
  1339
    }
deba@869
  1340
deba@869
  1341
    /// \brief Return the fractional matching arc (or edge) incident
deba@869
  1342
    /// to the given node.
deba@869
  1343
    ///
deba@869
  1344
    /// This function returns one of the fractional matching arc (or
deba@869
  1345
    /// edge) incident to the given node in the found matching or \c
deba@869
  1346
    /// INVALID if the node is not covered by the matching or if the
deba@869
  1347
    /// node is on an odd length cycle then it is the successor edge
deba@869
  1348
    /// on the cycle.
deba@869
  1349
    ///
deba@869
  1350
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1351
    Arc matching(const Node& node) const {
deba@869
  1352
      return (*_matching)[node];
deba@869
  1353
    }
deba@869
  1354
deba@869
  1355
    /// \brief Return a const reference to the matching map.
deba@869
  1356
    ///
deba@869
  1357
    /// This function returns a const reference to a node map that stores
deba@869
  1358
    /// the matching arc (or edge) incident to each node.
deba@869
  1359
    const MatchingMap& matchingMap() const {
deba@869
  1360
      return *_matching;
deba@869
  1361
    }
deba@869
  1362
deba@869
  1363
    /// @}
deba@869
  1364
deba@869
  1365
    /// \name Dual Solution
deba@869
  1366
    /// Functions to get the dual solution.\n
deba@869
  1367
    /// Either \ref run() or \ref start() function should be called before
deba@869
  1368
    /// using them.
deba@869
  1369
deba@869
  1370
    /// @{
deba@869
  1371
deba@869
  1372
    /// \brief Return the value of the dual solution.
deba@869
  1373
    ///
deba@869
  1374
    /// This function returns the value of the dual solution.
deba@869
  1375
    /// It should be equal to the primal value scaled by \ref dualScale
deba@869
  1376
    /// "dual scale".
deba@869
  1377
    ///
deba@869
  1378
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1379
    Value dualValue() const {
deba@869
  1380
      Value sum = 0;
deba@869
  1381
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1382
        sum += nodeValue(n);
deba@869
  1383
      }
deba@869
  1384
      return sum;
deba@869
  1385
    }
deba@869
  1386
deba@869
  1387
    /// \brief Return the dual value (potential) of the given node.
deba@869
  1388
    ///
deba@869
  1389
    /// This function returns the dual value (potential) of the given node.
deba@869
  1390
    ///
deba@869
  1391
    /// \pre Either run() or start() must be called before using this function.
deba@869
  1392
    Value nodeValue(const Node& n) const {
deba@869
  1393
      return (*_node_potential)[n];
deba@869
  1394
    }
deba@869
  1395
deba@869
  1396
    /// @}
deba@869
  1397
deba@869
  1398
  };
deba@869
  1399
deba@869
  1400
  /// \ingroup matching
deba@869
  1401
  ///
deba@869
  1402
  /// \brief Weighted fractional perfect matching in general graphs
deba@869
  1403
  ///
deba@869
  1404
  /// This class provides an efficient implementation of fractional
deba@871
  1405
  /// matching algorithm. The implementation uses priority queues and
deba@871
  1406
  /// provides \f$O(nm\log n)\f$ time complexity.
deba@869
  1407
  ///
deba@869
  1408
  /// The maximum weighted fractional perfect matching is a relaxation
deba@869
  1409
  /// of the maximum weighted perfect matching problem where the odd
deba@869
  1410
  /// set constraints are omitted.
deba@869
  1411
  /// It can be formulated with the following linear program.
deba@869
  1412
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
deba@869
  1413
  /// \f[x_e \ge 0\quad \forall e\in E\f]
deba@869
  1414
  /// \f[\max \sum_{e\in E}x_ew_e\f]
deba@869
  1415
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
deba@869
  1416
  /// \f$X\f$. The result must be the union of a matching with one
deba@869
  1417
  /// value edges and a set of odd length cycles with half value edges.
deba@869
  1418
  ///
deba@869
  1419
  /// The algorithm calculates an optimal fractional matching and a
deba@869
  1420
  /// proof of the optimality. The solution of the dual problem can be
deba@869
  1421
  /// used to check the result of the algorithm. The dual linear
deba@869
  1422
  /// problem is the following.
deba@869
  1423
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
deba@871
  1424
  /// \f[\min \sum_{u \in V}y_u \f]
deba@869
  1425
  ///
deba@869
  1426
  /// The algorithm can be executed with the run() function.
deba@869
  1427
  /// After it the matching (the primal solution) and the dual solution
deba@869
  1428
  /// can be obtained using the query functions.
deba@872
  1429
  ///
deba@872
  1430
  /// The primal solution is multiplied by
deba@872
  1431
  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
deba@872
  1432
  /// If the value type is integer, then the dual
deba@872
  1433
  /// solution is scaled by
deba@872
  1434
  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
deba@869
  1435
  ///
deba@869
  1436
  /// \tparam GR The undirected graph type the algorithm runs on.
deba@869
  1437
  /// \tparam WM The type edge weight map. The default type is
deba@869
  1438
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
deba@869
  1439
#ifdef DOXYGEN
deba@869
  1440
  template <typename GR, typename WM>
deba@869
  1441
#else
deba@869
  1442
  template <typename GR,
deba@869
  1443
            typename WM = typename GR::template EdgeMap<int> >
deba@869
  1444
#endif
deba@869
  1445
  class MaxWeightedPerfectFractionalMatching {
deba@869
  1446
  public:
deba@869
  1447
deba@869
  1448
    /// The graph type of the algorithm
deba@869
  1449
    typedef GR Graph;
deba@869
  1450
    /// The type of the edge weight map
deba@869
  1451
    typedef WM WeightMap;
deba@869
  1452
    /// The value type of the edge weights
deba@869
  1453
    typedef typename WeightMap::Value Value;
deba@869
  1454
deba@869
  1455
    /// The type of the matching map
deba@869
  1456
    typedef typename Graph::template NodeMap<typename Graph::Arc>
deba@869
  1457
    MatchingMap;
deba@869
  1458
deba@869
  1459
    /// \brief Scaling factor for primal solution
deba@869
  1460
    ///
deba@872
  1461
    /// Scaling factor for primal solution.
deba@872
  1462
    static const int primalScale = 2;
deba@869
  1463
deba@869
  1464
    /// \brief Scaling factor for dual solution
deba@869
  1465
    ///
deba@869
  1466
    /// Scaling factor for dual solution. It is equal to 4 or 1
deba@869
  1467
    /// according to the value type.
deba@869
  1468
    static const int dualScale =
deba@869
  1469
      std::numeric_limits<Value>::is_integer ? 4 : 1;
deba@869
  1470
deba@869
  1471
  private:
deba@869
  1472
deba@869
  1473
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
deba@869
  1474
deba@869
  1475
    typedef typename Graph::template NodeMap<Value> NodePotential;
deba@869
  1476
deba@869
  1477
    const Graph& _graph;
deba@869
  1478
    const WeightMap& _weight;
deba@869
  1479
deba@869
  1480
    MatchingMap* _matching;
deba@869
  1481
    NodePotential* _node_potential;
deba@869
  1482
deba@869
  1483
    int _node_num;
deba@869
  1484
    bool _allow_loops;
deba@869
  1485
deba@869
  1486
    enum Status {
deba@869
  1487
      EVEN = -1, MATCHED = 0, ODD = 1
deba@869
  1488
    };
deba@869
  1489
deba@869
  1490
    typedef typename Graph::template NodeMap<Status> StatusMap;
deba@869
  1491
    StatusMap* _status;
deba@869
  1492
deba@869
  1493
    typedef typename Graph::template NodeMap<Arc> PredMap;
deba@869
  1494
    PredMap* _pred;
deba@869
  1495
deba@869
  1496
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
deba@869
  1497
deba@869
  1498
    IntNodeMap *_tree_set_index;
deba@869
  1499
    TreeSet *_tree_set;
deba@869
  1500
deba@869
  1501
    IntNodeMap *_delta2_index;
deba@869
  1502
    BinHeap<Value, IntNodeMap> *_delta2;
deba@869
  1503
deba@869
  1504
    IntEdgeMap *_delta3_index;
deba@869
  1505
    BinHeap<Value, IntEdgeMap> *_delta3;
deba@869
  1506
deba@869
  1507
    Value _delta_sum;
deba@869
  1508
deba@869
  1509
    void createStructures() {
deba@869
  1510
      _node_num = countNodes(_graph);
deba@869
  1511
deba@869
  1512
      if (!_matching) {
deba@869
  1513
        _matching = new MatchingMap(_graph);
deba@869
  1514
      }
deba@869
  1515
      if (!_node_potential) {
deba@869
  1516
        _node_potential = new NodePotential(_graph);
deba@869
  1517
      }
deba@869
  1518
      if (!_status) {
deba@869
  1519
        _status = new StatusMap(_graph);
deba@869
  1520
      }
deba@869
  1521
      if (!_pred) {
deba@869
  1522
        _pred = new PredMap(_graph);
deba@869
  1523
      }
deba@869
  1524
      if (!_tree_set) {
deba@869
  1525
        _tree_set_index = new IntNodeMap(_graph);
deba@869
  1526
        _tree_set = new TreeSet(*_tree_set_index);
deba@869
  1527
      }
deba@869
  1528
      if (!_delta2) {
deba@869
  1529
        _delta2_index = new IntNodeMap(_graph);
deba@869
  1530
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
deba@869
  1531
      }
deba@869
  1532
      if (!_delta3) {
deba@869
  1533
        _delta3_index = new IntEdgeMap(_graph);
deba@869
  1534
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
deba@869
  1535
      }
deba@869
  1536
    }
deba@869
  1537
deba@869
  1538
    void destroyStructures() {
deba@869
  1539
      if (_matching) {
deba@869
  1540
        delete _matching;
deba@869
  1541
      }
deba@869
  1542
      if (_node_potential) {
deba@869
  1543
        delete _node_potential;
deba@869
  1544
      }
deba@869
  1545
      if (_status) {
deba@869
  1546
        delete _status;
deba@869
  1547
      }
deba@869
  1548
      if (_pred) {
deba@869
  1549
        delete _pred;
deba@869
  1550
      }
deba@869
  1551
      if (_tree_set) {
deba@869
  1552
        delete _tree_set_index;
deba@869
  1553
        delete _tree_set;
deba@869
  1554
      }
deba@869
  1555
      if (_delta2) {
deba@869
  1556
        delete _delta2_index;
deba@869
  1557
        delete _delta2;
deba@869
  1558
      }
deba@869
  1559
      if (_delta3) {
deba@869
  1560
        delete _delta3_index;
deba@869
  1561
        delete _delta3;
deba@869
  1562
      }
deba@869
  1563
    }
deba@869
  1564
deba@869
  1565
    void matchedToEven(Node node, int tree) {
deba@869
  1566
      _tree_set->insert(node, tree);
deba@869
  1567
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
  1568
deba@869
  1569
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
  1570
        _delta2->erase(node);
deba@869
  1571
      }
deba@869
  1572
deba@869
  1573
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
  1574
        Node v = _graph.source(a);
deba@869
  1575
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
  1576
          dualScale * _weight[a];
deba@869
  1577
        if (node == v) {
deba@869
  1578
          if (_allow_loops && _graph.direction(a)) {
deba@869
  1579
            _delta3->push(a, rw / 2);
deba@869
  1580
          }
deba@869
  1581
        } else if ((*_status)[v] == EVEN) {
deba@869
  1582
          _delta3->push(a, rw / 2);
deba@869
  1583
        } else if ((*_status)[v] == MATCHED) {
deba@869
  1584
          if (_delta2->state(v) != _delta2->IN_HEAP) {
deba@869
  1585
            _pred->set(v, a);
deba@869
  1586
            _delta2->push(v, rw);
deba@869
  1587
          } else if ((*_delta2)[v] > rw) {
deba@869
  1588
            _pred->set(v, a);
deba@869
  1589
            _delta2->decrease(v, rw);
deba@869
  1590
          }
deba@869
  1591
        }
deba@869
  1592
      }
deba@869
  1593
    }
deba@869
  1594
deba@869
  1595
    void matchedToOdd(Node node, int tree) {
deba@869
  1596
      _tree_set->insert(node, tree);
deba@869
  1597
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
  1598
deba@869
  1599
      if (_delta2->state(node) == _delta2->IN_HEAP) {
deba@869
  1600
        _delta2->erase(node);
deba@869
  1601
      }
deba@869
  1602
    }
deba@869
  1603
deba@869
  1604
    void evenToMatched(Node node, int tree) {
deba@869
  1605
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
deba@869
  1606
      Arc min = INVALID;
deba@869
  1607
      Value minrw = std::numeric_limits<Value>::max();
deba@869
  1608
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
  1609
        Node v = _graph.source(a);
deba@869
  1610
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
  1611
          dualScale * _weight[a];
deba@869
  1612
deba@869
  1613
        if (node == v) {
deba@869
  1614
          if (_allow_loops && _graph.direction(a)) {
deba@869
  1615
            _delta3->erase(a);
deba@869
  1616
          }
deba@869
  1617
        } else if ((*_status)[v] == EVEN) {
deba@869
  1618
          _delta3->erase(a);
deba@869
  1619
          if (minrw > rw) {
deba@869
  1620
            min = _graph.oppositeArc(a);
deba@869
  1621
            minrw = rw;
deba@869
  1622
          }
deba@869
  1623
        } else if ((*_status)[v]  == MATCHED) {
deba@869
  1624
          if ((*_pred)[v] == a) {
deba@869
  1625
            Arc mina = INVALID;
deba@869
  1626
            Value minrwa = std::numeric_limits<Value>::max();
deba@869
  1627
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
deba@869
  1628
              Node va = _graph.target(aa);
deba@869
  1629
              if ((*_status)[va] != EVEN ||
deba@869
  1630
                  _tree_set->find(va) == tree) continue;
deba@869
  1631
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
deba@869
  1632
                dualScale * _weight[aa];
deba@869
  1633
              if (minrwa > rwa) {
deba@869
  1634
                minrwa = rwa;
deba@869
  1635
                mina = aa;
deba@869
  1636
              }
deba@869
  1637
            }
deba@869
  1638
            if (mina != INVALID) {
deba@869
  1639
              _pred->set(v, mina);
deba@869
  1640
              _delta2->increase(v, minrwa);
deba@869
  1641
            } else {
deba@869
  1642
              _pred->set(v, INVALID);
deba@869
  1643
              _delta2->erase(v);
deba@869
  1644
            }
deba@869
  1645
          }
deba@869
  1646
        }
deba@869
  1647
      }
deba@869
  1648
      if (min != INVALID) {
deba@869
  1649
        _pred->set(node, min);
deba@869
  1650
        _delta2->push(node, minrw);
deba@869
  1651
      } else {
deba@869
  1652
        _pred->set(node, INVALID);
deba@869
  1653
      }
deba@869
  1654
    }
deba@869
  1655
deba@869
  1656
    void oddToMatched(Node node) {
deba@869
  1657
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
deba@869
  1658
      Arc min = INVALID;
deba@869
  1659
      Value minrw = std::numeric_limits<Value>::max();
deba@869
  1660
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
deba@869
  1661
        Node v = _graph.source(a);
deba@869
  1662
        if ((*_status)[v] != EVEN) continue;
deba@869
  1663
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
deba@869
  1664
          dualScale * _weight[a];
deba@869
  1665
deba@869
  1666
        if (minrw > rw) {
deba@869
  1667
          min = _graph.oppositeArc(a);
deba@869
  1668
          minrw = rw;
deba@869
  1669
        }
deba@869
  1670
      }
deba@869
  1671
      if (min != INVALID) {
deba@869
  1672
        _pred->set(node, min);
deba@869
  1673
        _delta2->push(node, minrw);
deba@869
  1674
      } else {
deba@869
  1675
        _pred->set(node, INVALID);
deba@869
  1676
      }
deba@869
  1677
    }
deba@869
  1678
deba@869
  1679
    void alternatePath(Node even, int tree) {
deba@869
  1680
      Node odd;
deba@869
  1681
deba@869
  1682
      _status->set(even, MATCHED);
deba@869
  1683
      evenToMatched(even, tree);
deba@869
  1684
deba@869
  1685
      Arc prev = (*_matching)[even];
deba@869
  1686
      while (prev != INVALID) {
deba@869
  1687
        odd = _graph.target(prev);
deba@869
  1688
        even = _graph.target((*_pred)[odd]);
deba@869
  1689
        _matching->set(odd, (*_pred)[odd]);
deba@869
  1690
        _status->set(odd, MATCHED);
deba@869
  1691
        oddToMatched(odd);
deba@869
  1692
deba@869
  1693
        prev = (*_matching)[even];
deba@869
  1694
        _status->set(even, MATCHED);
deba@869
  1695
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
deba@869
  1696
        evenToMatched(even, tree);
deba@869
  1697
      }
deba@869
  1698
    }
deba@869
  1699
deba@869
  1700
    void destroyTree(int tree) {
deba@869
  1701
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
deba@869
  1702
        if ((*_status)[n] == EVEN) {
deba@869
  1703
          _status->set(n, MATCHED);
deba@869
  1704
          evenToMatched(n, tree);
deba@869
  1705
        } else if ((*_status)[n] == ODD) {
deba@869
  1706
          _status->set(n, MATCHED);
deba@869
  1707
          oddToMatched(n);
deba@869
  1708
        }
deba@869
  1709
      }
deba@869
  1710
      _tree_set->eraseClass(tree);
deba@869
  1711
    }
deba@869
  1712
deba@869
  1713
    void augmentOnEdge(const Edge& edge) {
deba@869
  1714
      Node left = _graph.u(edge);
deba@869
  1715
      int left_tree = _tree_set->find(left);
deba@869
  1716
deba@869
  1717
      alternatePath(left, left_tree);
deba@869
  1718
      destroyTree(left_tree);
deba@869
  1719
      _matching->set(left, _graph.direct(edge, true));
deba@869
  1720
deba@869
  1721
      Node right = _graph.v(edge);
deba@869
  1722
      int right_tree = _tree_set->find(right);
deba@869
  1723
deba@869
  1724
      alternatePath(right, right_tree);
deba@869
  1725
      destroyTree(right_tree);
deba@869
  1726
      _matching->set(right, _graph.direct(edge, false));
deba@869
  1727
    }
deba@869
  1728
deba@869
  1729
    void augmentOnArc(const Arc& arc) {
deba@869
  1730
      Node left = _graph.source(arc);
deba@869
  1731
      _status->set(left, MATCHED);
deba@869
  1732
      _matching->set(left, arc);
deba@869
  1733
      _pred->set(left, arc);
deba@869
  1734
deba@869
  1735
      Node right = _graph.target(arc);
deba@869
  1736
      int right_tree = _tree_set->find(right);
deba@869
  1737
deba@869
  1738
      alternatePath(right, right_tree);
deba@869
  1739
      destroyTree(right_tree);
deba@869
  1740
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
  1741
    }
deba@869
  1742
deba@869
  1743
    void extendOnArc(const Arc& arc) {
deba@869
  1744
      Node base = _graph.target(arc);
deba@869
  1745
      int tree = _tree_set->find(base);
deba@869
  1746
deba@869
  1747
      Node odd = _graph.source(arc);
deba@869
  1748
      _tree_set->insert(odd, tree);
deba@869
  1749
      _status->set(odd, ODD);
deba@869
  1750
      matchedToOdd(odd, tree);
deba@869
  1751
      _pred->set(odd, arc);
deba@869
  1752
deba@869
  1753
      Node even = _graph.target((*_matching)[odd]);
deba@869
  1754
      _tree_set->insert(even, tree);
deba@869
  1755
      _status->set(even, EVEN);
deba@869
  1756
      matchedToEven(even, tree);
deba@869
  1757
    }
deba@869
  1758
deba@869
  1759
    void cycleOnEdge(const Edge& edge, int tree) {
deba@869
  1760
      Node nca = INVALID;
deba@869
  1761
      std::vector<Node> left_path, right_path;
deba@869
  1762
deba@869
  1763
      {
deba@869
  1764
        std::set<Node> left_set, right_set;
deba@869
  1765
        Node left = _graph.u(edge);
deba@869
  1766
        left_path.push_back(left);
deba@869
  1767
        left_set.insert(left);
deba@869
  1768
deba@869
  1769
        Node right = _graph.v(edge);
deba@869
  1770
        right_path.push_back(right);
deba@869
  1771
        right_set.insert(right);
deba@869
  1772
deba@869
  1773
        while (true) {
deba@869
  1774
deba@869
  1775
          if (left_set.find(right) != left_set.end()) {
deba@869
  1776
            nca = right;
deba@869
  1777
            break;
deba@869
  1778
          }
deba@869
  1779
deba@869
  1780
          if ((*_matching)[left] == INVALID) break;
deba@869
  1781
deba@869
  1782
          left = _graph.target((*_matching)[left]);
deba@869
  1783
          left_path.push_back(left);
deba@869
  1784
          left = _graph.target((*_pred)[left]);
deba@869
  1785
          left_path.push_back(left);
deba@869
  1786
deba@869
  1787
          left_set.insert(left);
deba@869
  1788
deba@869
  1789
          if (right_set.find(left) != right_set.end()) {
deba@869
  1790
            nca = left;
deba@869
  1791
            break;
deba@869
  1792
          }
deba@869
  1793
deba@869
  1794
          if ((*_matching)[right] == INVALID) break;
deba@869
  1795
deba@869
  1796
          right = _graph.target((*_matching)[right]);
deba@869
  1797
          right_path.push_back(right);
deba@869
  1798
          right = _graph.target((*_pred)[right]);
deba@869
  1799
          right_path.push_back(right);
deba@869
  1800
deba@869
  1801
          right_set.insert(right);
deba@869
  1802
deba@869
  1803
        }
deba@869
  1804
deba@869
  1805
        if (nca == INVALID) {
deba@869
  1806
          if ((*_matching)[left] == INVALID) {
deba@869
  1807
            nca = right;
deba@869
  1808
            while (left_set.find(nca) == left_set.end()) {
deba@869
  1809
              nca = _graph.target((*_matching)[nca]);
deba@869
  1810
              right_path.push_back(nca);
deba@869
  1811
              nca = _graph.target((*_pred)[nca]);
deba@869
  1812
              right_path.push_back(nca);
deba@869
  1813
            }
deba@869
  1814
          } else {
deba@869
  1815
            nca = left;
deba@869
  1816
            while (right_set.find(nca) == right_set.end()) {
deba@869
  1817
              nca = _graph.target((*_matching)[nca]);
deba@869
  1818
              left_path.push_back(nca);
deba@869
  1819
              nca = _graph.target((*_pred)[nca]);
deba@869
  1820
              left_path.push_back(nca);
deba@869
  1821
            }
deba@869
  1822
          }
deba@869
  1823
        }
deba@869
  1824
      }
deba@869
  1825
deba@869
  1826
      alternatePath(nca, tree);
deba@869
  1827
      Arc prev;
deba@869
  1828
deba@869
  1829
      prev = _graph.direct(edge, true);
deba@869
  1830
      for (int i = 0; left_path[i] != nca; i += 2) {
deba@869
  1831
        _matching->set(left_path[i], prev);
deba@869
  1832
        _status->set(left_path[i], MATCHED);
deba@869
  1833
        evenToMatched(left_path[i], tree);
deba@869
  1834
deba@869
  1835
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
deba@869
  1836
        _status->set(left_path[i + 1], MATCHED);
deba@869
  1837
        oddToMatched(left_path[i + 1]);
deba@869
  1838
      }
deba@869
  1839
      _matching->set(nca, prev);
deba@869
  1840
deba@869
  1841
      for (int i = 0; right_path[i] != nca; i += 2) {
deba@869
  1842
        _status->set(right_path[i], MATCHED);
deba@869
  1843
        evenToMatched(right_path[i], tree);
deba@869
  1844
deba@869
  1845
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
deba@869
  1846
        _status->set(right_path[i + 1], MATCHED);
deba@869
  1847
        oddToMatched(right_path[i + 1]);
deba@869
  1848
      }
deba@869
  1849
deba@869
  1850
      destroyTree(tree);
deba@869
  1851
    }
deba@869
  1852
deba@869
  1853
    void extractCycle(const Arc &arc) {
deba@869
  1854
      Node left = _graph.source(arc);
deba@869
  1855
      Node odd = _graph.target((*_matching)[left]);
deba@869
  1856
      Arc prev;
deba@869
  1857
      while (odd != left) {
deba@869
  1858
        Node even = _graph.target((*_matching)[odd]);
deba@869
  1859
        prev = (*_matching)[odd];
deba@869
  1860
        odd = _graph.target((*_matching)[even]);
deba@869
  1861
        _matching->set(even, _graph.oppositeArc(prev));
deba@869
  1862
      }
deba@869
  1863
      _matching->set(left, arc);
deba@869
  1864
deba@869
  1865
      Node right = _graph.target(arc);
deba@869
  1866
      int right_tree = _tree_set->find(right);
deba@869
  1867
      alternatePath(right, right_tree);
deba@869
  1868
      destroyTree(right_tree);
deba@869
  1869
      _matching->set(right, _graph.oppositeArc(arc));
deba@869
  1870
    }
deba@869
  1871
deba@869
  1872
  public:
deba@869
  1873
deba@869
  1874
    /// \brief Constructor
deba@869
  1875
    ///
deba@869
  1876
    /// Constructor.
deba@869
  1877
    MaxWeightedPerfectFractionalMatching(const Graph& graph,
deba@869
  1878
                                         const WeightMap& weight,
deba@869
  1879
                                         bool allow_loops = true)
deba@869
  1880
      : _graph(graph), _weight(weight), _matching(0),
deba@869
  1881
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
deba@869
  1882
      _status(0),  _pred(0),
deba@869
  1883
      _tree_set_index(0), _tree_set(0),
deba@869
  1884
deba@869
  1885
      _delta2_index(0), _delta2(0),
deba@869
  1886
      _delta3_index(0), _delta3(0),
deba@869
  1887
deba@869
  1888
      _delta_sum() {}
deba@869
  1889
deba@869
  1890
    ~MaxWeightedPerfectFractionalMatching() {
deba@869
  1891
      destroyStructures();
deba@869
  1892
    }
deba@869
  1893
deba@869
  1894
    /// \name Execution Control
deba@869
  1895
    /// The simplest way to execute the algorithm is to use the
deba@869
  1896
    /// \ref run() member function.
deba@869
  1897
deba@869
  1898
    ///@{
deba@869
  1899
deba@869
  1900
    /// \brief Initialize the algorithm
deba@869
  1901
    ///
deba@869
  1902
    /// This function initializes the algorithm.
deba@869
  1903
    void init() {
deba@869
  1904
      createStructures();
deba@869
  1905
deba@869
  1906
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1907
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
deba@869
  1908
      }
deba@869
  1909
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1910
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
deba@869
  1911
      }
deba@869
  1912
deba@876
  1913
      _delta2->clear();
deba@876
  1914
      _delta3->clear();
deba@876
  1915
      _tree_set->clear();
deba@876
  1916
deba@869
  1917
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  1918
        Value max = - std::numeric_limits<Value>::max();
deba@869
  1919
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@869
  1920
          if (_graph.target(e) == n && !_allow_loops) continue;
deba@869
  1921
          if ((dualScale * _weight[e]) / 2 > max) {
deba@869
  1922
            max = (dualScale * _weight[e]) / 2;
deba@869
  1923
          }
deba@869
  1924
        }
deba@869
  1925
        _node_potential->set(n, max);
deba@869
  1926
deba@869
  1927
        _tree_set->insert(n);
deba@869
  1928
deba@869
  1929
        _matching->set(n, INVALID);
deba@869
  1930
        _status->set(n, EVEN);
deba@869
  1931
      }
deba@869
  1932
deba@869
  1933
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@869
  1934
        Node left = _graph.u(e);
deba@869
  1935
        Node right = _graph.v(e);
deba@869
  1936
        if (left == right && !_allow_loops) continue;
deba@869
  1937
        _delta3->push(e, ((*_node_potential)[left] +
deba@869
  1938
                          (*_node_potential)[right] -
deba@869
  1939
                          dualScale * _weight[e]) / 2);
deba@869
  1940
      }
deba@869
  1941
    }
deba@869
  1942
deba@869
  1943
    /// \brief Start the algorithm
deba@869
  1944
    ///
deba@869
  1945
    /// This function starts the algorithm.
deba@869
  1946
    ///
deba@869
  1947
    /// \pre \ref init() must be called before using this function.
deba@869
  1948
    bool start() {
deba@869
  1949
      enum OpType {
deba@869
  1950
        D2, D3
deba@869
  1951
      };
deba@869
  1952
deba@869
  1953
      int unmatched = _node_num;
deba@869
  1954
      while (unmatched > 0) {
deba@869
  1955
        Value d2 = !_delta2->empty() ?
deba@869
  1956
          _delta2->prio() : std::numeric_limits<Value>::max();
deba@869
  1957
deba@869
  1958
        Value d3 = !_delta3->empty() ?
deba@869
  1959
          _delta3->prio() : std::numeric_limits<Value>::max();
deba@869
  1960
deba@869
  1961
        _delta_sum = d3; OpType ot = D3;
deba@869
  1962
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
deba@869
  1963
deba@869
  1964
        if (_delta_sum == std::numeric_limits<Value>::max()) {
deba@869
  1965
          return false;
deba@869
  1966
        }
deba@869
  1967
deba@869
  1968
        switch (ot) {
deba@869
  1969
        case D2:
deba@869
  1970
          {
deba@869
  1971
            Node n = _delta2->top();
deba@869
  1972
            Arc a = (*_pred)[n];
deba@869
  1973
            if ((*_matching)[n] == INVALID) {
deba@869
  1974
              augmentOnArc(a);
deba@869
  1975
              --unmatched;
deba@869
  1976
            } else {
deba@869
  1977
              Node v = _graph.target((*_matching)[n]);
deba@869
  1978
              if ((*_matching)[n] !=
deba@869
  1979
                  _graph.oppositeArc((*_matching)[v])) {
deba@869
  1980
                extractCycle(a);
deba@869
  1981
                --unmatched;
deba@869
  1982
              } else {
deba@869
  1983
                extendOnArc(a);
deba@869
  1984
              }
deba@869
  1985
            }
deba@869
  1986
          } break;
deba@869
  1987
        case D3:
deba@869
  1988
          {
deba@869
  1989
            Edge e = _delta3->top();
deba@869
  1990
deba@869
  1991
            Node left = _graph.u(e);
deba@869
  1992
            Node right = _graph.v(e);
deba@869
  1993
deba@869
  1994
            int left_tree = _tree_set->find(left);
deba@869
  1995
            int right_tree = _tree_set->find(right);
deba@869
  1996
deba@869
  1997
            if (left_tree == right_tree) {
deba@869
  1998
              cycleOnEdge(e, left_tree);
deba@869
  1999
              --unmatched;
deba@869
  2000
            } else {
deba@869
  2001
              augmentOnEdge(e);
deba@869
  2002
              unmatched -= 2;
deba@869
  2003
            }
deba@869
  2004
          } break;
deba@869
  2005
        }
deba@869
  2006
      }
deba@869
  2007
      return true;
deba@869
  2008
    }
deba@869
  2009
deba@869
  2010
    /// \brief Run the algorithm.
deba@869
  2011
    ///
alpar@877
  2012
    /// This method runs the \c %MaxWeightedPerfectFractionalMatching
deba@871
  2013
    /// algorithm.
deba@869
  2014
    ///
deba@869
  2015
    /// \note mwfm.run() is just a shortcut of the following code.
deba@869
  2016
    /// \code
deba@869
  2017
    ///   mwpfm.init();
deba@869
  2018
    ///   mwpfm.start();
deba@869
  2019
    /// \endcode
deba@869
  2020
    bool run() {
deba@869
  2021
      init();
deba@869
  2022
      return start();
deba@869
  2023
    }
deba@869
  2024
deba@869
  2025
    /// @}
deba@869
  2026
deba@869
  2027
    /// \name Primal Solution
deba@869
  2028
    /// Functions to get the primal solution, i.e. the maximum weighted
deba@869
  2029
    /// matching.\n
deba@869
  2030
    /// Either \ref run() or \ref start() function should be called before
deba@869
  2031
    /// using them.
deba@869
  2032
deba@869
  2033
    /// @{
deba@869
  2034
deba@869
  2035
    /// \brief Return the weight of the matching.
deba@869
  2036
    ///
deba@869
  2037
    /// This function returns the weight of the found matching. This
deba@869
  2038
    /// value is scaled by \ref primalScale "primal scale".
deba@869
  2039
    ///
deba@869
  2040
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2041
    Value matchingWeight() const {
deba@869
  2042
      Value sum = 0;
deba@869
  2043
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  2044
        if ((*_matching)[n] != INVALID) {
deba@869
  2045
          sum += _weight[(*_matching)[n]];
deba@869
  2046
        }
deba@869
  2047
      }
deba@869
  2048
      return sum * primalScale / 2;
deba@869
  2049
    }
deba@869
  2050
deba@869
  2051
    /// \brief Return the number of covered nodes in the matching.
deba@869
  2052
    ///
deba@869
  2053
    /// This function returns the number of covered nodes in the matching.
deba@869
  2054
    ///
deba@869
  2055
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2056
    int matchingSize() const {
deba@869
  2057
      int num = 0;
deba@869
  2058
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  2059
        if ((*_matching)[n] != INVALID) {
deba@869
  2060
          ++num;
deba@869
  2061
        }
deba@869
  2062
      }
deba@869
  2063
      return num;
deba@869
  2064
    }
deba@869
  2065
deba@869
  2066
    /// \brief Return \c true if the given edge is in the matching.
deba@869
  2067
    ///
deba@869
  2068
    /// This function returns \c true if the given edge is in the
deba@869
  2069
    /// found matching. The result is scaled by \ref primalScale
deba@869
  2070
    /// "primal scale".
deba@869
  2071
    ///
deba@869
  2072
    /// \pre Either run() or start() must be called before using this function.
deba@872
  2073
    int matching(const Edge& edge) const {
deba@872
  2074
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
deba@872
  2075
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
deba@869
  2076
    }
deba@869
  2077
deba@869
  2078
    /// \brief Return the fractional matching arc (or edge) incident
deba@869
  2079
    /// to the given node.
deba@869
  2080
    ///
deba@869
  2081
    /// This function returns one of the fractional matching arc (or
deba@869
  2082
    /// edge) incident to the given node in the found matching or \c
deba@869
  2083
    /// INVALID if the node is not covered by the matching or if the
deba@869
  2084
    /// node is on an odd length cycle then it is the successor edge
deba@869
  2085
    /// on the cycle.
deba@869
  2086
    ///
deba@869
  2087
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2088
    Arc matching(const Node& node) const {
deba@869
  2089
      return (*_matching)[node];
deba@869
  2090
    }
deba@869
  2091
deba@869
  2092
    /// \brief Return a const reference to the matching map.
deba@869
  2093
    ///
deba@869
  2094
    /// This function returns a const reference to a node map that stores
deba@869
  2095
    /// the matching arc (or edge) incident to each node.
deba@869
  2096
    const MatchingMap& matchingMap() const {
deba@869
  2097
      return *_matching;
deba@869
  2098
    }
deba@869
  2099
deba@869
  2100
    /// @}
deba@869
  2101
deba@869
  2102
    /// \name Dual Solution
deba@869
  2103
    /// Functions to get the dual solution.\n
deba@869
  2104
    /// Either \ref run() or \ref start() function should be called before
deba@869
  2105
    /// using them.
deba@869
  2106
deba@869
  2107
    /// @{
deba@869
  2108
deba@869
  2109
    /// \brief Return the value of the dual solution.
deba@869
  2110
    ///
deba@869
  2111
    /// This function returns the value of the dual solution.
deba@869
  2112
    /// It should be equal to the primal value scaled by \ref dualScale
deba@869
  2113
    /// "dual scale".
deba@869
  2114
    ///
deba@869
  2115
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2116
    Value dualValue() const {
deba@869
  2117
      Value sum = 0;
deba@869
  2118
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@869
  2119
        sum += nodeValue(n);
deba@869
  2120
      }
deba@869
  2121
      return sum;
deba@869
  2122
    }
deba@869
  2123
deba@869
  2124
    /// \brief Return the dual value (potential) of the given node.
deba@869
  2125
    ///
deba@869
  2126
    /// This function returns the dual value (potential) of the given node.
deba@869
  2127
    ///
deba@869
  2128
    /// \pre Either run() or start() must be called before using this function.
deba@869
  2129
    Value nodeValue(const Node& n) const {
deba@869
  2130
      return (*_node_potential)[n];
deba@869
  2131
    }
deba@869
  2132
deba@869
  2133
    /// @}
deba@869
  2134
deba@869
  2135
  };
deba@869
  2136
deba@869
  2137
} //END OF NAMESPACE LEMON
deba@869
  2138
deba@869
  2139
#endif //LEMON_FRACTIONAL_MATCHING_H