COIN-OR::LEMON - Graph Library

Ignore:
Files:
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • doc/groups.dox

    r953 r952  
    387387problem of maximum flow.
    388388
    389 \ref Circulation is a preflow push-relabel algorithm implemented directly
     389\ref Circulation is a preflow push-relabel algorithm implemented directly 
    390390for finding feasible circulations, which is a somewhat different problem,
    391391but it is strongly related to maximum flow.
     
    523523  Edmond's blossom shrinking algorithm for calculating maximum weighted
    524524  perfect matching in general graphs.
    525 - \ref MaxFractionalMatching Push-relabel algorithm for calculating
    526   maximum cardinality fractional matching in general graphs.
    527 - \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
    528   maximum weighted fractional matching in general graphs.
    529 - \ref MaxWeightedPerfectFractionalMatching
    530   Augmenting path algorithm for calculating maximum weighted
    531   perfect fractional matching in general graphs.
    532525
    533526\image html matching.png
  • lemon/Makefile.am

    r953 r942  
    8585        lemon/euler.h \
    8686        lemon/fib_heap.h \
    87         lemon/fractional_matching.h \
    8887        lemon/full_graph.h \
    8988        lemon/glpk.h \
  • lemon/matching.h

    r949 r698  
    1717 */
    1818
    19 #ifndef LEMON_MATCHING_H
    20 #define LEMON_MATCHING_H
     19#ifndef LEMON_MAX_MATCHING_H
     20#define LEMON_MAX_MATCHING_H
    2121
    2222#include <vector>
     
    2929#include <lemon/bin_heap.h>
    3030#include <lemon/maps.h>
    31 #include <lemon/fractional_matching.h>
    3231
    3332///\ingroup matching
     
    4342  /// This class implements Edmonds' alternating forest matching algorithm
    4443  /// for finding a maximum cardinality matching in a general undirected graph.
    45   /// It can be started from an arbitrary initial matching
     44  /// It can be started from an arbitrary initial matching 
    4645  /// (the default is the empty one).
    4746  ///
     
    7170    ///\brief Status constants for Gallai-Edmonds decomposition.
    7271    ///
    73     ///These constants are used for indicating the Gallai-Edmonds
     72    ///These constants are used for indicating the Gallai-Edmonds 
    7473    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
    7574    ///induce a subgraph with factor-critical components, the nodes with
    7675    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
    77     ///with status \c MATCHED (or \c C) induce a subgraph having a
     76    ///with status \c MATCHED (or \c C) induce a subgraph having a 
    7877    ///perfect matching.
    7978    enum Status {
     
    514513    }
    515514
    516     /// \brief Start Edmonds' algorithm with a heuristic improvement
     515    /// \brief Start Edmonds' algorithm with a heuristic improvement 
    517516    /// for dense graphs
    518517    ///
     
    536535    /// \brief Run Edmonds' algorithm
    537536    ///
    538     /// This function runs Edmonds' algorithm. An additional heuristic of
    539     /// postponing shrinks is used for relatively dense graphs
     537    /// This function runs Edmonds' algorithm. An additional heuristic of 
     538    /// postponing shrinks is used for relatively dense graphs 
    540539    /// (for which <tt>m>=2*n</tt> holds).
    541540    void run() {
     
    558557    /// \brief Return the size (cardinality) of the matching.
    559558    ///
    560     /// This function returns the size (cardinality) of the current matching.
     559    /// This function returns the size (cardinality) of the current matching. 
    561560    /// After run() it returns the size of the maximum matching in the graph.
    562561    int matchingSize() const {
     
    572571    /// \brief Return \c true if the given edge is in the matching.
    573572    ///
    574     /// This function returns \c true if the given edge is in the current
     573    /// This function returns \c true if the given edge is in the current 
    575574    /// matching.
    576575    bool matching(const Edge& edge) const {
     
    581580    ///
    582581    /// This function returns the matching arc (or edge) incident to the
    583     /// given node in the current matching or \c INVALID if the node is
     582    /// given node in the current matching or \c INVALID if the node is 
    584583    /// not covered by the matching.
    585584    Arc matching(const Node& n) const {
     
    597596    /// \brief Return the mate of the given node.
    598597    ///
    599     /// This function returns the mate of the given node in the current
     598    /// This function returns the mate of the given node in the current 
    600599    /// matching or \c INVALID if the node is not covered by the matching.
    601600    Node mate(const Node& n) const {
     
    607606
    608607    /// \name Dual Solution
    609     /// Functions to get the dual solution, i.e. the Gallai-Edmonds
     608    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
    610609    /// decomposition.
    611610
     
    650649  /// \f$O(nm\log n)\f$ time complexity.
    651650  ///
    652   /// The maximum weighted matching problem is to find a subset of the
    653   /// edges in an undirected graph with maximum overall weight for which
     651  /// The maximum weighted matching problem is to find a subset of the 
     652  /// edges in an undirected graph with maximum overall weight for which 
    654653  /// each node has at most one incident edge.
    655654  /// It can be formulated with the following linear program.
     
    675674      \frac{\vert B \vert - 1}{2}z_B\f] */
    676675  ///
    677   /// The algorithm can be executed with the run() function.
     676  /// The algorithm can be executed with the run() function. 
    678677  /// After it the matching (the primal solution) and the dual solution
    679   /// can be obtained using the query functions and the
    680   /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
    681   /// which is able to iterate on the nodes of a blossom.
     678  /// can be obtained using the query functions and the 
     679  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
     680  /// which is able to iterate on the nodes of a blossom. 
    682681  /// If the value type is integer, then the dual solution is multiplied
    683682  /// by \ref MaxWeightedMatching::dualScale "4".
    684683  ///
    685684  /// \tparam GR The undirected graph type the algorithm runs on.
    686   /// \tparam WM The type edge weight map. The default type is
     685  /// \tparam WM The type edge weight map. The default type is 
    687686  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
    688687#ifdef DOXYGEN
     
    747746
    748747    enum Status {
    749       EVEN = -1, MATCHED = 0, ODD = 1
     748      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
    750749    };
    751750
     
    799798
    800799    Value _delta_sum;
    801     int _unmatched;
    802 
    803     typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
    804     FractionalMatching *_fractional;
    805800
    806801    void createStructures() {
     
    850845
    851846    void destroyStructures() {
     847      _node_num = countNodes(_graph);
     848      _blossom_num = _node_num * 3 / 2;
     849
    852850      if (_matching) {
    853851        delete _matching;
     
    925923              _delta3->push(e, rw / 2);
    926924            }
     925          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
     926            if (_delta3->state(e) != _delta3->IN_HEAP) {
     927              _delta3->push(e, rw);
     928            }
    927929          } else {
     930            typename std::map<int, Arc>::iterator it =
     931              (*_node_data)[vi].heap_index.find(tree);
     932
     933            if (it != (*_node_data)[vi].heap_index.end()) {
     934              if ((*_node_data)[vi].heap[it->second] > rw) {
     935                (*_node_data)[vi].heap.replace(it->second, e);
     936                (*_node_data)[vi].heap.decrease(e, rw);
     937                it->second = e;
     938              }
     939            } else {
     940              (*_node_data)[vi].heap.push(e, rw);
     941              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
     942            }
     943
     944            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
     945              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
     946
     947              if ((*_blossom_data)[vb].status == MATCHED) {
     948                if (_delta2->state(vb) != _delta2->IN_HEAP) {
     949                  _delta2->push(vb, _blossom_set->classPrio(vb) -
     950                               (*_blossom_data)[vb].offset);
     951                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
     952                           (*_blossom_data)[vb].offset){
     953                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
     954                                   (*_blossom_data)[vb].offset);
     955                }
     956              }
     957            }
     958          }
     959        }
     960      }
     961      (*_blossom_data)[blossom].offset = 0;
     962    }
     963
     964    void matchedToOdd(int blossom) {
     965      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
     966        _delta2->erase(blossom);
     967      }
     968      (*_blossom_data)[blossom].offset += _delta_sum;
     969      if (!_blossom_set->trivial(blossom)) {
     970        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
     971                     (*_blossom_data)[blossom].offset);
     972      }
     973    }
     974
     975    void evenToMatched(int blossom, int tree) {
     976      if (!_blossom_set->trivial(blossom)) {
     977        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
     978      }
     979
     980      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
     981           n != INVALID; ++n) {
     982        int ni = (*_node_index)[n];
     983        (*_node_data)[ni].pot -= _delta_sum;
     984
     985        _delta1->erase(n);
     986
     987        for (InArcIt e(_graph, n); e != INVALID; ++e) {
     988          Node v = _graph.source(e);
     989          int vb = _blossom_set->find(v);
     990          int vi = (*_node_index)[v];
     991
     992          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
     993            dualScale * _weight[e];
     994
     995          if (vb == blossom) {
     996            if (_delta3->state(e) == _delta3->IN_HEAP) {
     997              _delta3->erase(e);
     998            }
     999          } else if ((*_blossom_data)[vb].status == EVEN) {
     1000
     1001            if (_delta3->state(e) == _delta3->IN_HEAP) {
     1002              _delta3->erase(e);
     1003            }
     1004
     1005            int vt = _tree_set->find(vb);
     1006
     1007            if (vt != tree) {
     1008
     1009              Arc r = _graph.oppositeArc(e);
     1010
     1011              typename std::map<int, Arc>::iterator it =
     1012                (*_node_data)[ni].heap_index.find(vt);
     1013
     1014              if (it != (*_node_data)[ni].heap_index.end()) {
     1015                if ((*_node_data)[ni].heap[it->second] > rw) {
     1016                  (*_node_data)[ni].heap.replace(it->second, r);
     1017                  (*_node_data)[ni].heap.decrease(r, rw);
     1018                  it->second = r;
     1019                }
     1020              } else {
     1021                (*_node_data)[ni].heap.push(r, rw);
     1022                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
     1023              }
     1024
     1025              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
     1026                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
     1027
     1028                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
     1029                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
     1030                               (*_blossom_data)[blossom].offset);
     1031                } else if ((*_delta2)[blossom] >
     1032                           _blossom_set->classPrio(blossom) -
     1033                           (*_blossom_data)[blossom].offset){
     1034                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
     1035                                   (*_blossom_data)[blossom].offset);
     1036                }
     1037              }
     1038            }
     1039
     1040          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
     1041            if (_delta3->state(e) == _delta3->IN_HEAP) {
     1042              _delta3->erase(e);
     1043            }
     1044          } else {
     1045
     1046            typename std::map<int, Arc>::iterator it =
     1047              (*_node_data)[vi].heap_index.find(tree);
     1048
     1049            if (it != (*_node_data)[vi].heap_index.end()) {
     1050              (*_node_data)[vi].heap.erase(it->second);
     1051              (*_node_data)[vi].heap_index.erase(it);
     1052              if ((*_node_data)[vi].heap.empty()) {
     1053                _blossom_set->increase(v, std::numeric_limits<Value>::max());
     1054              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
     1055                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
     1056              }
     1057
     1058              if ((*_blossom_data)[vb].status == MATCHED) {
     1059                if (_blossom_set->classPrio(vb) ==
     1060                    std::numeric_limits<Value>::max()) {
     1061                  _delta2->erase(vb);
     1062                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
     1063                           (*_blossom_data)[vb].offset) {
     1064                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
     1065                                   (*_blossom_data)[vb].offset);
     1066                }
     1067              }
     1068            }
     1069          }
     1070        }
     1071      }
     1072    }
     1073
     1074    void oddToMatched(int blossom) {
     1075      (*_blossom_data)[blossom].offset -= _delta_sum;
     1076
     1077      if (_blossom_set->classPrio(blossom) !=
     1078          std::numeric_limits<Value>::max()) {
     1079        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
     1080                       (*_blossom_data)[blossom].offset);
     1081      }
     1082
     1083      if (!_blossom_set->trivial(blossom)) {
     1084        _delta4->erase(blossom);
     1085      }
     1086    }
     1087
     1088    void oddToEven(int blossom, int tree) {
     1089      if (!_blossom_set->trivial(blossom)) {
     1090        _delta4->erase(blossom);
     1091        (*_blossom_data)[blossom].pot -=
     1092          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
     1093      }
     1094
     1095      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
     1096           n != INVALID; ++n) {
     1097        int ni = (*_node_index)[n];
     1098
     1099        _blossom_set->increase(n, std::numeric_limits<Value>::max());
     1100
     1101        (*_node_data)[ni].heap.clear();
     1102        (*_node_data)[ni].heap_index.clear();
     1103        (*_node_data)[ni].pot +=
     1104          2 * _delta_sum - (*_blossom_data)[blossom].offset;
     1105
     1106        _delta1->push(n, (*_node_data)[ni].pot);
     1107
     1108        for (InArcIt e(_graph, n); e != INVALID; ++e) {
     1109          Node v = _graph.source(e);
     1110          int vb = _blossom_set->find(v);
     1111          int vi = (*_node_index)[v];
     1112
     1113          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
     1114            dualScale * _weight[e];
     1115
     1116          if ((*_blossom_data)[vb].status == EVEN) {
     1117            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
     1118              _delta3->push(e, rw / 2);
     1119            }
     1120          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
     1121            if (_delta3->state(e) != _delta3->IN_HEAP) {
     1122              _delta3->push(e, rw);
     1123            }
     1124          } else {
     1125
    9281126            typename std::map<int, Arc>::iterator it =
    9291127              (*_node_data)[vi].heap_index.find(tree);
     
    9601158    }
    9611159
    962     void matchedToOdd(int blossom) {
     1160
     1161    void matchedToUnmatched(int blossom) {
    9631162      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
    9641163        _delta2->erase(blossom);
    965       }
    966       (*_blossom_data)[blossom].offset += _delta_sum;
    967       if (!_blossom_set->trivial(blossom)) {
    968         _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
    969                       (*_blossom_data)[blossom].offset);
    970       }
    971     }
    972 
    973     void evenToMatched(int blossom, int tree) {
    974       if (!_blossom_set->trivial(blossom)) {
    975         (*_blossom_data)[blossom].pot += 2 * _delta_sum;
    9761164      }
    9771165
     
    9791167           n != INVALID; ++n) {
    9801168        int ni = (*_node_index)[n];
    981         (*_node_data)[ni].pot -= _delta_sum;
    982 
    983         _delta1->erase(n);
     1169
     1170        _blossom_set->increase(n, std::numeric_limits<Value>::max());
     1171
     1172        (*_node_data)[ni].heap.clear();
     1173        (*_node_data)[ni].heap_index.clear();
     1174
     1175        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
     1176          Node v = _graph.target(e);
     1177          int vb = _blossom_set->find(v);
     1178          int vi = (*_node_index)[v];
     1179
     1180          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
     1181            dualScale * _weight[e];
     1182
     1183          if ((*_blossom_data)[vb].status == EVEN) {
     1184            if (_delta3->state(e) != _delta3->IN_HEAP) {
     1185              _delta3->push(e, rw);
     1186            }
     1187          }
     1188        }
     1189      }
     1190    }
     1191
     1192    void unmatchedToMatched(int blossom) {
     1193      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
     1194           n != INVALID; ++n) {
     1195        int ni = (*_node_index)[n];
    9841196
    9851197        for (InArcIt e(_graph, n); e != INVALID; ++e) {
     
    10031215            int vt = _tree_set->find(vb);
    10041216
    1005             if (vt != tree) {
    1006 
    1007               Arc r = _graph.oppositeArc(e);
    1008 
    1009               typename std::map<int, Arc>::iterator it =
    1010                 (*_node_data)[ni].heap_index.find(vt);
    1011 
    1012               if (it != (*_node_data)[ni].heap_index.end()) {
    1013                 if ((*_node_data)[ni].heap[it->second] > rw) {
    1014                   (*_node_data)[ni].heap.replace(it->second, r);
    1015                   (*_node_data)[ni].heap.decrease(r, rw);
    1016                   it->second = r;
    1017                 }
    1018               } else {
    1019                 (*_node_data)[ni].heap.push(r, rw);
    1020                 (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
    1021               }
    1022 
    1023               if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
    1024                 _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
    1025 
    1026                 if (_delta2->state(blossom) != _delta2->IN_HEAP) {
    1027                   _delta2->push(blossom, _blossom_set->classPrio(blossom) -
    1028                                (*_blossom_data)[blossom].offset);
    1029                 } else if ((*_delta2)[blossom] >
    1030                            _blossom_set->classPrio(blossom) -
    1031                            (*_blossom_data)[blossom].offset){
    1032                   _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
    1033                                    (*_blossom_data)[blossom].offset);
    1034                 }
    1035               }
    1036             }
    1037           } else {
     1217            Arc r = _graph.oppositeArc(e);
    10381218
    10391219            typename std::map<int, Arc>::iterator it =
    1040               (*_node_data)[vi].heap_index.find(tree);
    1041 
    1042             if (it != (*_node_data)[vi].heap_index.end()) {
    1043               (*_node_data)[vi].heap.erase(it->second);
    1044               (*_node_data)[vi].heap_index.erase(it);
    1045               if ((*_node_data)[vi].heap.empty()) {
    1046                 _blossom_set->increase(v, std::numeric_limits<Value>::max());
    1047               } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
    1048                 _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
    1049               }
    1050 
    1051               if ((*_blossom_data)[vb].status == MATCHED) {
    1052                 if (_blossom_set->classPrio(vb) ==
    1053                     std::numeric_limits<Value>::max()) {
    1054                   _delta2->erase(vb);
    1055                 } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
    1056                            (*_blossom_data)[vb].offset) {
    1057                   _delta2->increase(vb, _blossom_set->classPrio(vb) -
    1058                                    (*_blossom_data)[vb].offset);
    1059                 }
    1060               }
    1061             }
    1062           }
    1063         }
    1064       }
    1065     }
    1066 
    1067     void oddToMatched(int blossom) {
    1068       (*_blossom_data)[blossom].offset -= _delta_sum;
    1069 
    1070       if (_blossom_set->classPrio(blossom) !=
    1071           std::numeric_limits<Value>::max()) {
    1072         _delta2->push(blossom, _blossom_set->classPrio(blossom) -
    1073                       (*_blossom_data)[blossom].offset);
    1074       }
    1075 
    1076       if (!_blossom_set->trivial(blossom)) {
    1077         _delta4->erase(blossom);
    1078       }
    1079     }
    1080 
    1081     void oddToEven(int blossom, int tree) {
    1082       if (!_blossom_set->trivial(blossom)) {
    1083         _delta4->erase(blossom);
    1084         (*_blossom_data)[blossom].pot -=
    1085           2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
    1086       }
    1087 
    1088       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
    1089            n != INVALID; ++n) {
    1090         int ni = (*_node_index)[n];
    1091 
    1092         _blossom_set->increase(n, std::numeric_limits<Value>::max());
    1093 
    1094         (*_node_data)[ni].heap.clear();
    1095         (*_node_data)[ni].heap_index.clear();
    1096         (*_node_data)[ni].pot +=
    1097           2 * _delta_sum - (*_blossom_data)[blossom].offset;
    1098 
    1099         _delta1->push(n, (*_node_data)[ni].pot);
    1100 
    1101         for (InArcIt e(_graph, n); e != INVALID; ++e) {
    1102           Node v = _graph.source(e);
    1103           int vb = _blossom_set->find(v);
    1104           int vi = (*_node_index)[v];
    1105 
    1106           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
    1107             dualScale * _weight[e];
    1108 
    1109           if ((*_blossom_data)[vb].status == EVEN) {
    1110             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
    1111               _delta3->push(e, rw / 2);
    1112             }
    1113           } else {
    1114 
    1115             typename std::map<int, Arc>::iterator it =
    1116               (*_node_data)[vi].heap_index.find(tree);
    1117 
    1118             if (it != (*_node_data)[vi].heap_index.end()) {
    1119               if ((*_node_data)[vi].heap[it->second] > rw) {
    1120                 (*_node_data)[vi].heap.replace(it->second, e);
    1121                 (*_node_data)[vi].heap.decrease(e, rw);
    1122                 it->second = e;
     1220              (*_node_data)[ni].heap_index.find(vt);
     1221
     1222            if (it != (*_node_data)[ni].heap_index.end()) {
     1223              if ((*_node_data)[ni].heap[it->second] > rw) {
     1224                (*_node_data)[ni].heap.replace(it->second, r);
     1225                (*_node_data)[ni].heap.decrease(r, rw);
     1226                it->second = r;
    11231227              }
    11241228            } else {
    1125               (*_node_data)[vi].heap.push(e, rw);
    1126               (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
    1127             }
    1128 
    1129             if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
    1130               _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
    1131 
    1132               if ((*_blossom_data)[vb].status == MATCHED) {
    1133                 if (_delta2->state(vb) != _delta2->IN_HEAP) {
    1134                   _delta2->push(vb, _blossom_set->classPrio(vb) -
    1135                                (*_blossom_data)[vb].offset);
    1136                 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
    1137                            (*_blossom_data)[vb].offset) {
    1138                   _delta2->decrease(vb, _blossom_set->classPrio(vb) -
    1139                                    (*_blossom_data)[vb].offset);
    1140                 }
     1229              (*_node_data)[ni].heap.push(r, rw);
     1230              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
     1231            }
     1232
     1233            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
     1234              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
     1235
     1236              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
     1237                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
     1238                             (*_blossom_data)[blossom].offset);
     1239              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
     1240                         (*_blossom_data)[blossom].offset){
     1241                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
     1242                                 (*_blossom_data)[blossom].offset);
    11411243              }
    11421244            }
     1245
     1246          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
     1247            if (_delta3->state(e) == _delta3->IN_HEAP) {
     1248              _delta3->erase(e);
     1249            }
    11431250          }
    11441251        }
    11451252      }
    1146       (*_blossom_data)[blossom].offset = 0;
    11471253    }
    11481254
     
    11891295      destroyTree(tree);
    11901296
     1297      (*_blossom_data)[blossom].status = UNMATCHED;
    11911298      (*_blossom_data)[blossom].base = node;
    1192       (*_blossom_data)[blossom].next = INVALID;
    1193     }
     1299      matchedToUnmatched(blossom);
     1300    }
     1301
    11941302
    11951303    void augmentOnEdge(const Edge& edge) {
     
    11981306      int right = _blossom_set->find(_graph.v(edge));
    11991307
    1200       int left_tree = _tree_set->find(left);
    1201       alternatePath(left, left_tree);
    1202       destroyTree(left_tree);
    1203 
    1204       int right_tree = _tree_set->find(right);
    1205       alternatePath(right, right_tree);
    1206       destroyTree(right_tree);
     1308      if ((*_blossom_data)[left].status == EVEN) {
     1309        int left_tree = _tree_set->find(left);
     1310        alternatePath(left, left_tree);
     1311        destroyTree(left_tree);
     1312      } else {
     1313        (*_blossom_data)[left].status = MATCHED;
     1314        unmatchedToMatched(left);
     1315      }
     1316
     1317      if ((*_blossom_data)[right].status == EVEN) {
     1318        int right_tree = _tree_set->find(right);
     1319        alternatePath(right, right_tree);
     1320        destroyTree(right_tree);
     1321      } else {
     1322        (*_blossom_data)[right].status = MATCHED;
     1323        unmatchedToMatched(right);
     1324      }
    12071325
    12081326      (*_blossom_data)[left].next = _graph.direct(edge, true);
    12091327      (*_blossom_data)[right].next = _graph.direct(edge, false);
    1210     }
    1211 
    1212     void augmentOnArc(const Arc& arc) {
    1213 
    1214       int left = _blossom_set->find(_graph.source(arc));
    1215       int right = _blossom_set->find(_graph.target(arc));
    1216 
    1217       (*_blossom_data)[left].status = MATCHED;
    1218 
    1219       int right_tree = _tree_set->find(right);
    1220       alternatePath(right, right_tree);
    1221       destroyTree(right_tree);
    1222 
    1223       (*_blossom_data)[left].next = arc;
    1224       (*_blossom_data)[right].next = _graph.oppositeArc(arc);
    12251328    }
    12261329
     
    14271530          (*_blossom_data)[sb].pred = pred;
    14281531          (*_blossom_data)[sb].next =
    1429             _graph.oppositeArc((*_blossom_data)[tb].next);
     1532                           _graph.oppositeArc((*_blossom_data)[tb].next);
    14301533
    14311534          pred = (*_blossom_data)[ub].next;
     
    15271630
    15281631      for (int i = 0; i < int(blossoms.size()); ++i) {
    1529         if ((*_blossom_data)[blossoms[i]].next != INVALID) {
     1632        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
    15301633
    15311634          Value offset = (*_blossom_data)[blossoms[i]].offset;
     
    15651668        _delta4_index(0), _delta4(0),
    15661669
    1567         _delta_sum(), _unmatched(0),
    1568 
    1569         _fractional(0)
    1570     {}
     1670        _delta_sum() {}
    15711671
    15721672    ~MaxWeightedMatching() {
    15731673      destroyStructures();
    1574       if (_fractional) {
    1575         delete _fractional;
    1576       }
    15771674    }
    15781675
     
    16021699        (*_delta4_index)[i] = _delta4->PRE_HEAP;
    16031700      }
    1604 
    1605       _unmatched = _node_num;
    16061701
    16071702      int index = 0;
     
    16391734    }
    16401735
    1641     /// \brief Initialize the algorithm with fractional matching
    1642     ///
    1643     /// This function initializes the algorithm with a fractional
    1644     /// matching. This initialization is also called jumpstart heuristic.
    1645     void fractionalInit() {
    1646       createStructures();
    1647      
    1648       if (_fractional == 0) {
    1649         _fractional = new FractionalMatching(_graph, _weight, false);
    1650       }
    1651       _fractional->run();
    1652 
    1653       for (ArcIt e(_graph); e != INVALID; ++e) {
    1654         (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
    1655       }
    1656       for (NodeIt n(_graph); n != INVALID; ++n) {
    1657         (*_delta1_index)[n] = _delta1->PRE_HEAP;
    1658       }
    1659       for (EdgeIt e(_graph); e != INVALID; ++e) {
    1660         (*_delta3_index)[e] = _delta3->PRE_HEAP;
    1661       }
    1662       for (int i = 0; i < _blossom_num; ++i) {
    1663         (*_delta2_index)[i] = _delta2->PRE_HEAP;
    1664         (*_delta4_index)[i] = _delta4->PRE_HEAP;
    1665       }
    1666 
    1667       _unmatched = 0;
    1668 
    1669       int index = 0;
    1670       for (NodeIt n(_graph); n != INVALID; ++n) {
    1671         Value pot = _fractional->nodeValue(n);
    1672         (*_node_index)[n] = index;
    1673         (*_node_data)[index].pot = pot;
    1674         int blossom =
    1675           _blossom_set->insert(n, std::numeric_limits<Value>::max());
    1676 
    1677         (*_blossom_data)[blossom].status = MATCHED;
    1678         (*_blossom_data)[blossom].pred = INVALID;
    1679         (*_blossom_data)[blossom].next = _fractional->matching(n);
    1680         if (_fractional->matching(n) == INVALID) {
    1681           (*_blossom_data)[blossom].base = n;
    1682         }
    1683         (*_blossom_data)[blossom].pot = 0;
    1684         (*_blossom_data)[blossom].offset = 0;
    1685         ++index;
    1686       }
    1687 
    1688       typename Graph::template NodeMap<bool> processed(_graph, false);
    1689       for (NodeIt n(_graph); n != INVALID; ++n) {
    1690         if (processed[n]) continue;
    1691         processed[n] = true;
    1692         if (_fractional->matching(n) == INVALID) continue;
    1693         int num = 1;
    1694         Node v = _graph.target(_fractional->matching(n));
    1695         while (n != v) {
    1696           processed[v] = true;
    1697           v = _graph.target(_fractional->matching(v));
    1698           ++num;
    1699         }
    1700 
    1701         if (num % 2 == 1) {
    1702           std::vector<int> subblossoms(num);
    1703 
    1704           subblossoms[--num] = _blossom_set->find(n);
    1705           _delta1->push(n, _fractional->nodeValue(n));
    1706           v = _graph.target(_fractional->matching(n));
    1707           while (n != v) {
    1708             subblossoms[--num] = _blossom_set->find(v);
    1709             _delta1->push(v, _fractional->nodeValue(v));
    1710             v = _graph.target(_fractional->matching(v));           
    1711           }
    1712          
    1713           int surface =
    1714             _blossom_set->join(subblossoms.begin(), subblossoms.end());
    1715           (*_blossom_data)[surface].status = EVEN;
    1716           (*_blossom_data)[surface].pred = INVALID;
    1717           (*_blossom_data)[surface].next = INVALID;
    1718           (*_blossom_data)[surface].pot = 0;
    1719           (*_blossom_data)[surface].offset = 0;
    1720          
    1721           _tree_set->insert(surface);
    1722           ++_unmatched;
    1723         }
    1724       }
    1725 
    1726       for (EdgeIt e(_graph); e != INVALID; ++e) {
    1727         int si = (*_node_index)[_graph.u(e)];
    1728         int sb = _blossom_set->find(_graph.u(e));
    1729         int ti = (*_node_index)[_graph.v(e)];
    1730         int tb = _blossom_set->find(_graph.v(e));
    1731         if ((*_blossom_data)[sb].status == EVEN &&
    1732             (*_blossom_data)[tb].status == EVEN && sb != tb) {
    1733           _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
    1734                             dualScale * _weight[e]) / 2);
    1735         }
    1736       }
    1737 
    1738       for (NodeIt n(_graph); n != INVALID; ++n) {
    1739         int nb = _blossom_set->find(n);
    1740         if ((*_blossom_data)[nb].status != MATCHED) continue;
    1741         int ni = (*_node_index)[n];
    1742 
    1743         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
    1744           Node v = _graph.target(e);
    1745           int vb = _blossom_set->find(v);
    1746           int vi = (*_node_index)[v];
    1747 
    1748           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
    1749             dualScale * _weight[e];
    1750 
    1751           if ((*_blossom_data)[vb].status == EVEN) {
    1752 
    1753             int vt = _tree_set->find(vb);
    1754 
    1755             typename std::map<int, Arc>::iterator it =
    1756               (*_node_data)[ni].heap_index.find(vt);
    1757 
    1758             if (it != (*_node_data)[ni].heap_index.end()) {
    1759               if ((*_node_data)[ni].heap[it->second] > rw) {
    1760                 (*_node_data)[ni].heap.replace(it->second, e);
    1761                 (*_node_data)[ni].heap.decrease(e, rw);
    1762                 it->second = e;
    1763               }
    1764             } else {
    1765               (*_node_data)[ni].heap.push(e, rw);
    1766               (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
    1767             }
    1768           }
    1769         }
    1770            
    1771         if (!(*_node_data)[ni].heap.empty()) {
    1772           _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
    1773           _delta2->push(nb, _blossom_set->classPrio(nb));
    1774         }
    1775       }
    1776     }
    1777 
    17781736    /// \brief Start the algorithm
    17791737    ///
    17801738    /// This function starts the algorithm.
    17811739    ///
    1782     /// \pre \ref init() or \ref fractionalInit() must be called
    1783     /// before using this function.
     1740    /// \pre \ref init() must be called before using this function.
    17841741    void start() {
    17851742      enum OpType {
     
    17871744      };
    17881745
    1789       while (_unmatched > 0) {
     1746      int unmatched = _node_num;
     1747      while (unmatched > 0) {
    17901748        Value d1 = !_delta1->empty() ?
    17911749          _delta1->prio() : std::numeric_limits<Value>::max();
     
    18001758          _delta4->prio() : std::numeric_limits<Value>::max();
    18011759
    1802         _delta_sum = d3; OpType ot = D3;
    1803         if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
     1760        _delta_sum = d1; OpType ot = D1;
    18041761        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
     1762        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
    18051763        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
     1764
    18061765
    18071766        switch (ot) {
     
    18101769            Node n = _delta1->top();
    18111770            unmatchNode(n);
    1812             --_unmatched;
     1771            --unmatched;
    18131772          }
    18141773          break;
     
    18171776            int blossom = _delta2->top();
    18181777            Node n = _blossom_set->classTop(blossom);
    1819             Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
    1820             if ((*_blossom_data)[blossom].next == INVALID) {
    1821               augmentOnArc(a);
    1822               --_unmatched;
    1823             } else {
    1824               extendOnArc(a);
    1825             }
     1778            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
     1779            extendOnArc(e);
    18261780          }
    18271781          break;
     
    18361790              _delta3->pop();
    18371791            } else {
    1838               int left_tree = _tree_set->find(left_blossom);
    1839               int right_tree = _tree_set->find(right_blossom);
     1792              int left_tree;
     1793              if ((*_blossom_data)[left_blossom].status == EVEN) {
     1794                left_tree = _tree_set->find(left_blossom);
     1795              } else {
     1796                left_tree = -1;
     1797                ++unmatched;
     1798              }
     1799              int right_tree;
     1800              if ((*_blossom_data)[right_blossom].status == EVEN) {
     1801                right_tree = _tree_set->find(right_blossom);
     1802              } else {
     1803                right_tree = -1;
     1804                ++unmatched;
     1805              }
    18401806
    18411807              if (left_tree == right_tree) {
     
    18431809              } else {
    18441810                augmentOnEdge(e);
    1845                 _unmatched -= 2;
     1811                unmatched -= 2;
    18461812              }
    18471813            }
     
    18611827    /// \note mwm.run() is just a shortcut of the following code.
    18621828    /// \code
    1863     ///   mwm.fractionalInit();
     1829    ///   mwm.init();
    18641830    ///   mwm.start();
    18651831    /// \endcode
    18661832    void run() {
    1867       fractionalInit();
     1833      init();
    18681834      start();
    18691835    }
     
    18721838
    18731839    /// \name Primal Solution
    1874     /// Functions to get the primal solution, i.e. the maximum weighted
     1840    /// Functions to get the primal solution, i.e. the maximum weighted 
    18751841    /// matching.\n
    18761842    /// Either \ref run() or \ref start() function should be called before
     
    18911857        }
    18921858      }
    1893       return sum / 2;
     1859      return sum /= 2;
    18941860    }
    18951861
     
    19111877    /// \brief Return \c true if the given edge is in the matching.
    19121878    ///
    1913     /// This function returns \c true if the given edge is in the found
     1879    /// This function returns \c true if the given edge is in the found 
    19141880    /// matching.
    19151881    ///
     
    19221888    ///
    19231889    /// This function returns the matching arc (or edge) incident to the
    1924     /// given node in the found matching or \c INVALID if the node is
     1890    /// given node in the found matching or \c INVALID if the node is 
    19251891    /// not covered by the matching.
    19261892    ///
     
    19401906    /// \brief Return the mate of the given node.
    19411907    ///
    1942     /// This function returns the mate of the given node in the found
     1908    /// This function returns the mate of the given node in the found 
    19431909    /// matching or \c INVALID if the node is not covered by the matching.
    19441910    ///
     
    19601926    /// \brief Return the value of the dual solution.
    19611927    ///
    1962     /// This function returns the value of the dual solution.
    1963     /// It should be equal to the primal value scaled by \ref dualScale
     1928    /// This function returns the value of the dual solution. 
     1929    /// It should be equal to the primal value scaled by \ref dualScale 
    19641930    /// "dual scale".
    19651931    ///
     
    20161982    /// \brief Iterator for obtaining the nodes of a blossom.
    20171983    ///
    2018     /// This class provides an iterator for obtaining the nodes of the
     1984    /// This class provides an iterator for obtaining the nodes of the 
    20191985    /// given blossom. It lists a subset of the nodes.
    2020     /// Before using this iterator, you must allocate a
     1986    /// Before using this iterator, you must allocate a 
    20211987    /// MaxWeightedMatching class and execute it.
    20221988    class BlossomIt {
     
    20271993      /// Constructor to get the nodes of the given variable.
    20281994      ///
    2029       /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
    2030       /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
     1995      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
     1996      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
    20311997      /// called before initializing this iterator.
    20321998      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
     
    20812047  /// \f$O(nm\log n)\f$ time complexity.
    20822048  ///
    2083   /// The maximum weighted perfect matching problem is to find a subset of
    2084   /// the edges in an undirected graph with maximum overall weight for which
     2049  /// The maximum weighted perfect matching problem is to find a subset of 
     2050  /// the edges in an undirected graph with maximum overall weight for which 
    20852051  /// each node has exactly one incident edge.
    20862052  /// It can be formulated with the following linear program.
     
    21052071      \frac{\vert B \vert - 1}{2}z_B\f] */
    21062072  ///
    2107   /// The algorithm can be executed with the run() function.
     2073  /// The algorithm can be executed with the run() function. 
    21082074  /// After it the matching (the primal solution) and the dual solution
    2109   /// can be obtained using the query functions and the
    2110   /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
    2111   /// which is able to iterate on the nodes of a blossom.
     2075  /// can be obtained using the query functions and the 
     2076  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
     2077  /// which is able to iterate on the nodes of a blossom. 
    21122078  /// If the value type is integer, then the dual solution is multiplied
    21132079  /// by \ref MaxWeightedMatching::dualScale "4".
    21142080  ///
    21152081  /// \tparam GR The undirected graph type the algorithm runs on.
    2116   /// \tparam WM The type edge weight map. The default type is
     2082  /// \tparam WM The type edge weight map. The default type is 
    21172083  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
    21182084#ifdef DOXYGEN
     
    22252191
    22262192    Value _delta_sum;
    2227     int _unmatched;
    2228 
    2229     typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
    2230     FractionalMatching;
    2231     FractionalMatching *_fractional;
    22322193
    22332194    void createStructures() {
     
    22732234
    22742235    void destroyStructures() {
     2236      _node_num = countNodes(_graph);
     2237      _blossom_num = _node_num * 3 / 2;
     2238
    22752239      if (_matching) {
    22762240        delete _matching;
     
    29452909        _delta4_index(0), _delta4(0),
    29462910
    2947         _delta_sum(), _unmatched(0),
    2948 
    2949         _fractional(0)
    2950     {}
     2911        _delta_sum() {}
    29512912
    29522913    ~MaxWeightedPerfectMatching() {
    29532914      destroyStructures();
    2954       if (_fractional) {
    2955         delete _fractional;
    2956       }
    29572915    }
    29582916
     
    29792937        (*_delta4_index)[i] = _delta4->PRE_HEAP;
    29802938      }
    2981 
    2982       _unmatched = _node_num;
    29832939
    29842940      int index = 0;
     
    30152971    }
    30162972
    3017     /// \brief Initialize the algorithm with fractional matching
    3018     ///
    3019     /// This function initializes the algorithm with a fractional
    3020     /// matching. This initialization is also called jumpstart heuristic.
    3021     void fractionalInit() {
    3022       createStructures();
    3023      
    3024       if (_fractional == 0) {
    3025         _fractional = new FractionalMatching(_graph, _weight, false);
    3026       }
    3027       if (!_fractional->run()) {
    3028         _unmatched = -1;
    3029         return;
    3030       }
    3031 
    3032       for (ArcIt e(_graph); e != INVALID; ++e) {
    3033         (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
    3034       }
    3035       for (EdgeIt e(_graph); e != INVALID; ++e) {
    3036         (*_delta3_index)[e] = _delta3->PRE_HEAP;
    3037       }
    3038       for (int i = 0; i < _blossom_num; ++i) {
    3039         (*_delta2_index)[i] = _delta2->PRE_HEAP;
    3040         (*_delta4_index)[i] = _delta4->PRE_HEAP;
    3041       }
    3042 
    3043       _unmatched = 0;
    3044 
    3045       int index = 0;
    3046       for (NodeIt n(_graph); n != INVALID; ++n) {
    3047         Value pot = _fractional->nodeValue(n);
    3048         (*_node_index)[n] = index;
    3049         (*_node_data)[index].pot = pot;
    3050         int blossom =
    3051           _blossom_set->insert(n, std::numeric_limits<Value>::max());
    3052 
    3053         (*_blossom_data)[blossom].status = MATCHED;
    3054         (*_blossom_data)[blossom].pred = INVALID;
    3055         (*_blossom_data)[blossom].next = _fractional->matching(n);
    3056         (*_blossom_data)[blossom].pot = 0;
    3057         (*_blossom_data)[blossom].offset = 0;
    3058         ++index;
    3059       }
    3060 
    3061       typename Graph::template NodeMap<bool> processed(_graph, false);
    3062       for (NodeIt n(_graph); n != INVALID; ++n) {
    3063         if (processed[n]) continue;
    3064         processed[n] = true;
    3065         if (_fractional->matching(n) == INVALID) continue;
    3066         int num = 1;
    3067         Node v = _graph.target(_fractional->matching(n));
    3068         while (n != v) {
    3069           processed[v] = true;
    3070           v = _graph.target(_fractional->matching(v));
    3071           ++num;
    3072         }
    3073 
    3074         if (num % 2 == 1) {
    3075           std::vector<int> subblossoms(num);
    3076 
    3077           subblossoms[--num] = _blossom_set->find(n);
    3078           v = _graph.target(_fractional->matching(n));
    3079           while (n != v) {
    3080             subblossoms[--num] = _blossom_set->find(v);
    3081             v = _graph.target(_fractional->matching(v));           
    3082           }
    3083          
    3084           int surface =
    3085             _blossom_set->join(subblossoms.begin(), subblossoms.end());
    3086           (*_blossom_data)[surface].status = EVEN;
    3087           (*_blossom_data)[surface].pred = INVALID;
    3088           (*_blossom_data)[surface].next = INVALID;
    3089           (*_blossom_data)[surface].pot = 0;
    3090           (*_blossom_data)[surface].offset = 0;
    3091          
    3092           _tree_set->insert(surface);
    3093           ++_unmatched;
    3094         }
    3095       }
    3096 
    3097       for (EdgeIt e(_graph); e != INVALID; ++e) {
    3098         int si = (*_node_index)[_graph.u(e)];
    3099         int sb = _blossom_set->find(_graph.u(e));
    3100         int ti = (*_node_index)[_graph.v(e)];
    3101         int tb = _blossom_set->find(_graph.v(e));
    3102         if ((*_blossom_data)[sb].status == EVEN &&
    3103             (*_blossom_data)[tb].status == EVEN && sb != tb) {
    3104           _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
    3105                             dualScale * _weight[e]) / 2);
    3106         }
    3107       }
    3108 
    3109       for (NodeIt n(_graph); n != INVALID; ++n) {
    3110         int nb = _blossom_set->find(n);
    3111         if ((*_blossom_data)[nb].status != MATCHED) continue;
    3112         int ni = (*_node_index)[n];
    3113 
    3114         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
    3115           Node v = _graph.target(e);
    3116           int vb = _blossom_set->find(v);
    3117           int vi = (*_node_index)[v];
    3118 
    3119           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
    3120             dualScale * _weight[e];
    3121 
    3122           if ((*_blossom_data)[vb].status == EVEN) {
    3123 
    3124             int vt = _tree_set->find(vb);
    3125 
    3126             typename std::map<int, Arc>::iterator it =
    3127               (*_node_data)[ni].heap_index.find(vt);
    3128 
    3129             if (it != (*_node_data)[ni].heap_index.end()) {
    3130               if ((*_node_data)[ni].heap[it->second] > rw) {
    3131                 (*_node_data)[ni].heap.replace(it->second, e);
    3132                 (*_node_data)[ni].heap.decrease(e, rw);
    3133                 it->second = e;
    3134               }
    3135             } else {
    3136               (*_node_data)[ni].heap.push(e, rw);
    3137               (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
    3138             }
    3139           }
    3140         }
    3141            
    3142         if (!(*_node_data)[ni].heap.empty()) {
    3143           _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
    3144           _delta2->push(nb, _blossom_set->classPrio(nb));
    3145         }
    3146       }
    3147     }
    3148 
    31492973    /// \brief Start the algorithm
    31502974    ///
    31512975    /// This function starts the algorithm.
    31522976    ///
    3153     /// \pre \ref init() or \ref fractionalInit() must be called before
    3154     /// using this function.
     2977    /// \pre \ref init() must be called before using this function.
    31552978    bool start() {
    31562979      enum OpType {
     
    31582981      };
    31592982
    3160       if (_unmatched == -1) return false;
    3161 
    3162       while (_unmatched > 0) {
     2983      int unmatched = _node_num;
     2984      while (unmatched > 0) {
    31632985        Value d2 = !_delta2->empty() ?
    31642986          _delta2->prio() : std::numeric_limits<Value>::max();
     
    31702992          _delta4->prio() : std::numeric_limits<Value>::max();
    31712993
    3172         _delta_sum = d3; OpType ot = D3;
    3173         if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
     2994        _delta_sum = d2; OpType ot = D2;
     2995        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
    31742996        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
    31752997
     
    32043026              } else {
    32053027                augmentOnEdge(e);
    3206                 _unmatched -= 2;
     3028                unmatched -= 2;
    32073029              }
    32083030            }
     
    32233045    /// \note mwpm.run() is just a shortcut of the following code.
    32243046    /// \code
    3225     ///   mwpm.fractionalInit();
     3047    ///   mwpm.init();
    32263048    ///   mwpm.start();
    32273049    /// \endcode
    32283050    bool run() {
    3229       fractionalInit();
     3051      init();
    32303052      return start();
    32313053    }
     
    32343056
    32353057    /// \name Primal Solution
    3236     /// Functions to get the primal solution, i.e. the maximum weighted
     3058    /// Functions to get the primal solution, i.e. the maximum weighted 
    32373059    /// perfect matching.\n
    32383060    /// Either \ref run() or \ref start() function should be called before
     
    32533075        }
    32543076      }
    3255       return sum / 2;
     3077      return sum /= 2;
    32563078    }
    32573079
    32583080    /// \brief Return \c true if the given edge is in the matching.
    32593081    ///
    3260     /// This function returns \c true if the given edge is in the found
     3082    /// This function returns \c true if the given edge is in the found 
    32613083    /// matching.
    32623084    ///
     
    32693091    ///
    32703092    /// This function returns the matching arc (or edge) incident to the
    3271     /// given node in the found matching or \c INVALID if the node is
     3093    /// given node in the found matching or \c INVALID if the node is 
    32723094    /// not covered by the matching.
    32733095    ///
     
    32873109    /// \brief Return the mate of the given node.
    32883110    ///
    3289     /// This function returns the mate of the given node in the found
     3111    /// This function returns the mate of the given node in the found 
    32903112    /// matching or \c INVALID if the node is not covered by the matching.
    32913113    ///
     
    33063128    /// \brief Return the value of the dual solution.
    33073129    ///
    3308     /// This function returns the value of the dual solution.
    3309     /// It should be equal to the primal value scaled by \ref dualScale
     3130    /// This function returns the value of the dual solution. 
     3131    /// It should be equal to the primal value scaled by \ref dualScale 
    33103132    /// "dual scale".
    33113133    ///
     
    33623184    /// \brief Iterator for obtaining the nodes of a blossom.
    33633185    ///
    3364     /// This class provides an iterator for obtaining the nodes of the
     3186    /// This class provides an iterator for obtaining the nodes of the 
    33653187    /// given blossom. It lists a subset of the nodes.
    3366     /// Before using this iterator, you must allocate a
     3188    /// Before using this iterator, you must allocate a 
    33673189    /// MaxWeightedPerfectMatching class and execute it.
    33683190    class BlossomIt {
     
    33733195      /// Constructor to get the nodes of the given variable.
    33743196      ///
    3375       /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
    3376       /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
     3197      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
     3198      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
    33773199      /// must be called before initializing this iterator.
    33783200      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
     
    34203242} //END OF NAMESPACE LEMON
    34213243
    3422 #endif //LEMON_MATCHING_H
     3244#endif //LEMON_MAX_MATCHING_H
  • test/CMakeLists.txt

    r953 r863  
    2222  error_test
    2323  euler_test
    24   fractional_matching_test
    2524  gomory_hu_test
    2625  graph_copy_test
  • test/Makefile.am

    r953 r863  
    2424        test/error_test \
    2525        test/euler_test \
    26         test/fractional_matching_test \
    2726        test/gomory_hu_test \
    2827        test/graph_copy_test \
     
    7372test_error_test_SOURCES = test/error_test.cc
    7473test_euler_test_SOURCES = test/euler_test.cc
    75 test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
    7674test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
    7775test_graph_copy_test_SOURCES = test/graph_copy_test.cc
  • test/matching_test.cc

    r949 r641  
    402402      edgeMap("weight", weight).run();
    403403
    404     bool perfect;
    405     {
    406       MaxMatching<SmartGraph> mm(graph);
    407       mm.run();
    408       checkMatching(graph, mm);
    409       perfect = 2 * mm.matchingSize() == countNodes(graph);
    410     }
    411 
    412     {
    413       MaxWeightedMatching<SmartGraph> mwm(graph, weight);
    414       mwm.run();
    415       checkWeightedMatching(graph, weight, mwm);
    416     }
    417 
    418     {
    419       MaxWeightedMatching<SmartGraph> mwm(graph, weight);
    420       mwm.init();
    421       mwm.start();
    422       checkWeightedMatching(graph, weight, mwm);
    423     }
    424 
    425     {
    426       MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
    427       bool result = mwpm.run();
    428      
    429       check(result == perfect, "Perfect matching found");
    430       if (perfect) {
    431         checkWeightedPerfectMatching(graph, weight, mwpm);
    432       }
    433     }
    434 
    435     {
    436       MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
    437       mwpm.init();
    438       bool result = mwpm.start();
    439      
    440       check(result == perfect, "Perfect matching found");
    441       if (perfect) {
    442         checkWeightedPerfectMatching(graph, weight, mwpm);
    443       }
     404    MaxMatching<SmartGraph> mm(graph);
     405    mm.run();
     406    checkMatching(graph, mm);
     407
     408    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
     409    mwm.run();
     410    checkWeightedMatching(graph, weight, mwm);
     411
     412    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
     413    bool perfect = mwpm.run();
     414
     415    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
     416          "Perfect matching found");
     417
     418    if (perfect) {
     419      checkWeightedPerfectMatching(graph, weight, mwpm);
    444420    }
    445421  }
Note: See TracChangeset for help on using the changeset viewer.