[Lemon-commits] deba: r3301 - in lemon/trunk: lemon test
Lemon SVN
svn at lemon.cs.elte.hu
Sat Aug 11 18:34:43 CEST 2007
Author: deba
Date: Sat Aug 11 18:34:41 2007
New Revision: 3301
Added:
lemon/trunk/lemon/pr_bipartite_matching.h
- copied, changed from r3300, /lemon/trunk/lemon/bp_matching.h
Removed:
lemon/trunk/lemon/bp_matching.h
Modified:
lemon/trunk/lemon/Makefile.am
lemon/trunk/lemon/bipartite_matching.h
lemon/trunk/test/bipartite_matching_test.cc
Log:
Common interface for bipartite matchings
Some useful query function for push-relabel based matching
The naming should be rethink for these classes
for example: pr-ap prefix for push-relabel and augmenting path
algorithms
Modified: lemon/trunk/lemon/Makefile.am
==============================================================================
--- lemon/trunk/lemon/Makefile.am (original)
+++ lemon/trunk/lemon/Makefile.am Sat Aug 11 18:34:41 2007
@@ -39,7 +39,6 @@
lemon/bfs.h \
lemon/bin_heap.h \
lemon/bipartite_matching.h \
- lemon/bp_matching.h \
lemon/bpugraph_adaptor.h \
lemon/bucket_heap.h \
lemon/capacity_scaling.h \
@@ -103,6 +102,7 @@
lemon/polynomial.h \
lemon/preflow.h \
lemon/prim.h \
+ lemon/pr_bipartite_matching.h \
lemon/radix_heap.h \
lemon/radix_sort.h \
lemon/random.h \
Modified: lemon/trunk/lemon/bipartite_matching.h
==============================================================================
--- lemon/trunk/lemon/bipartite_matching.h (original)
+++ lemon/trunk/lemon/bipartite_matching.h Sat Aug 11 18:34:41 2007
@@ -29,6 +29,9 @@
///\ingroup matching
///\file
///\brief Maximum matching algorithms in bipartite graphs.
+///
+///\note The pr_bipartite_matching.h file also contains algorithms to
+///solve maximum cardinality bipartite matching problems.
namespace lemon {
@@ -39,6 +42,11 @@
/// Bipartite Max Cardinality Matching algorithm. This class implements
/// the Hopcroft-Karp algorithm which has \f$ O(e\sqrt{n}) \f$ time
/// complexity.
+ ///
+ /// \note In several cases the push-relabel based algorithms have
+ /// better runtime performance than the augmenting path based ones.
+ ///
+ /// \see PrBipartiteMatching
template <typename BpUGraph>
class MaxBipartiteMatching {
protected:
@@ -342,10 +350,64 @@
///@{
- /// \brief Returns an minimum covering of the nodes.
+ /// \brief Set true all matching uedge in the map.
+ ///
+ /// Set true all matching uedge in the map. It does not change the
+ /// value mapped to the other uedges.
+ /// \return The number of the matching edges.
+ template <typename MatchingMap>
+ int quickMatching(MatchingMap& mm) const {
+ for (ANodeIt it(*graph); it != INVALID; ++it) {
+ if (anode_matching[it] != INVALID) {
+ mm[anode_matching[it]] = true;
+ }
+ }
+ return matching_size;
+ }
+
+ /// \brief Set true all matching uedge in the map and the others to false.
+ ///
+ /// Set true all matching uedge in the map and the others to false.
+ /// \return The number of the matching edges.
+ template <typename MatchingMap>
+ int matching(MatchingMap& mm) const {
+ for (UEdgeIt it(*graph); it != INVALID; ++it) {
+ mm[it] = it == anode_matching[graph->aNode(it)];
+ }
+ return matching_size;
+ }
+
+
+ /// \brief Return true if the given uedge is in the matching.
+ ///
+ /// It returns true if the given uedge is in the matching.
+ bool matchingEdge(const UEdge& edge) const {
+ return anode_matching[graph->aNode(edge)] == edge;
+ }
+
+ /// \brief Returns the matching edge from the node.
+ ///
+ /// Returns the matching edge from the node. If there is not such
+ /// edge it gives back \c INVALID.
+ UEdge matchingEdge(const Node& node) const {
+ if (graph->aNode(node)) {
+ return anode_matching[node];
+ } else {
+ return bnode_matching[node];
+ }
+ }
+
+ /// \brief Gives back the number of the matching edges.
+ ///
+ /// Gives back the number of the matching edges.
+ int matchingSize() const {
+ return matching_size;
+ }
+
+ /// \brief Returns a minimum covering of the nodes.
///
/// The minimum covering set problem is the dual solution of the
- /// maximum bipartite matching. It provides an solution for this
+ /// maximum bipartite matching. It provides a solution for this
/// problem what is proof of the optimality of the matching.
/// \return The size of the cover set.
template <typename CoverMap>
@@ -397,58 +459,92 @@
return size;
}
- /// \brief Set true all matching uedge in the map.
- ///
- /// Set true all matching uedge in the map. It does not change the
- /// value mapped to the other uedges.
- /// \return The number of the matching edges.
- template <typename MatchingMap>
- int quickMatching(MatchingMap& mm) const {
+ /// \brief Gives back a barrier on the A-nodes
+
+ /// The barrier is s subset of the nodes on the same side of the
+ /// graph, which size minus its neighbours is exactly the
+ /// unmatched nodes on the A-side.
+ /// \retval barrier A WriteMap on the ANodes with bool value.
+ template <typename BarrierMap>
+ void aBarrier(BarrierMap& barrier) const {
+
+ typename Graph::template ANodeMap<bool> areached(*graph, false);
+ typename Graph::template BNodeMap<bool> breached(*graph, false);
+
+ std::vector<Node> queue;
for (ANodeIt it(*graph); it != INVALID; ++it) {
- if (anode_matching[it] != INVALID) {
- mm[anode_matching[it]] = true;
+ if (anode_matching[it] == INVALID) {
+ queue.push_back(it);
}
}
- return matching_size;
- }
- /// \brief Set true all matching uedge in the map and the others to false.
- ///
- /// Set true all matching uedge in the map and the others to false.
- /// \return The number of the matching edges.
- template <typename MatchingMap>
- int matching(MatchingMap& mm) const {
- for (UEdgeIt it(*graph); it != INVALID; ++it) {
- mm[it] = it == anode_matching[graph->aNode(it)];
+ while (!queue.empty()) {
+ std::vector<Node> newqueue;
+ for (int i = 0; i < int(queue.size()); ++i) {
+ Node anode = queue[i];
+ for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
+ Node bnode = graph->bNode(jt);
+ if (breached[bnode]) continue;
+ breached[bnode] = true;
+ if (bnode_matching[bnode] != INVALID) {
+ Node newanode = graph->aNode(bnode_matching[bnode]);
+ if (!areached[newanode]) {
+ areached[newanode] = true;
+ newqueue.push_back(newanode);
+ }
+ }
+ }
+ }
+ queue.swap(newqueue);
+ }
+
+ for (ANodeIt it(*graph); it != INVALID; ++it) {
+ barrier[it] = areached[it] || anode_matching[it] == INVALID;
}
- return matching_size;
}
+ /// \brief Gives back a barrier on the B-nodes
+
+ /// The barrier is s subset of the nodes on the same side of the
+ /// graph, which size minus its neighbours is exactly the
+ /// unmatched nodes on the B-side.
+ /// \retval barrier A WriteMap on the BNodes with bool value.
+ template <typename BarrierMap>
+ void bBarrier(BarrierMap& barrier) const {
- /// \brief Return true if the given uedge is in the matching.
- ///
- /// It returns true if the given uedge is in the matching.
- bool matchingEdge(const UEdge& edge) const {
- return anode_matching[graph->aNode(edge)] == edge;
- }
+ typename Graph::template ANodeMap<bool> areached(*graph, false);
+ typename Graph::template BNodeMap<bool> breached(*graph, false);
+
+ std::vector<Node> queue;
+ for (ANodeIt it(*graph); it != INVALID; ++it) {
+ if (anode_matching[it] == INVALID) {
+ queue.push_back(it);
+ }
+ }
- /// \brief Returns the matching edge from the node.
- ///
- /// Returns the matching edge from the node. If there is not such
- /// edge it gives back \c INVALID.
- UEdge matchingEdge(const Node& node) const {
- if (graph->aNode(node)) {
- return anode_matching[node];
- } else {
- return bnode_matching[node];
+ while (!queue.empty()) {
+ std::vector<Node> newqueue;
+ for (int i = 0; i < int(queue.size()); ++i) {
+ Node anode = queue[i];
+ for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
+ Node bnode = graph->bNode(jt);
+ if (breached[bnode]) continue;
+ breached[bnode] = true;
+ if (bnode_matching[bnode] != INVALID) {
+ Node newanode = graph->aNode(bnode_matching[bnode]);
+ if (!areached[newanode]) {
+ areached[newanode] = true;
+ newqueue.push_back(newanode);
+ }
+ }
+ }
+ }
+ queue.swap(newqueue);
}
- }
- /// \brief Gives back the number of the matching edges.
- ///
- /// Gives back the number of the matching edges.
- int matchingSize() const {
- return matching_size;
+ for (BNodeIt it(*graph); it != INVALID; ++it) {
+ barrier[it] = !breached[it];
+ }
}
/// @}
Copied: lemon/trunk/lemon/pr_bipartite_matching.h (from r3300, /lemon/trunk/lemon/bp_matching.h)
==============================================================================
--- /lemon/trunk/lemon/bp_matching.h (original)
+++ lemon/trunk/lemon/pr_bipartite_matching.h Sat Aug 11 18:34:41 2007
@@ -16,66 +16,86 @@
*
*/
-#ifndef LEMON_BP_MATCHING
-#define LEMON_BP_MATCHING
+#ifndef LEMON_PR_BIPARTITE_MATCHING
+#define LEMON_PR_BIPARTITE_MATCHING
#include <lemon/graph_utils.h>
#include <lemon/iterable_maps.h>
#include <iostream>
#include <queue>
-#include <lemon/counter.h>
#include <lemon/elevator.h>
///\ingroup matching
///\file
///\brief Push-prelabel maximum matching algorithms in bipartite graphs.
///
-///\todo This file slightly conflicts with \ref lemon/bipartite_matching.h
-///\todo (Re)move the XYZ_TYPEDEFS macros
namespace lemon {
-#define BIPARTITE_TYPEDEFS(Graph) \
- GRAPH_TYPEDEFS(Graph) \
- typedef Graph::ANodeIt ANodeIt; \
- typedef Graph::BNodeIt BNodeIt;
-
-#define UNDIRBIPARTITE_TYPEDEFS(Graph) \
- UNDIRGRAPH_TYPEDEFS(Graph) \
- typedef Graph::ANodeIt ANodeIt; \
- typedef Graph::BNodeIt BNodeIt;
-
- template<class Graph,
- class MT=typename Graph::template ANodeMap<typename Graph::UEdge> >
- class BpMatching {
+ ///Max cardinality matching algorithm based on push-relabel principle
+
+ ///\ingroup matching
+ ///Bipartite Max Cardinality Matching algorithm. This class uses the
+ ///push-relabel principle which in several cases has better runtime
+ ///performance than the augmenting path solutions.
+ ///
+ ///\author Alpar Juttner
+ template<class Graph>
+ class PrBipartiteMatching {
typedef typename Graph::Node Node;
typedef typename Graph::ANodeIt ANodeIt;
typedef typename Graph::BNodeIt BNodeIt;
typedef typename Graph::UEdge UEdge;
+ typedef typename Graph::UEdgeIt UEdgeIt;
typedef typename Graph::IncEdgeIt IncEdgeIt;
const Graph &_g;
int _node_num;
- MT &_matching;
+ int _matching_size;
+ int _empty_level;
+
+ typename Graph::template ANodeMap<typename Graph::UEdge> _matching;
Elevator<Graph,typename Graph::BNode> _levels;
typename Graph::template BNodeMap<int> _cov;
public:
- BpMatching(const Graph &g, MT &matching) :
+
+ PrBipartiteMatching(const Graph &g) :
_g(g),
_node_num(countBNodes(g)),
- _matching(matching),
+ _matching(g),
_levels(g,_node_num),
_cov(g,0)
{
}
- private:
- void init()
- {
-// for(BNodeIt n(g);n!=INVALID;++n) cov[n]=0;
+ /// \name Execution control
+ /// The simplest way to execute the algorithm is to use one of the
+ /// member functions called \c run(). \n
+ /// If you need more control on the execution, first
+ /// you must call \ref init() and then one variant of the start()
+ /// member.
+
+ /// @{
+
+ ///Initialize the data structures
+
+ ///This function constructs a prematching first, which is a
+ ///regular matching on the A-side of the graph, but on the B-side
+ ///each node could cover more matching edges. After that, the
+ ///B-nodes which multiple matched, will be pushed into the lowest
+ ///level of the Elevator. The remaning B-nodes will be pushed to
+ ///the consequent levels respect to a Bfs on following graph: the
+ ///nodes are the B-nodes of the original bipartite graph and two
+ ///nodes are adjacent if a node can pass over a matching edge to
+ ///an other node. The source of the Bfs are the lowest level
+ ///nodes. Last, the reached B-nodes without covered matching edge
+ ///becomes active.
+ void init() {
+ _matching_size=0;
+ _empty_level=_node_num;
for(ANodeIt n(_g);n!=INVALID;++n)
if((_matching[n]=IncEdgeIt(_g,n))!=INVALID)
- ++_cov[_g.oppositeNode(n,_matching[n])];
+ ++_cov[_g.bNode(_matching[n])];
std::queue<Node> q;
_levels.initStart();
@@ -109,17 +129,32 @@
if(_cov[n]<1&&_levels[n]<_node_num)
_levels.activate(n);
}
- public:
- int run()
- {
- init();
+ ///Start the main phase of the algorithm
+
+ ///This algorithm calculates the maximum matching with the
+ ///push-relabel principle. This function should be called just
+ ///after the init() function which already set the initial
+ ///prematching, the level function on the B-nodes and the active,
+ ///ie. unmatched B-nodes.
+ ///
+ ///The algorithm always takes highest active B-node, and it try to
+ ///find a B-node which is eligible to pass over one of it's
+ ///matching edge. This condition holds when the B-node is one
+ ///level lower, and the opposite node of it's matching edge is
+ ///adjacent to the highest active node. In this case the current
+ ///node steals the matching edge and becomes inactive. If there is
+ ///not eligible node then the highest active node should be lift
+ ///to the next proper level.
+ ///
+ ///The nodes should not lift higher than the number of the
+ ///B-nodes, if a node reach this level it remains unmatched. If
+ ///during the execution one level becomes empty the nodes above it
+ ///can be deactivated and lift to the highest level.
+ void start() {
Node act;
Node bact=INVALID;
Node last_activated=INVALID;
-// while((act=last_activated!=INVALID?
-// last_activated:_levels.highestActive())
-// !=INVALID)
while((act=_levels.highestActive())!=INVALID) {
last_activated=INVALID;
int actlevel=_levels[act];
@@ -141,7 +176,6 @@
if(nlevel<_node_num) {
if(nlevel>=actlevel)
_levels.liftHighestActiveTo(nlevel+1);
-// _levels.liftTo(act,nlevel+1);
bact=_g.bNode(_matching[_g.aNode(bedge)]);
if(--_cov[bact]<1) {
_levels.activate(bact);
@@ -154,7 +188,6 @@
else {
if(_node_num>actlevel)
_levels.liftHighestActiveTo(_node_num);
-// _levels.liftTo(act,_node_num);
_levels.deactivate(act);
}
@@ -162,23 +195,29 @@
_levels.liftToTop(actlevel);
}
- int ret=_node_num;
+ _matching_size = _node_num;
for(ANodeIt n(_g);n!=INVALID;++n)
- if(_matching[n]==INVALID) ret--;
+ if(_matching[n]==INVALID) _matching_size--;
else if (_cov[_g.bNode(_matching[n])]>1) {
_cov[_g.bNode(_matching[n])]--;
- ret--;
+ _matching_size--;
_matching[n]=INVALID;
}
- return ret;
}
-
- ///\returns -1 if there is a perfect matching, or an empty level
- ///if it doesn't exists
- int runPerfect()
- {
- init();
+ ///Start the algorithm to find a perfect matching
+
+ ///This function is close to identical to the simple start()
+ ///member function but it calculates just perfect matching.
+ ///However, the perfect property is only checked on the B-side of
+ ///the graph
+ ///
+ ///The main difference between the two function is the handling of
+ ///the empty levels. The simple start() function let the nodes
+ ///above the empty levels unmatched while this variant if it find
+ ///an empty level immediately terminates and gives back false
+ ///return value.
+ bool startPerfect() {
Node act;
Node bact=INVALID;
Node last_activated=INVALID;
@@ -219,28 +258,179 @@
}
if(_levels.onLevel(actlevel)==0)
- return actlevel;
+ _empty_level=actlevel;
+ return false;
+ }
+ return true;
+ }
+
+ ///Runs the algorithm
+
+ ///Just a shortcut for the next code:
+ ///\code
+ /// init();
+ /// start();
+ ///\endcode
+ void run() {
+ init();
+ start();
+ }
+
+ ///Runs the algorithm to find a perfect matching
+
+ ///Just a shortcut for the next code:
+ ///\code
+ /// init();
+ /// startPerfect();
+ ///\endcode
+ ///
+ ///\note If the two nodesets of the graph have different size then
+ ///this algorithm checks the perfect property on the B-side.
+ bool runPerfect() {
+ init();
+ return startPerfect();
+ }
+
+ ///Runs the algorithm to find a perfect matching
+
+ ///Just a shortcut for the next code:
+ ///\code
+ /// init();
+ /// startPerfect();
+ ///\endcode
+ ///
+ ///\note It checks that the size of the two nodesets are equal.
+ bool checkedRunPerfect() {
+ if (countANodes(_g) != _node_num) return false;
+ init();
+ return startPerfect();
+ }
+
+ ///@}
+
+ /// \name Query Functions
+ /// The result of the %Matching algorithm can be obtained using these
+ /// functions.\n
+ /// Before the use of these functions,
+ /// either run() or start() must be called.
+ ///@{
+
+ /// \brief Set true all matching uedge in the map.
+ ///
+ /// Set true all matching uedge in the map. It does not change the
+ /// value mapped to the other uedges.
+ /// \return The number of the matching edges.
+ template <typename MatchingMap>
+ int quickMatching(MatchingMap& mm) const {
+ for (ANodeIt n(_g);n!=INVALID;++n) {
+ if (_matching[n]!=INVALID) mm.set(_matching[n],true);
+ }
+ return _matching_size;
+ }
+
+ ///\brief Set true all matching uedge in the map and the others to false.
+
+ ///Set true all matching uedge in the map and the others to false.
+ ///\return The number of the matching edges.
+ template<class MatchingMap>
+ int matching(MatchingMap& mm) const {
+ for (UEdgeIt e(_g);e!=INVALID;++e) {
+ mm.set(e,e==_matching[_g.aNode(e)]);
}
- return -1;
+ return _matching_size;
}
-
- template<class GT>
- void aBarrier(GT &bar,int empty_level=-1)
+
+
+ ///Returns true if the given uedge is in the matching.
+
+ ///It returns true if the given uedge is in the matching.
+ ///
+ bool matchingEdge(const UEdge& e) const {
+ return _matching[_g.aNode(e)]==e;
+ }
+
+ ///Returns the matching edge from the node.
+
+ ///Returns the matching edge from the node. If there is not such
+ ///edge it gives back \c INVALID.
+ ///\note If the parameter node is a B-node then the running time is
+ ///propotional to the degree of the node.
+ UEdge matchingEdge(const Node& n) const {
+ if (_g.aNode(n)) {
+ return _matching[n];
+ } else {
+ for (IncEdgeIt e(_g,n);e!=INVALID;++e)
+ if (e==_matching[_g.aNode(e)]) return e;
+ return INVALID;
+ }
+ }
+
+ ///Gives back the number of the matching edges.
+
+ ///Gives back the number of the matching edges.
+ int matchingSize() const {
+ return _matching_size;
+ }
+
+ ///Gives back a barrier on the A-nodes
+
+ ///The barrier is s subset of the nodes on the same side of the
+ ///graph. If we tried to find a perfect matching and it failed
+ ///then the barrier size will be greater than its neighbours. If
+ ///the maximum matching searched then the barrier size minus its
+ ///neighbours will be exactly the unmatched nodes on the A-side.
+ ///\retval bar A WriteMap on the ANodes with bool value.
+ template<class BarrierMap>
+ void aBarrier(BarrierMap &bar) const
{
- if(empty_level==-1)
- for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
for(ANodeIt n(_g);n!=INVALID;++n)
- bar[n] = _matching[n]==INVALID ||
- _levels[_g.bNode(_matching[n])]<empty_level;
+ bar.set(n,_matching[n]==INVALID ||
+ _levels[_g.bNode(_matching[n])]<_empty_level);
}
- template<class GT>
- void bBarrier(GT &bar, int empty_level=-1)
+
+ ///Gives back a barrier on the B-nodes
+
+ ///The barrier is s subset of the nodes on the same side of the
+ ///graph. If we tried to find a perfect matching and it failed
+ ///then the barrier size will be greater than its neighbours. If
+ ///the maximum matching searched then the barrier size minus its
+ ///neighbours will be exactly the unmatched nodes on the B-side.
+ ///\retval bar A WriteMap on the BNodes with bool value.
+ template<class BarrierMap>
+ void bBarrier(BarrierMap &bar) const
{
- if(empty_level==-1)
- for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
- for(BNodeIt n(_g);n!=INVALID;++n) bar[n]=(_levels[n]>empty_level);
- }
-
+ for(BNodeIt n(_g);n!=INVALID;++n) bar.set(n,_levels[n]>=_empty_level);
+ }
+
+ ///Returns a minimum covering of the nodes.
+
+ ///The minimum covering set problem is the dual solution of the
+ ///maximum bipartite matching. It provides a solution for this
+ ///problem what is proof of the optimality of the matching.
+ ///\param covering NodeMap of bool values, the nodes of the cover
+ ///set will set true while the others false.
+ ///\return The size of the cover set.
+ ///\note This function can be called just after the algorithm have
+ ///already found a matching.
+ template<class CoverMap>
+ int coverSet(CoverMap& covering) const {
+ int ret=0;
+ for(BNodeIt n(_g);n!=INVALID;++n) {
+ if (_levels[n]<_empty_level) { covering.set(n,true); ++ret; }
+ else covering.set(n,false);
+ }
+ for(ANodeIt n(_g);n!=INVALID;++n) {
+ if (_matching[n]!=INVALID &&
+ _levels[_g.bNode(_matching[n])]>=_empty_level)
+ { covering.set(n,true); ++ret; }
+ else covering.set(n,false);
+ }
+ return ret;
+ }
+
+
+ /// @}
+
};
@@ -255,10 +445,10 @@
///\note The the implementation is based
///on the push-relabel principle.
template<class Graph>
- int maxBpMatching(const Graph &g)
+ int prBipartiteMatching(const Graph &g)
{
- typename Graph::template ANodeMap<typename Graph::UEdge> matching(g);
- return maxBpMatching(g,matching);
+ PrBipartiteMatching<Graph> bpm(g);
+ return bpm.matchingSize();
}
///Maximum cardinality matching in a bipartite graph
@@ -267,19 +457,19 @@
///This function finds a maximum cardinality matching
///in a bipartite graph \c g.
///\param g An undirected bipartite graph.
- ///\retval matching A readwrite ANodeMap of value type \c Edge.
- /// The found edges will be returned in this map,
- /// i.e. for an \c ANode \c n,
- /// the edge <tt>matching[n]</tt> is the one that covers the node \c n, or
- /// \ref INVALID if it is uncovered.
+ ///\retval matching A write UEdgeMap of value type \c bool.
+ /// The found edges will be returned in this map.
///\return The cardinality of the maximum matching.
///
///\note The the implementation is based
///on the push-relabel principle.
template<class Graph,class MT>
- int maxBpMatching(const Graph &g,MT &matching)
+ int prBipartiteMatching(const Graph &g,MT &matching)
{
- return BpMatching<Graph,MT>(g,matching).run();
+ PrBipartiteMatching<Graph> bpm(g);
+ bpm.run();
+ bpm.matching(matching);
+ return bpm.matchingSize();
}
///Maximum cardinality matching in a bipartite graph
@@ -288,11 +478,8 @@
///This function finds a maximum cardinality matching
///in a bipartite graph \c g.
///\param g An undirected bipartite graph.
- ///\retval matching A readwrite ANodeMap of value type \c Edge.
- /// The found edges will be returned in this map,
- /// i.e. for an \c ANode \c n,
- /// the edge <tt>matching[n]</tt> is the one that covers the node \c n, or
- /// \ref INVALID if it is uncovered.
+ ///\retval matching A write UEdgeMap of value type \c bool.
+ /// The found edges will be returned in this map.
///\retval barrier A \c bool WriteMap on the BNodes. The map will be set
/// exactly once for each BNode. The nodes with \c true value represent
/// a barrier \e B, i.e. the cardinality of \e B minus the number of its
@@ -303,12 +490,13 @@
///\note The the implementation is based
///on the push-relabel principle.
template<class Graph,class MT, class GT>
- int maxBpMatching(const Graph &g,MT &matching,GT &barrier)
+ int prBipartiteMatching(const Graph &g,MT &matching,GT &barrier)
{
- BpMatching<Graph,MT> bpm(g,matching);
- int ret=bpm.run();
- bpm.barrier(barrier);
- return ret;
+ PrBipartiteMatching<Graph> bpm(g);
+ bpm.run();
+ bpm.matching(matching);
+ bpm.bBarrier(barrier);
+ return bpm.matchingSize();
}
///Perfect matching in a bipartite graph
@@ -322,10 +510,10 @@
///\note The the implementation is based
///on the push-relabel principle.
template<class Graph>
- bool perfectBpMatching(const Graph &g)
+ bool prPerfectBipartiteMatching(const Graph &g)
{
- typename Graph::template ANodeMap<typename Graph::UEdge> matching(g);
- return perfectBpMatching(g,matching);
+ PrBipartiteMatching<Graph> bpm(g);
+ return bpm.runPerfect();
}
///Perfect matching in a bipartite graph
@@ -333,20 +521,21 @@
///\ingroup matching
///This function finds a perfect matching in a bipartite graph \c g.
///\param g An undirected bipartite graph.
- ///\retval matching A readwrite ANodeMap of value type \c Edge.
- /// The found edges will be returned in this map,
- /// i.e. for an \c ANode \c n,
- /// the edge <tt>matching[n]</tt> is the one that covers the node \c n.
- /// The values are unspecified if the graph
+ ///\retval matching A write UEdgeMap of value type \c bool.
+ /// The found edges will be returned in this map.
+ /// The values are unchanged if the graph
/// has no perfect matching.
///\return \c true iff \c g has a perfect matching.
///
///\note The the implementation is based
///on the push-relabel principle.
template<class Graph,class MT>
- bool perfectBpMatching(const Graph &g,MT &matching)
+ bool prPerfectBipartiteMatching(const Graph &g,MT &matching)
{
- return BpMatching<Graph,MT>(g,matching).runPerfect()<0;
+ PrBipartiteMatching<Graph> bpm(g);
+ bool ret = bpm.runPerfect();
+ if (ret) bpm.matching(matching);
+ return ret;
}
///Perfect matching in a bipartite graph
@@ -354,29 +543,29 @@
///\ingroup matching
///This function finds a perfect matching in a bipartite graph \c g.
///\param g An undirected bipartite graph.
- ///\retval matching A readwrite ANodeMap of value type \c Edge.
- /// The found edges will be returned in this map,
- /// i.e. for an \c ANode \c n,
- /// the edge <tt>matching[n]</tt> is the one that covers the node \c n.
- /// The values are unspecified if the graph
+ ///\retval matching A readwrite UEdgeMap of value type \c bool.
+ /// The found edges will be returned in this map.
+ /// The values are unchanged if the graph
/// has no perfect matching.
///\retval barrier A \c bool WriteMap on the BNodes. The map will only
/// be set if \c g has no perfect matching. In this case it is set
/// exactly once for each BNode. The nodes with \c true value represent
/// a barrier, i.e. a subset \e B a of BNodes with the property that
- /// the cardinality of \e B is greater than the numner of its neighbors.
+ /// the cardinality of \e B is greater than the number of its neighbors.
///\return \c true iff \c g has a perfect matching.
///
///\note The the implementation is based
///on the push-relabel principle.
template<class Graph,class MT, class GT>
- int perfectBpMatching(const Graph &g,MT &matching,GT &barrier)
+ int prPerfectBipartiteMatching(const Graph &g,MT &matching,GT &barrier)
{
- BpMatching<Graph,MT> bpm(g,matching);
- int ret=bpm.run();
- if(ret>=0)
- bpm.barrier(barrier,ret);
- return ret<0;
+ PrBipartiteMatching<Graph> bpm(g);
+ bool ret=bpm.runPerfect();
+ if(ret)
+ bpm.matching(matching);
+ else
+ bpm.bBarrier(barrier);
+ return ret;
}
}
Modified: lemon/trunk/test/bipartite_matching_test.cc
==============================================================================
--- lemon/trunk/test/bipartite_matching_test.cc (original)
+++ lemon/trunk/test/bipartite_matching_test.cc Sat Aug 11 18:34:41 2007
@@ -24,6 +24,7 @@
#include <lemon/bpugraph_adaptor.h>
#include <lemon/bipartite_matching.h>
+#include <lemon/pr_bipartite_matching.h>
#include <lemon/graph_utils.h>
@@ -111,6 +112,30 @@
}
{
+ PrBipartiteMatching<Graph> bpmatch(graph);
+
+ bpmatch.run();
+
+ Graph::UEdgeMap<bool> mm(graph);
+ Graph::NodeMap<bool> cs(graph);
+
+ check(bpmatch.coverSet(cs) == bpmatch.matching(mm), "INVALID PRIMAL-DUAL");
+
+ for (UEdgeIt it(graph); it != INVALID; ++it) {
+ check(cs[graph.aNode(it)] || cs[graph.bNode(it)], "INVALID DUAL");
+ }
+
+ for (ANodeIt it(graph); it != INVALID; ++it) {
+ int num = 0;
+ for (IncEdgeIt jt(graph, it); jt != INVALID; ++jt) {
+ if (mm[jt]) ++num;
+ }
+ check(num <= 1, "INVALID PRIMAL");
+ }
+ max_cardinality = bpmatch.matchingSize();
+ }
+
+ {
Graph::UEdgeMap<bool> mm(graph);
check(max_cardinality == maxBipartiteMatching(graph, mm),
More information about the Lemon-commits
mailing list