COIN-OR::LEMON - Graph Library

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/matching.h

    r651 r877  
    33 * This file is a part of LEMON, a generic C++ optimization library.
    44 *
    5  * Copyright (C) 2003-2009
     5 * Copyright (C) 2003-2010
    66 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    77 * (Egervary Research Group on Combinatorial Optimization, EGRES).
     
    1717 */
    1818
    19 #ifndef LEMON_MAX_MATCHING_H
    20 #define LEMON_MAX_MATCHING_H
     19#ifndef LEMON_MATCHING_H
     20#define LEMON_MATCHING_H
    2121
    2222#include <vector>
     
    2929#include <lemon/bin_heap.h>
    3030#include <lemon/maps.h>
     31#include <lemon/fractional_matching.h>
    3132
    3233///\ingroup matching
     
    4243  /// This class implements Edmonds' alternating forest matching algorithm
    4344  /// for finding a maximum cardinality matching in a general undirected graph.
    44   /// It can be started from an arbitrary initial matching 
     45  /// It can be started from an arbitrary initial matching
    4546  /// (the default is the empty one).
    4647  ///
     
    7071    ///\brief Status constants for Gallai-Edmonds decomposition.
    7172    ///
    72     ///These constants are used for indicating the Gallai-Edmonds 
     73    ///These constants are used for indicating the Gallai-Edmonds
    7374    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
    7475    ///induce a subgraph with factor-critical components, the nodes with
    7576    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
    76     ///with status \c MATCHED (or \c C) induce a subgraph having a 
     77    ///with status \c MATCHED (or \c C) induce a subgraph having a
    7778    ///perfect matching.
    7879    enum Status {
     
    513514    }
    514515
    515     /// \brief Start Edmonds' algorithm with a heuristic improvement 
     516    /// \brief Start Edmonds' algorithm with a heuristic improvement
    516517    /// for dense graphs
    517518    ///
     
    535536    /// \brief Run Edmonds' algorithm
    536537    ///
    537     /// This function runs Edmonds' algorithm. An additional heuristic of 
    538     /// postponing shrinks is used for relatively dense graphs 
     538    /// This function runs Edmonds' algorithm. An additional heuristic of
     539    /// postponing shrinks is used for relatively dense graphs
    539540    /// (for which <tt>m>=2*n</tt> holds).
    540541    void run() {
     
    557558    /// \brief Return the size (cardinality) of the matching.
    558559    ///
    559     /// This function returns the size (cardinality) of the current matching. 
     560    /// This function returns the size (cardinality) of the current matching.
    560561    /// After run() it returns the size of the maximum matching in the graph.
    561562    int matchingSize() const {
     
    571572    /// \brief Return \c true if the given edge is in the matching.
    572573    ///
    573     /// This function returns \c true if the given edge is in the current 
     574    /// This function returns \c true if the given edge is in the current
    574575    /// matching.
    575576    bool matching(const Edge& edge) const {
     
    580581    ///
    581582    /// This function returns the matching arc (or edge) incident to the
    582     /// given node in the current matching or \c INVALID if the node is 
     583    /// given node in the current matching or \c INVALID if the node is
    583584    /// not covered by the matching.
    584585    Arc matching(const Node& n) const {
     
    596597    /// \brief Return the mate of the given node.
    597598    ///
    598     /// This function returns the mate of the given node in the current 
     599    /// This function returns the mate of the given node in the current
    599600    /// matching or \c INVALID if the node is not covered by the matching.
    600601    Node mate(const Node& n) const {
     
    606607
    607608    /// \name Dual Solution
    608     /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
     609    /// Functions to get the dual solution, i.e. the Gallai-Edmonds
    609610    /// decomposition.
    610611
     
    649650  /// \f$O(nm\log n)\f$ time complexity.
    650651  ///
    651   /// The maximum weighted matching problem is to find a subset of the 
    652   /// edges in an undirected graph with maximum overall weight for which 
     652  /// The maximum weighted matching problem is to find a subset of the
     653  /// edges in an undirected graph with maximum overall weight for which
    653654  /// each node has at most one incident edge.
    654655  /// It can be formulated with the following linear program.
     
    674675      \frac{\vert B \vert - 1}{2}z_B\f] */
    675676  ///
    676   /// The algorithm can be executed with the run() function. 
     677  /// The algorithm can be executed with the run() function.
    677678  /// After it the matching (the primal solution) and the dual solution
    678   /// can be obtained using the query functions and the 
    679   /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
    680   /// which is able to iterate on the nodes of a blossom. 
     679  /// can be obtained using the query functions and the
     680  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
     681  /// which is able to iterate on the nodes of a blossom.
    681682  /// If the value type is integer, then the dual solution is multiplied
    682683  /// by \ref MaxWeightedMatching::dualScale "4".
    683684  ///
    684685  /// \tparam GR The undirected graph type the algorithm runs on.
    685   /// \tparam WM The type edge weight map. The default type is 
     686  /// \tparam WM The type edge weight map. The default type is
    686687  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
    687688#ifdef DOXYGEN
     
    746747
    747748    enum Status {
    748       EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
     749      EVEN = -1, MATCHED = 0, ODD = 1
    749750    };
    750751
     
    798799
    799800    Value _delta_sum;
     801    int _unmatched;
     802
     803    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
     804    FractionalMatching *_fractional;
    800805
    801806    void createStructures() {
     
    806811        _matching = new MatchingMap(_graph);
    807812      }
     813
    808814      if (!_node_potential) {
    809815        _node_potential = new NodePotential(_graph);
    810816      }
     817
    811818      if (!_blossom_set) {
    812819        _blossom_index = new IntNodeMap(_graph);
    813820        _blossom_set = new BlossomSet(*_blossom_index);
    814821        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
     822      } else if (_blossom_data->size() != _blossom_num) {
     823        delete _blossom_data;
     824        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
    815825      }
    816826
     
    819829        _node_heap_index = new IntArcMap(_graph);
    820830        _node_data = new RangeMap<NodeData>(_node_num,
    821                                               NodeData(*_node_heap_index));
     831                                            NodeData(*_node_heap_index));
     832      } else {
     833        delete _node_data;
     834        _node_data = new RangeMap<NodeData>(_node_num,
     835                                            NodeData(*_node_heap_index));
    822836      }
    823837
     
    825839        _tree_set_index = new IntIntMap(_blossom_num);
    826840        _tree_set = new TreeSet(*_tree_set_index);
    827       }
     841      } else {
     842        _tree_set_index->resize(_blossom_num);
     843      }
     844
    828845      if (!_delta1) {
    829846        _delta1_index = new IntNodeMap(_graph);
    830847        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
    831848      }
     849
    832850      if (!_delta2) {
    833851        _delta2_index = new IntIntMap(_blossom_num);
    834852        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
    835       }
     853      } else {
     854        _delta2_index->resize(_blossom_num);
     855      }
     856
    836857      if (!_delta3) {
    837858        _delta3_index = new IntEdgeMap(_graph);
    838859        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
    839860      }
     861
    840862      if (!_delta4) {
    841863        _delta4_index = new IntIntMap(_blossom_num);
    842864        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
     865      } else {
     866        _delta4_index->resize(_blossom_num);
    843867      }
    844868    }
    845869
    846870    void destroyStructures() {
    847       _node_num = countNodes(_graph);
    848       _blossom_num = _node_num * 3 / 2;
    849 
    850871      if (_matching) {
    851872        delete _matching;
     
    922943            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
    923944              _delta3->push(e, rw / 2);
    924             }
    925           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
    926             if (_delta3->state(e) != _delta3->IN_HEAP) {
    927               _delta3->push(e, rw);
    928945            }
    929946          } else {
     
    950967                               (*_blossom_data)[vb].offset);
    951968                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
    952                            (*_blossom_data)[vb].offset){
     969                           (*_blossom_data)[vb].offset) {
    953970                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
    954971                                   (*_blossom_data)[vb].offset);
     
    969986      if (!_blossom_set->trivial(blossom)) {
    970987        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
    971                      (*_blossom_data)[blossom].offset);
     988                      (*_blossom_data)[blossom].offset);
    972989      }
    973990    }
     
    10361053                }
    10371054              }
    1038             }
    1039 
    1040           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
    1041             if (_delta3->state(e) == _delta3->IN_HEAP) {
    1042               _delta3->erase(e);
    10431055            }
    10441056          } else {
     
    10781090          std::numeric_limits<Value>::max()) {
    10791091        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
    1080                        (*_blossom_data)[blossom].offset);
     1092                      (*_blossom_data)[blossom].offset);
    10811093      }
    10821094
     
    11171129            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
    11181130              _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);
    11231131            }
    11241132          } else {
     
    11581166    }
    11591167
    1160 
    1161     void matchedToUnmatched(int blossom) {
    1162       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
    1163         _delta2->erase(blossom);
    1164       }
    1165 
    1166       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
    1167            n != INVALID; ++n) {
    1168         int ni = (*_node_index)[n];
    1169 
    1170         _blossom_set->increase(n, std::numeric_limits<Value>::max());
    1171 
    1172         (*_node_data)[ni].heap.clear();
    1173         (*_node_data)[ni].heap_index.clear();
    1174 
    1175         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
    1176           Node v = _graph.target(e);
    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];
    1196 
    1197         for (InArcIt e(_graph, n); e != INVALID; ++e) {
    1198           Node v = _graph.source(e);
    1199           int vb = _blossom_set->find(v);
    1200           int vi = (*_node_index)[v];
    1201 
    1202           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
    1203             dualScale * _weight[e];
    1204 
    1205           if (vb == blossom) {
    1206             if (_delta3->state(e) == _delta3->IN_HEAP) {
    1207               _delta3->erase(e);
    1208             }
    1209           } else if ((*_blossom_data)[vb].status == EVEN) {
    1210 
    1211             if (_delta3->state(e) == _delta3->IN_HEAP) {
    1212               _delta3->erase(e);
    1213             }
    1214 
    1215             int vt = _tree_set->find(vb);
    1216 
    1217             Arc r = _graph.oppositeArc(e);
    1218 
    1219             typename std::map<int, Arc>::iterator it =
    1220               (*_node_data)[ni].heap_index.find(vt);
    1221 
    1222             if (it != (*_node_data)[ni].heap_index.end()) {
    1223               if ((*_node_data)[ni].heap[it->second] > rw) {
    1224                 (*_node_data)[ni].heap.replace(it->second, r);
    1225                 (*_node_data)[ni].heap.decrease(r, rw);
    1226                 it->second = r;
    1227               }
    1228             } else {
    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);
    1243               }
    1244             }
    1245 
    1246           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
    1247             if (_delta3->state(e) == _delta3->IN_HEAP) {
    1248               _delta3->erase(e);
    1249             }
    1250           }
    1251         }
    1252       }
    1253     }
    1254 
    12551168    void alternatePath(int even, int tree) {
    12561169      int odd;
     
    12951208      destroyTree(tree);
    12961209
    1297       (*_blossom_data)[blossom].status = UNMATCHED;
    12981210      (*_blossom_data)[blossom].base = node;
    1299       matchedToUnmatched(blossom);
    1300     }
    1301 
     1211      (*_blossom_data)[blossom].next = INVALID;
     1212    }
    13021213
    13031214    void augmentOnEdge(const Edge& edge) {
     
    13061217      int right = _blossom_set->find(_graph.v(edge));
    13071218
    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       }
     1219      int left_tree = _tree_set->find(left);
     1220      alternatePath(left, left_tree);
     1221      destroyTree(left_tree);
     1222
     1223      int right_tree = _tree_set->find(right);
     1224      alternatePath(right, right_tree);
     1225      destroyTree(right_tree);
    13251226
    13261227      (*_blossom_data)[left].next = _graph.direct(edge, true);
    13271228      (*_blossom_data)[right].next = _graph.direct(edge, false);
     1229    }
     1230
     1231    void augmentOnArc(const Arc& arc) {
     1232
     1233      int left = _blossom_set->find(_graph.source(arc));
     1234      int right = _blossom_set->find(_graph.target(arc));
     1235
     1236      (*_blossom_data)[left].status = MATCHED;
     1237
     1238      int right_tree = _tree_set->find(right);
     1239      alternatePath(right, right_tree);
     1240      destroyTree(right_tree);
     1241
     1242      (*_blossom_data)[left].next = arc;
     1243      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
    13281244    }
    13291245
     
    15301446          (*_blossom_data)[sb].pred = pred;
    15311447          (*_blossom_data)[sb].next =
    1532                            _graph.oppositeArc((*_blossom_data)[tb].next);
     1448            _graph.oppositeArc((*_blossom_data)[tb].next);
    15331449
    15341450          pred = (*_blossom_data)[ub].next;
     
    16301546
    16311547      for (int i = 0; i < int(blossoms.size()); ++i) {
    1632         if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
     1548        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
    16331549
    16341550          Value offset = (*_blossom_data)[blossoms[i]].offset;
     
    16681584        _delta4_index(0), _delta4(0),
    16691585
    1670         _delta_sum() {}
     1586        _delta_sum(), _unmatched(0),
     1587
     1588        _fractional(0)
     1589    {}
    16711590
    16721591    ~MaxWeightedMatching() {
    16731592      destroyStructures();
     1593      if (_fractional) {
     1594        delete _fractional;
     1595      }
    16741596    }
    16751597
     
    16861608      createStructures();
    16871609
     1610      _blossom_node_list.clear();
     1611      _blossom_potential.clear();
     1612
    16881613      for (ArcIt e(_graph); e != INVALID; ++e) {
    16891614        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
     
    16991624        (*_delta4_index)[i] = _delta4->PRE_HEAP;
    17001625      }
     1626
     1627      _unmatched = _node_num;
     1628
     1629      _delta1->clear();
     1630      _delta2->clear();
     1631      _delta3->clear();
     1632      _delta4->clear();
     1633      _blossom_set->clear();
     1634      _tree_set->clear();
    17011635
    17021636      int index = 0;
     
    17101644        }
    17111645        (*_node_index)[n] = index;
     1646        (*_node_data)[index].heap_index.clear();
     1647        (*_node_data)[index].heap.clear();
    17121648        (*_node_data)[index].pot = max;
    17131649        _delta1->push(n, max);
     
    17341670    }
    17351671
     1672    /// \brief Initialize the algorithm with fractional matching
     1673    ///
     1674    /// This function initializes the algorithm with a fractional
     1675    /// matching. This initialization is also called jumpstart heuristic.
     1676    void fractionalInit() {
     1677      createStructures();
     1678
     1679      _blossom_node_list.clear();
     1680      _blossom_potential.clear();
     1681
     1682      if (_fractional == 0) {
     1683        _fractional = new FractionalMatching(_graph, _weight, false);
     1684      }
     1685      _fractional->run();
     1686
     1687      for (ArcIt e(_graph); e != INVALID; ++e) {
     1688        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
     1689      }
     1690      for (NodeIt n(_graph); n != INVALID; ++n) {
     1691        (*_delta1_index)[n] = _delta1->PRE_HEAP;
     1692      }
     1693      for (EdgeIt e(_graph); e != INVALID; ++e) {
     1694        (*_delta3_index)[e] = _delta3->PRE_HEAP;
     1695      }
     1696      for (int i = 0; i < _blossom_num; ++i) {
     1697        (*_delta2_index)[i] = _delta2->PRE_HEAP;
     1698        (*_delta4_index)[i] = _delta4->PRE_HEAP;
     1699      }
     1700
     1701      _unmatched = 0;
     1702
     1703      _delta1->clear();
     1704      _delta2->clear();
     1705      _delta3->clear();
     1706      _delta4->clear();
     1707      _blossom_set->clear();
     1708      _tree_set->clear();
     1709
     1710      int index = 0;
     1711      for (NodeIt n(_graph); n != INVALID; ++n) {
     1712        Value pot = _fractional->nodeValue(n);
     1713        (*_node_index)[n] = index;
     1714        (*_node_data)[index].pot = pot;
     1715        (*_node_data)[index].heap_index.clear();
     1716        (*_node_data)[index].heap.clear();
     1717        int blossom =
     1718          _blossom_set->insert(n, std::numeric_limits<Value>::max());
     1719
     1720        (*_blossom_data)[blossom].status = MATCHED;
     1721        (*_blossom_data)[blossom].pred = INVALID;
     1722        (*_blossom_data)[blossom].next = _fractional->matching(n);
     1723        if (_fractional->matching(n) == INVALID) {
     1724          (*_blossom_data)[blossom].base = n;
     1725        }
     1726        (*_blossom_data)[blossom].pot = 0;
     1727        (*_blossom_data)[blossom].offset = 0;
     1728        ++index;
     1729      }
     1730
     1731      typename Graph::template NodeMap<bool> processed(_graph, false);
     1732      for (NodeIt n(_graph); n != INVALID; ++n) {
     1733        if (processed[n]) continue;
     1734        processed[n] = true;
     1735        if (_fractional->matching(n) == INVALID) continue;
     1736        int num = 1;
     1737        Node v = _graph.target(_fractional->matching(n));
     1738        while (n != v) {
     1739          processed[v] = true;
     1740          v = _graph.target(_fractional->matching(v));
     1741          ++num;
     1742        }
     1743
     1744        if (num % 2 == 1) {
     1745          std::vector<int> subblossoms(num);
     1746
     1747          subblossoms[--num] = _blossom_set->find(n);
     1748          _delta1->push(n, _fractional->nodeValue(n));
     1749          v = _graph.target(_fractional->matching(n));
     1750          while (n != v) {
     1751            subblossoms[--num] = _blossom_set->find(v);
     1752            _delta1->push(v, _fractional->nodeValue(v));
     1753            v = _graph.target(_fractional->matching(v));
     1754          }
     1755
     1756          int surface =
     1757            _blossom_set->join(subblossoms.begin(), subblossoms.end());
     1758          (*_blossom_data)[surface].status = EVEN;
     1759          (*_blossom_data)[surface].pred = INVALID;
     1760          (*_blossom_data)[surface].next = INVALID;
     1761          (*_blossom_data)[surface].pot = 0;
     1762          (*_blossom_data)[surface].offset = 0;
     1763
     1764          _tree_set->insert(surface);
     1765          ++_unmatched;
     1766        }
     1767      }
     1768
     1769      for (EdgeIt e(_graph); e != INVALID; ++e) {
     1770        int si = (*_node_index)[_graph.u(e)];
     1771        int sb = _blossom_set->find(_graph.u(e));
     1772        int ti = (*_node_index)[_graph.v(e)];
     1773        int tb = _blossom_set->find(_graph.v(e));
     1774        if ((*_blossom_data)[sb].status == EVEN &&
     1775            (*_blossom_data)[tb].status == EVEN && sb != tb) {
     1776          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
     1777                            dualScale * _weight[e]) / 2);
     1778        }
     1779      }
     1780
     1781      for (NodeIt n(_graph); n != INVALID; ++n) {
     1782        int nb = _blossom_set->find(n);
     1783        if ((*_blossom_data)[nb].status != MATCHED) continue;
     1784        int ni = (*_node_index)[n];
     1785
     1786        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
     1787          Node v = _graph.target(e);
     1788          int vb = _blossom_set->find(v);
     1789          int vi = (*_node_index)[v];
     1790
     1791          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
     1792            dualScale * _weight[e];
     1793
     1794          if ((*_blossom_data)[vb].status == EVEN) {
     1795
     1796            int vt = _tree_set->find(vb);
     1797
     1798            typename std::map<int, Arc>::iterator it =
     1799              (*_node_data)[ni].heap_index.find(vt);
     1800
     1801            if (it != (*_node_data)[ni].heap_index.end()) {
     1802              if ((*_node_data)[ni].heap[it->second] > rw) {
     1803                (*_node_data)[ni].heap.replace(it->second, e);
     1804                (*_node_data)[ni].heap.decrease(e, rw);
     1805                it->second = e;
     1806              }
     1807            } else {
     1808              (*_node_data)[ni].heap.push(e, rw);
     1809              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
     1810            }
     1811          }
     1812        }
     1813
     1814        if (!(*_node_data)[ni].heap.empty()) {
     1815          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
     1816          _delta2->push(nb, _blossom_set->classPrio(nb));
     1817        }
     1818      }
     1819    }
     1820
    17361821    /// \brief Start the algorithm
    17371822    ///
    17381823    /// This function starts the algorithm.
    17391824    ///
    1740     /// \pre \ref init() must be called before using this function.
     1825    /// \pre \ref init() or \ref fractionalInit() must be called
     1826    /// before using this function.
    17411827    void start() {
    17421828      enum OpType {
     
    17441830      };
    17451831
    1746       int unmatched = _node_num;
    1747       while (unmatched > 0) {
     1832      while (_unmatched > 0) {
    17481833        Value d1 = !_delta1->empty() ?
    17491834          _delta1->prio() : std::numeric_limits<Value>::max();
     
    17581843          _delta4->prio() : std::numeric_limits<Value>::max();
    17591844
    1760         _delta_sum = d1; OpType ot = D1;
     1845        _delta_sum = d3; OpType ot = D3;
     1846        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
    17611847        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
    1762         if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
    17631848        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
    1764 
    17651849
    17661850        switch (ot) {
     
    17691853            Node n = _delta1->top();
    17701854            unmatchNode(n);
    1771             --unmatched;
     1855            --_unmatched;
    17721856          }
    17731857          break;
     
    17761860            int blossom = _delta2->top();
    17771861            Node n = _blossom_set->classTop(blossom);
    1778             Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
    1779             extendOnArc(e);
     1862            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
     1863            if ((*_blossom_data)[blossom].next == INVALID) {
     1864              augmentOnArc(a);
     1865              --_unmatched;
     1866            } else {
     1867              extendOnArc(a);
     1868            }
    17801869          }
    17811870          break;
     
    17901879              _delta3->pop();
    17911880            } else {
    1792               int left_tree;
    1793               if ((*_blossom_data)[left_blossom].status == EVEN) {
    1794                 left_tree = _tree_set->find(left_blossom);
    1795               } else {
    1796                 left_tree = -1;
    1797                 ++unmatched;
    1798               }
    1799               int right_tree;
    1800               if ((*_blossom_data)[right_blossom].status == EVEN) {
    1801                 right_tree = _tree_set->find(right_blossom);
    1802               } else {
    1803                 right_tree = -1;
    1804                 ++unmatched;
    1805               }
     1881              int left_tree = _tree_set->find(left_blossom);
     1882              int right_tree = _tree_set->find(right_blossom);
    18061883
    18071884              if (left_tree == right_tree) {
     
    18091886              } else {
    18101887                augmentOnEdge(e);
    1811                 unmatched -= 2;
     1888                _unmatched -= 2;
    18121889              }
    18131890            }
     
    18271904    /// \note mwm.run() is just a shortcut of the following code.
    18281905    /// \code
    1829     ///   mwm.init();
     1906    ///   mwm.fractionalInit();
    18301907    ///   mwm.start();
    18311908    /// \endcode
    18321909    void run() {
    1833       init();
     1910      fractionalInit();
    18341911      start();
    18351912    }
     
    18381915
    18391916    /// \name Primal Solution
    1840     /// Functions to get the primal solution, i.e. the maximum weighted 
     1917    /// Functions to get the primal solution, i.e. the maximum weighted
    18411918    /// matching.\n
    18421919    /// Either \ref run() or \ref start() function should be called before
     
    18571934        }
    18581935      }
    1859       return sum /= 2;
     1936      return sum / 2;
    18601937    }
    18611938
     
    18771954    /// \brief Return \c true if the given edge is in the matching.
    18781955    ///
    1879     /// This function returns \c true if the given edge is in the found 
     1956    /// This function returns \c true if the given edge is in the found
    18801957    /// matching.
    18811958    ///
     
    18881965    ///
    18891966    /// This function returns the matching arc (or edge) incident to the
    1890     /// given node in the found matching or \c INVALID if the node is 
     1967    /// given node in the found matching or \c INVALID if the node is
    18911968    /// not covered by the matching.
    18921969    ///
     
    19061983    /// \brief Return the mate of the given node.
    19071984    ///
    1908     /// This function returns the mate of the given node in the found 
     1985    /// This function returns the mate of the given node in the found
    19091986    /// matching or \c INVALID if the node is not covered by the matching.
    19101987    ///
     
    19262003    /// \brief Return the value of the dual solution.
    19272004    ///
    1928     /// This function returns the value of the dual solution. 
    1929     /// It should be equal to the primal value scaled by \ref dualScale 
     2005    /// This function returns the value of the dual solution.
     2006    /// It should be equal to the primal value scaled by \ref dualScale
    19302007    /// "dual scale".
    19312008    ///
     
    19822059    /// \brief Iterator for obtaining the nodes of a blossom.
    19832060    ///
    1984     /// This class provides an iterator for obtaining the nodes of the 
     2061    /// This class provides an iterator for obtaining the nodes of the
    19852062    /// given blossom. It lists a subset of the nodes.
    1986     /// Before using this iterator, you must allocate a 
     2063    /// Before using this iterator, you must allocate a
    19872064    /// MaxWeightedMatching class and execute it.
    19882065    class BlossomIt {
     
    19932070      /// Constructor to get the nodes of the given variable.
    19942071      ///
    1995       /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
    1996       /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
     2072      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
     2073      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
    19972074      /// called before initializing this iterator.
    19982075      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
     
    20472124  /// \f$O(nm\log n)\f$ time complexity.
    20482125  ///
    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 
     2126  /// The maximum weighted perfect matching problem is to find a subset of
     2127  /// the edges in an undirected graph with maximum overall weight for which
    20512128  /// each node has exactly one incident edge.
    20522129  /// It can be formulated with the following linear program.
     
    20712148      \frac{\vert B \vert - 1}{2}z_B\f] */
    20722149  ///
    2073   /// The algorithm can be executed with the run() function. 
     2150  /// The algorithm can be executed with the run() function.
    20742151  /// After it the matching (the primal solution) and the dual solution
    2075   /// can be obtained using the query functions and the 
    2076   /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
    2077   /// which is able to iterate on the nodes of a blossom. 
     2152  /// can be obtained using the query functions and the
     2153  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
     2154  /// which is able to iterate on the nodes of a blossom.
    20782155  /// If the value type is integer, then the dual solution is multiplied
    20792156  /// by \ref MaxWeightedMatching::dualScale "4".
    20802157  ///
    20812158  /// \tparam GR The undirected graph type the algorithm runs on.
    2082   /// \tparam WM The type edge weight map. The default type is 
     2159  /// \tparam WM The type edge weight map. The default type is
    20832160  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
    20842161#ifdef DOXYGEN
     
    21912268
    21922269    Value _delta_sum;
     2270    int _unmatched;
     2271
     2272    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
     2273    FractionalMatching;
     2274    FractionalMatching *_fractional;
    21932275
    21942276    void createStructures() {
     
    21992281        _matching = new MatchingMap(_graph);
    22002282      }
     2283
    22012284      if (!_node_potential) {
    22022285        _node_potential = new NodePotential(_graph);
    22032286      }
     2287
    22042288      if (!_blossom_set) {
    22052289        _blossom_index = new IntNodeMap(_graph);
    22062290        _blossom_set = new BlossomSet(*_blossom_index);
     2291        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
     2292      } else if (_blossom_data->size() != _blossom_num) {
     2293        delete _blossom_data;
    22072294        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
    22082295      }
     
    22132300        _node_data = new RangeMap<NodeData>(_node_num,
    22142301                                            NodeData(*_node_heap_index));
     2302      } else if (_node_data->size() != _node_num) {
     2303        delete _node_data;
     2304        _node_data = new RangeMap<NodeData>(_node_num,
     2305                                            NodeData(*_node_heap_index));
    22152306      }
    22162307
     
    22182309        _tree_set_index = new IntIntMap(_blossom_num);
    22192310        _tree_set = new TreeSet(*_tree_set_index);
    2220       }
     2311      } else {
     2312        _tree_set_index->resize(_blossom_num);
     2313      }
     2314
    22212315      if (!_delta2) {
    22222316        _delta2_index = new IntIntMap(_blossom_num);
    22232317        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
    2224       }
     2318      } else {
     2319        _delta2_index->resize(_blossom_num);
     2320      }
     2321
    22252322      if (!_delta3) {
    22262323        _delta3_index = new IntEdgeMap(_graph);
    22272324        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
    22282325      }
     2326
    22292327      if (!_delta4) {
    22302328        _delta4_index = new IntIntMap(_blossom_num);
    22312329        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
     2330      } else {
     2331        _delta4_index->resize(_blossom_num);
    22322332      }
    22332333    }
    22342334
    22352335    void destroyStructures() {
    2236       _node_num = countNodes(_graph);
    2237       _blossom_num = _node_num * 3 / 2;
    2238 
    22392336      if (_matching) {
    22402337        delete _matching;
     
    29093006        _delta4_index(0), _delta4(0),
    29103007
    2911         _delta_sum() {}
     3008        _delta_sum(), _unmatched(0),
     3009
     3010        _fractional(0)
     3011    {}
    29123012
    29133013    ~MaxWeightedPerfectMatching() {
    29143014      destroyStructures();
     3015      if (_fractional) {
     3016        delete _fractional;
     3017      }
    29153018    }
    29163019
     
    29273030      createStructures();
    29283031
     3032      _blossom_node_list.clear();
     3033      _blossom_potential.clear();
     3034
    29293035      for (ArcIt e(_graph); e != INVALID; ++e) {
    29303036        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
     
    29373043        (*_delta4_index)[i] = _delta4->PRE_HEAP;
    29383044      }
     3045
     3046      _unmatched = _node_num;
     3047
     3048      _delta2->clear();
     3049      _delta3->clear();
     3050      _delta4->clear();
     3051      _blossom_set->clear();
     3052      _tree_set->clear();
    29393053
    29403054      int index = 0;
     
    29483062        }
    29493063        (*_node_index)[n] = index;
     3064        (*_node_data)[index].heap_index.clear();
     3065        (*_node_data)[index].heap.clear();
    29503066        (*_node_data)[index].pot = max;
    29513067        int blossom =
     
    29713087    }
    29723088
     3089    /// \brief Initialize the algorithm with fractional matching
     3090    ///
     3091    /// This function initializes the algorithm with a fractional
     3092    /// matching. This initialization is also called jumpstart heuristic.
     3093    void fractionalInit() {
     3094      createStructures();
     3095
     3096      _blossom_node_list.clear();
     3097      _blossom_potential.clear();
     3098
     3099      if (_fractional == 0) {
     3100        _fractional = new FractionalMatching(_graph, _weight, false);
     3101      }
     3102      if (!_fractional->run()) {
     3103        _unmatched = -1;
     3104        return;
     3105      }
     3106
     3107      for (ArcIt e(_graph); e != INVALID; ++e) {
     3108        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
     3109      }
     3110      for (EdgeIt e(_graph); e != INVALID; ++e) {
     3111        (*_delta3_index)[e] = _delta3->PRE_HEAP;
     3112      }
     3113      for (int i = 0; i < _blossom_num; ++i) {
     3114        (*_delta2_index)[i] = _delta2->PRE_HEAP;
     3115        (*_delta4_index)[i] = _delta4->PRE_HEAP;
     3116      }
     3117
     3118      _unmatched = 0;
     3119
     3120      _delta2->clear();
     3121      _delta3->clear();
     3122      _delta4->clear();
     3123      _blossom_set->clear();
     3124      _tree_set->clear();
     3125
     3126      int index = 0;
     3127      for (NodeIt n(_graph); n != INVALID; ++n) {
     3128        Value pot = _fractional->nodeValue(n);
     3129        (*_node_index)[n] = index;
     3130        (*_node_data)[index].pot = pot;
     3131        (*_node_data)[index].heap_index.clear();
     3132        (*_node_data)[index].heap.clear();
     3133        int blossom =
     3134          _blossom_set->insert(n, std::numeric_limits<Value>::max());
     3135
     3136        (*_blossom_data)[blossom].status = MATCHED;
     3137        (*_blossom_data)[blossom].pred = INVALID;
     3138        (*_blossom_data)[blossom].next = _fractional->matching(n);
     3139        (*_blossom_data)[blossom].pot = 0;
     3140        (*_blossom_data)[blossom].offset = 0;
     3141        ++index;
     3142      }
     3143
     3144      typename Graph::template NodeMap<bool> processed(_graph, false);
     3145      for (NodeIt n(_graph); n != INVALID; ++n) {
     3146        if (processed[n]) continue;
     3147        processed[n] = true;
     3148        if (_fractional->matching(n) == INVALID) continue;
     3149        int num = 1;
     3150        Node v = _graph.target(_fractional->matching(n));
     3151        while (n != v) {
     3152          processed[v] = true;
     3153          v = _graph.target(_fractional->matching(v));
     3154          ++num;
     3155        }
     3156
     3157        if (num % 2 == 1) {
     3158          std::vector<int> subblossoms(num);
     3159
     3160          subblossoms[--num] = _blossom_set->find(n);
     3161          v = _graph.target(_fractional->matching(n));
     3162          while (n != v) {
     3163            subblossoms[--num] = _blossom_set->find(v);
     3164            v = _graph.target(_fractional->matching(v));
     3165          }
     3166
     3167          int surface =
     3168            _blossom_set->join(subblossoms.begin(), subblossoms.end());
     3169          (*_blossom_data)[surface].status = EVEN;
     3170          (*_blossom_data)[surface].pred = INVALID;
     3171          (*_blossom_data)[surface].next = INVALID;
     3172          (*_blossom_data)[surface].pot = 0;
     3173          (*_blossom_data)[surface].offset = 0;
     3174
     3175          _tree_set->insert(surface);
     3176          ++_unmatched;
     3177        }
     3178      }
     3179
     3180      for (EdgeIt e(_graph); e != INVALID; ++e) {
     3181        int si = (*_node_index)[_graph.u(e)];
     3182        int sb = _blossom_set->find(_graph.u(e));
     3183        int ti = (*_node_index)[_graph.v(e)];
     3184        int tb = _blossom_set->find(_graph.v(e));
     3185        if ((*_blossom_data)[sb].status == EVEN &&
     3186            (*_blossom_data)[tb].status == EVEN && sb != tb) {
     3187          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
     3188                            dualScale * _weight[e]) / 2);
     3189        }
     3190      }
     3191
     3192      for (NodeIt n(_graph); n != INVALID; ++n) {
     3193        int nb = _blossom_set->find(n);
     3194        if ((*_blossom_data)[nb].status != MATCHED) continue;
     3195        int ni = (*_node_index)[n];
     3196
     3197        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
     3198          Node v = _graph.target(e);
     3199          int vb = _blossom_set->find(v);
     3200          int vi = (*_node_index)[v];
     3201
     3202          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
     3203            dualScale * _weight[e];
     3204
     3205          if ((*_blossom_data)[vb].status == EVEN) {
     3206
     3207            int vt = _tree_set->find(vb);
     3208
     3209            typename std::map<int, Arc>::iterator it =
     3210              (*_node_data)[ni].heap_index.find(vt);
     3211
     3212            if (it != (*_node_data)[ni].heap_index.end()) {
     3213              if ((*_node_data)[ni].heap[it->second] > rw) {
     3214                (*_node_data)[ni].heap.replace(it->second, e);
     3215                (*_node_data)[ni].heap.decrease(e, rw);
     3216                it->second = e;
     3217              }
     3218            } else {
     3219              (*_node_data)[ni].heap.push(e, rw);
     3220              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
     3221            }
     3222          }
     3223        }
     3224
     3225        if (!(*_node_data)[ni].heap.empty()) {
     3226          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
     3227          _delta2->push(nb, _blossom_set->classPrio(nb));
     3228        }
     3229      }
     3230    }
     3231
    29733232    /// \brief Start the algorithm
    29743233    ///
    29753234    /// This function starts the algorithm.
    29763235    ///
    2977     /// \pre \ref init() must be called before using this function.
     3236    /// \pre \ref init() or \ref fractionalInit() must be called before
     3237    /// using this function.
    29783238    bool start() {
    29793239      enum OpType {
     
    29813241      };
    29823242
    2983       int unmatched = _node_num;
    2984       while (unmatched > 0) {
     3243      if (_unmatched == -1) return false;
     3244
     3245      while (_unmatched > 0) {
    29853246        Value d2 = !_delta2->empty() ?
    29863247          _delta2->prio() : std::numeric_limits<Value>::max();
     
    29923253          _delta4->prio() : std::numeric_limits<Value>::max();
    29933254
    2994         _delta_sum = d2; OpType ot = D2;
    2995         if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
     3255        _delta_sum = d3; OpType ot = D3;
     3256        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
    29963257        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
    29973258
     
    30263287              } else {
    30273288                augmentOnEdge(e);
    3028                 unmatched -= 2;
     3289                _unmatched -= 2;
    30293290              }
    30303291            }
     
    30453306    /// \note mwpm.run() is just a shortcut of the following code.
    30463307    /// \code
    3047     ///   mwpm.init();
     3308    ///   mwpm.fractionalInit();
    30483309    ///   mwpm.start();
    30493310    /// \endcode
    30503311    bool run() {
    3051       init();
     3312      fractionalInit();
    30523313      return start();
    30533314    }
     
    30563317
    30573318    /// \name Primal Solution
    3058     /// Functions to get the primal solution, i.e. the maximum weighted 
     3319    /// Functions to get the primal solution, i.e. the maximum weighted
    30593320    /// perfect matching.\n
    30603321    /// Either \ref run() or \ref start() function should be called before
     
    30753336        }
    30763337      }
    3077       return sum /= 2;
     3338      return sum / 2;
    30783339    }
    30793340
    30803341    /// \brief Return \c true if the given edge is in the matching.
    30813342    ///
    3082     /// This function returns \c true if the given edge is in the found 
     3343    /// This function returns \c true if the given edge is in the found
    30833344    /// matching.
    30843345    ///
     
    30913352    ///
    30923353    /// This function returns the matching arc (or edge) incident to the
    3093     /// given node in the found matching or \c INVALID if the node is 
     3354    /// given node in the found matching or \c INVALID if the node is
    30943355    /// not covered by the matching.
    30953356    ///
     
    31093370    /// \brief Return the mate of the given node.
    31103371    ///
    3111     /// This function returns the mate of the given node in the found 
     3372    /// This function returns the mate of the given node in the found
    31123373    /// matching or \c INVALID if the node is not covered by the matching.
    31133374    ///
     
    31283389    /// \brief Return the value of the dual solution.
    31293390    ///
    3130     /// This function returns the value of the dual solution. 
    3131     /// It should be equal to the primal value scaled by \ref dualScale 
     3391    /// This function returns the value of the dual solution.
     3392    /// It should be equal to the primal value scaled by \ref dualScale
    31323393    /// "dual scale".
    31333394    ///
     
    31843445    /// \brief Iterator for obtaining the nodes of a blossom.
    31853446    ///
    3186     /// This class provides an iterator for obtaining the nodes of the 
     3447    /// This class provides an iterator for obtaining the nodes of the
    31873448    /// given blossom. It lists a subset of the nodes.
    3188     /// Before using this iterator, you must allocate a 
     3449    /// Before using this iterator, you must allocate a
    31893450    /// MaxWeightedPerfectMatching class and execute it.
    31903451    class BlossomIt {
     
    31953456      /// Constructor to get the nodes of the given variable.
    31963457      ///
    3197       /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
    3198       /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
     3458      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
     3459      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
    31993460      /// must be called before initializing this iterator.
    32003461      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
     
    32423503} //END OF NAMESPACE LEMON
    32433504
    3244 #endif //LEMON_MAX_MATCHING_H
     3505#endif //LEMON_MATCHING_H
Note: See TracChangeset for help on using the changeset viewer.