[Lemon-commits] Peter Kovacs: Imporvements for the matching algo...
Lemon HG
hg at lemon.cs.elte.hu
Sat Apr 18 09:55:40 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/b61354458b59
changeset: 622:b61354458b59
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Wed Apr 15 12:01:14 2009 +0200
description:
Imporvements for the matching algorithms (#264)
diffstat:
doc/groups.dox | 5 +-
lemon/max_matching.h | 470 ++++++++++++++++++++++++++++------------------
test/max_matching_test.cc | 106 ++++++++++-
3 files changed, 393 insertions(+), 188 deletions(-)
diffs (truncated from 1059 to 300 lines):
diff --git a/doc/groups.dox b/doc/groups.dox
--- a/doc/groups.dox
+++ b/doc/groups.dox
@@ -435,9 +435,10 @@
@ingroup algs
\brief Algorithms for finding matchings in graphs and bipartite graphs.
-This group contains algorithm objects and functions to calculate
+This group contains the algorithms for calculating
matchings in graphs and bipartite graphs. The general matching problem is
-finding a subset of the arcs which does not shares common endpoints.
+finding a subset of the edges for which each node has at most one incident
+edge.
There are several different algorithms for calculate matchings in
graphs. The matching problems in bipartite graphs are generally
diff --git a/lemon/max_matching.h b/lemon/max_matching.h
--- a/lemon/max_matching.h
+++ b/lemon/max_matching.h
@@ -37,42 +37,51 @@
/// \ingroup matching
///
- /// \brief Edmonds' alternating forest maximum matching algorithm.
+ /// \brief Maximum cardinality matching in general graphs
///
- /// This class implements Edmonds' alternating forest matching
- /// algorithm. The algorithm can be started from an arbitrary initial
- /// matching (the default is the empty one)
+ /// This class implements Edmonds' alternating forest matching algorithm
+ /// for finding a maximum cardinality matching in a general graph.
+ /// It can be started from an arbitrary initial matching
+ /// (the default is the empty one).
///
/// The dual solution of the problem is a map of the nodes to
- /// MaxMatching::Status, having values \c EVEN/D, \c ODD/A and \c
- /// MATCHED/C showing the Gallai-Edmonds decomposition of the
- /// graph. The nodes in \c EVEN/D induce a graph with
- /// factor-critical components, the nodes in \c ODD/A form the
- /// barrier, and the nodes in \c MATCHED/C induce a graph having a
- /// perfect matching. The number of the factor-critical components
+ /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
+ /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
+ /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
+ /// with factor-critical components, the nodes in \c ODD/A form the
+ /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
+ /// a perfect matching. The number of the factor-critical components
/// minus the number of barrier nodes is a lower bound on the
/// unmatched nodes, and the matching is optimal if and only if this bound is
- /// tight. This decomposition can be attained by calling \c
+ /// tight. This decomposition can be obtained by calling \c
/// decomposition() after running the algorithm.
///
- /// \param GR The graph type the algorithm runs on.
+ /// \tparam GR The graph type the algorithm runs on.
template <typename GR>
class MaxMatching {
public:
+ /// The graph type of the algorithm
typedef GR Graph;
typedef typename Graph::template NodeMap<typename Graph::Arc>
MatchingMap;
- ///\brief Indicates the Gallai-Edmonds decomposition of the graph.
+ ///\brief Status constants for Gallai-Edmonds decomposition.
///
- ///Indicates the Gallai-Edmonds decomposition of the graph. The
- ///nodes with Status \c EVEN/D induce a graph with factor-critical
- ///components, the nodes in \c ODD/A form the canonical barrier,
- ///and the nodes in \c MATCHED/C induce a graph having a perfect
- ///matching.
+ ///These constants are used for indicating the Gallai-Edmonds
+ ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
+ ///induce a subgraph with factor-critical components, the nodes with
+ ///status \c ODD (or \c A) form the canonical barrier, and the nodes
+ ///with status \c MATCHED (or \c C) induce a subgraph having a
+ ///perfect matching.
enum Status {
- EVEN = 1, D = 1, MATCHED = 0, C = 0, ODD = -1, A = -1, UNMATCHED = -2
+ EVEN = 1, ///< = 1. (\c D is an alias for \c EVEN.)
+ D = 1,
+ MATCHED = 0, ///< = 0. (\c C is an alias for \c MATCHED.)
+ C = 0,
+ ODD = -1, ///< = -1. (\c A is an alias for \c ODD.)
+ A = -1,
+ UNMATCHED = -2 ///< = -2.
};
typedef typename Graph::template NodeMap<Status> StatusMap;
@@ -338,8 +347,6 @@
(*_blossom_rep)[_blossom_set->find(nca)] = nca;
}
-
-
void extendOnArc(const Arc& a) {
Node base = _graph.source(a);
Node odd = _graph.target(a);
@@ -408,22 +415,19 @@
destroyStructures();
}
- /// \name Execution control
+ /// \name Execution Control
/// The simplest way to execute the algorithm is to use the
- /// \c run() member function.
- /// \n
-
- /// If you need better control on the execution, you must call
- /// \ref init(), \ref greedyInit() or \ref matchingInit()
- /// functions first, then you can start the algorithm with the \ref
- /// startSparse() or startDense() functions.
+ /// \c run() member function.\n
+ /// If you need better control on the execution, you have to call
+ /// one of the functions \ref init(), \ref greedyInit() or
+ /// \ref matchingInit() first, then you can start the algorithm with
+ /// \ref startSparse() or \ref startDense().
///@{
- /// \brief Sets the actual matching to the empty matching.
+ /// \brief Set the initial matching to the empty matching.
///
- /// Sets the actual matching to the empty matching.
- ///
+ /// This function sets the initial matching to the empty matching.
void init() {
createStructures();
for(NodeIt n(_graph); n != INVALID; ++n) {
@@ -432,9 +436,9 @@
}
}
- ///\brief Finds an initial matching in a greedy way
+ /// \brief Find an initial matching in a greedy way.
///
- ///It finds an initial matching in a greedy way.
+ /// This function finds an initial matching in a greedy way.
void greedyInit() {
createStructures();
for (NodeIt n(_graph); n != INVALID; ++n) {
@@ -458,11 +462,11 @@
}
- /// \brief Initialize the matching from a map containing.
+ /// \brief Initialize the matching from a map.
///
- /// Initialize the matching from a \c bool valued \c Edge map. This
- /// map must have the property that there are no two incident edges
- /// with true value, ie. it contains a matching.
+ /// This function initializes the matching from a \c bool valued edge
+ /// map. This map should have the property that there are no two incident
+ /// edges with \c true value, i.e. it really contains a matching.
/// \return \c true if the map contains a matching.
template <typename MatchingMap>
bool matchingInit(const MatchingMap& matching) {
@@ -489,9 +493,12 @@
return true;
}
- /// \brief Starts Edmonds' algorithm
+ /// \brief Start Edmonds' algorithm
///
- /// If runs the original Edmonds' algorithm.
+ /// This function runs the original Edmonds' algorithm.
+ ///
+ /// \pre \ref Init(), \ref greedyInit() or \ref matchingInit() must be
+ /// called before using this function.
void startSparse() {
for(NodeIt n(_graph); n != INVALID; ++n) {
if ((*_status)[n] == UNMATCHED) {
@@ -503,10 +510,14 @@
}
}
- /// \brief Starts Edmonds' algorithm.
+ /// \brief Start Edmonds' algorithm with a heuristic improvement
+ /// for dense graphs
///
- /// It runs Edmonds' algorithm with a heuristic of postponing
+ /// This function runs Edmonds' algorithm with a heuristic of postponing
/// shrinks, therefore resulting in a faster algorithm for dense graphs.
+ ///
+ /// \pre \ref Init(), \ref greedyInit() or \ref matchingInit() must be
+ /// called before using this function.
void startDense() {
for(NodeIt n(_graph); n != INVALID; ++n) {
if ((*_status)[n] == UNMATCHED) {
@@ -519,11 +530,11 @@
}
- /// \brief Runs Edmonds' algorithm
+ /// \brief Run Edmonds' algorithm
///
- /// Runs Edmonds' algorithm for sparse graphs (<tt>m<2*n</tt>)
- /// or Edmonds' algorithm with a heuristic of
- /// postponing shrinks for dense graphs.
+ /// This function runs Edmonds' algorithm. An additional heuristic of
+ /// postponing shrinks is used for relatively dense graphs
+ /// (for which <tt>m>=2*n</tt> holds).
void run() {
if (countEdges(_graph) < 2 * countNodes(_graph)) {
greedyInit();
@@ -536,15 +547,15 @@
/// @}
- /// \name Primal solution
- /// Functions to get the primal solution, ie. the matching.
+ /// \name Primal Solution
+ /// Functions to get the primal solution, i.e. the maximum matching.
/// @{
- ///\brief Returns the size of the current matching.
+ /// \brief Return the size (cardinality) of the matching.
///
- ///Returns the size of the current matching. After \ref
- ///run() it returns the size of the maximum matching in the graph.
+ /// This function returns the size (cardinality) of the current matching.
+ /// After run() it returns the size of the maximum matching in the graph.
int matchingSize() const {
int size = 0;
for (NodeIt n(_graph); n != INVALID; ++n) {
@@ -555,25 +566,27 @@
return size / 2;
}
- /// \brief Returns true when the edge is in the matching.
+ /// \brief Return \c true if the given edge is in the matching.
///
- /// Returns true when the edge is in the matching.
+ /// This function returns \c true if the given edge is in the current
+ /// matching.
bool matching(const Edge& edge) const {
return edge == (*_matching)[_graph.u(edge)];
}
- /// \brief Returns the matching edge incident to the given node.
+ /// \brief Return the matching arc (or edge) incident to the given node.
///
- /// Returns the matching edge of a \c node in the actual matching or
- /// INVALID if the \c node is not covered by the actual matching.
+ /// This function returns the matching arc (or edge) incident to the
+ /// given node in the current matching or \c INVALID if the node is
+ /// not covered by the matching.
Arc matching(const Node& n) const {
return (*_matching)[n];
}
- ///\brief Returns the mate of a node in the actual matching.
+ /// \brief Return the mate of the given node.
///
- ///Returns the mate of a \c node in the actual matching or
- ///INVALID if the \c node is not covered by the actual matching.
+ /// This function returns the mate of the given node in the current
+ /// matching or \c INVALID if the node is not covered by the matching.
Node mate(const Node& n) const {
return (*_matching)[n] != INVALID ?
_graph.target((*_matching)[n]) : INVALID;
@@ -581,23 +594,24 @@
/// @}
- /// \name Dual solution
- /// Functions to get the dual solution, ie. the decomposition.
+ /// \name Dual Solution
+ /// Functions to get the dual solution, i.e. the Gallai-Edmonds
+ /// decomposition.
/// @{
- /// \brief Returns the class of the node in the Edmonds-Gallai
+ /// \brief Return the status of the given node in the Edmonds-Gallai
/// decomposition.
///
- /// Returns the class of the node in the Edmonds-Gallai
- /// decomposition.
+ /// This function returns the \ref Status "status" of the given node
+ /// in the Edmonds-Gallai decomposition.
Status decomposition(const Node& n) const {
return (*_status)[n];
}
- /// \brief Returns true when the node is in the barrier.
+ /// \brief Return \c true if the given node is in the barrier.
///
- /// Returns true when the node is in the barrier.
+ /// This function returns \c true if the given node is in the barrier.
bool barrier(const Node& n) const {
return (*_status)[n] == ODD;
}
@@ -615,10 +629,10 @@
/// on extensive use of priority queues and provides
/// \f$O(nm\log n)\f$ time complexity.
///
- /// The maximum weighted matching problem is to find undirected
More information about the Lemon-commits
mailing list