[Lemon-commits] deba: r3305 - lemon/trunk/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Tue Aug 28 15:58:55 CEST 2007
Author: deba
Date: Tue Aug 28 15:58:54 2007
New Revision: 3305
Modified:
lemon/trunk/lemon/bipartite_matching.h
lemon/trunk/lemon/pr_bipartite_matching.h
Log:
Redesign of augmenting path based matching
Small bug fix in the push-relabel based
Modified: lemon/trunk/lemon/bipartite_matching.h
==============================================================================
--- lemon/trunk/lemon/bipartite_matching.h (original)
+++ lemon/trunk/lemon/bipartite_matching.h Tue Aug 28 15:58:54 2007
@@ -69,8 +69,8 @@
/// \brief Constructor.
///
/// Constructor of the algorithm.
- MaxBipartiteMatching(const BpUGraph& _graph)
- : anode_matching(_graph), bnode_matching(_graph), graph(&_graph) {}
+ MaxBipartiteMatching(const BpUGraph& graph)
+ : _matching(graph), _rmatching(graph), _reached(graph), _graph(&graph) {}
/// \name Execution control
/// The simplest way to execute the algorithm is to use
@@ -87,13 +87,15 @@
///
/// It initalizes the data structures and creates an empty matching.
void init() {
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- anode_matching[it] = INVALID;
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ _matching.set(it, INVALID);
}
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- bnode_matching[it] = INVALID;
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ _rmatching.set(it, INVALID);
+ _reached.set(it, -1);
}
- matching_size = 0;
+ _size = 0;
+ _phase = -1;
}
/// \brief Initalize the data structures.
@@ -102,21 +104,24 @@
/// matching. From this matching sometimes it is faster to get
/// the matching than from the initial empty matching.
void greedyInit() {
- matching_size = 0;
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- bnode_matching[it] = INVALID;
- }
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- anode_matching[it] = INVALID;
- for (IncEdgeIt jt(*graph, it); jt != INVALID; ++jt) {
- if (bnode_matching[graph->bNode(jt)] == INVALID) {
- anode_matching[it] = jt;
- bnode_matching[graph->bNode(jt)] = jt;
- ++matching_size;
+ _size = 0;
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ _rmatching.set(it, INVALID);
+ _reached.set(it, 0);
+ }
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ _matching[it] = INVALID;
+ for (IncEdgeIt jt(*_graph, it); jt != INVALID; ++jt) {
+ if (_rmatching[_graph->bNode(jt)] == INVALID) {
+ _matching.set(it, jt);
+ _rmatching.set(_graph->bNode(jt), jt);
+ _reached.set(it, -1);
+ ++_size;
break;
}
}
}
+ _phase = 0;
}
/// \brief Initalize the data structures with an initial matching.
@@ -124,20 +129,23 @@
/// It initalizes the data structures with an initial matching.
template <typename MatchingMap>
void matchingInit(const MatchingMap& mm) {
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- anode_matching[it] = INVALID;
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ _matching.set(it, INVALID);
}
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- bnode_matching[it] = INVALID;
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ _rmatching.set(it, INVALID);
+ _reached.set(it, 0);
}
- matching_size = 0;
- for (UEdgeIt it(*graph); it != INVALID; ++it) {
+ _size = 0;
+ for (UEdgeIt it(*_graph); it != INVALID; ++it) {
if (mm[it]) {
- ++matching_size;
- anode_matching[graph->aNode(it)] = it;
- bnode_matching[graph->bNode(it)] = it;
+ ++_size;
+ _matching.set(_graph->aNode(it), it);
+ _rmatching.set(_graph->bNode(it), it);
+ _reached.set(it, 0);
}
}
+ _phase = 0;
}
/// \brief Initalize the data structures with an initial matching.
@@ -145,185 +153,188 @@
/// It initalizes the data structures with an initial matching.
/// \return %True when the given map contains really a matching.
template <typename MatchingMap>
- void checkedMatchingInit(const MatchingMap& mm) {
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- anode_matching[it] = INVALID;
- }
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- bnode_matching[it] = INVALID;
+ bool checkedMatchingInit(const MatchingMap& mm) {
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ _matching.set(it, INVALID);
+ }
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ _rmatching.set(it, INVALID);
+ _reached.set(it, 0);
}
- matching_size = 0;
- for (UEdgeIt it(*graph); it != INVALID; ++it) {
+ _size = 0;
+ for (UEdgeIt it(*_graph); it != INVALID; ++it) {
if (mm[it]) {
- ++matching_size;
- if (anode_matching[graph->aNode(it)] != INVALID) {
+ ++_size;
+ if (_matching[_graph->aNode(it)] != INVALID) {
return false;
}
- anode_matching[graph->aNode(it)] = it;
- if (bnode_matching[graph->aNode(it)] != INVALID) {
+ _matching.set(_graph->aNode(it), it);
+ if (_matching[_graph->bNode(it)] != INVALID) {
return false;
}
- bnode_matching[graph->bNode(it)] = it;
+ _matching.set(_graph->bNode(it), it);
+ _reached.set(_graph->bNode(it), -1);
}
}
+ _phase = 0;
+ return true;
+ }
+
+ private:
+
+ bool _find_path(Node anode, int maxlevel,
+ typename Graph::template BNodeMap<int>& level) {
+ for (IncEdgeIt it(*_graph, anode); it != INVALID; ++it) {
+ Node bnode = _graph->bNode(it);
+ if (level[bnode] == maxlevel) {
+ level.set(bnode, -1);
+ if (maxlevel == 0) {
+ _matching.set(anode, it);
+ _rmatching.set(bnode, it);
+ return true;
+ } else {
+ Node nnode = _graph->aNode(_rmatching[bnode]);
+ if (_find_path(nnode, maxlevel - 1, level)) {
+ _matching.set(anode, it);
+ _rmatching.set(bnode, it);
+ return true;
+ }
+ }
+ }
+ }
return false;
}
+ public:
+
/// \brief An augmenting phase of the Hopcroft-Karp algorithm
///
/// It runs an augmenting phase of the Hopcroft-Karp
- /// algorithm. This phase finds maximum count of edge disjoint
- /// augmenting paths and augments on these paths. The algorithm
- /// consists at most of \f$ O(\sqrt{n}) \f$ phase and one phase is
- /// \f$ O(e) \f$ long.
+ /// algorithm. This phase finds maximal edge disjoint augmenting
+ /// paths and augments on these paths. The algorithm consists at
+ /// most of \f$ O(\sqrt{n}) \f$ phase and one phase is \f$ O(e)
+ /// \f$ long.
bool augment() {
- typename Graph::template ANodeMap<bool> areached(*graph, false);
- typename Graph::template BNodeMap<bool> breached(*graph, false);
-
- typename Graph::template BNodeMap<UEdge> bpred(*graph, INVALID);
+ ++_phase;
+
+ typename Graph::template BNodeMap<int> _level(*_graph, -1);
+ typename Graph::template ANodeMap<bool> _found(*_graph, false);
- std::vector<Node> queue, bqueue;
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- if (anode_matching[it] == INVALID) {
+ std::vector<Node> queue, aqueue;
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ if (_rmatching[it] == INVALID) {
queue.push_back(it);
- areached[it] = true;
+ _reached.set(it, _phase);
+ _level.set(it, 0);
}
}
bool success = false;
+ int level = 0;
while (!success && !queue.empty()) {
- std::vector<Node> newqueue;
+ std::vector<Node> nqueue;
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;
- bpred[bnode] = jt;
- if (bnode_matching[bnode] == INVALID) {
- bqueue.push_back(bnode);
+ Node bnode = queue[i];
+ for (IncEdgeIt jt(*_graph, bnode); jt != INVALID; ++jt) {
+ Node anode = _graph->aNode(jt);
+ if (_matching[anode] == INVALID) {
+
+ if (!_found[anode]) {
+ if (_find_path(anode, level, _level)) {
+ ++_size;
+ }
+ _found.set(anode, true);
+ }
success = true;
} else {
- Node newanode = graph->aNode(bnode_matching[bnode]);
- if (!areached[newanode]) {
- areached[newanode] = true;
- newqueue.push_back(newanode);
+ Node nnode = _graph->bNode(_matching[anode]);
+ if (_reached[nnode] != _phase) {
+ _reached.set(nnode, _phase);
+ nqueue.push_back(nnode);
+ _level.set(nnode, level + 1);
}
}
}
}
- queue.swap(newqueue);
+ ++level;
+ queue.swap(nqueue);
}
+
+ return success;
+ }
+ private:
+
+ void _find_path_bfs(Node anode,
+ typename Graph::template ANodeMap<UEdge>& pred) {
+ while (true) {
+ UEdge uedge = pred[anode];
+ Node bnode = _graph->bNode(uedge);
- if (success) {
-
- typename Graph::template ANodeMap<bool> aused(*graph, false);
-
- for (int i = 0; i < int(bqueue.size()); ++i) {
- Node bnode = bqueue[i];
-
- bool used = false;
-
- while (bnode != INVALID) {
- UEdge uedge = bpred[bnode];
- Node anode = graph->aNode(uedge);
-
- if (aused[anode]) {
- used = true;
- break;
- }
-
- bnode = anode_matching[anode] != INVALID ?
- graph->bNode(anode_matching[anode]) : INVALID;
-
- }
-
- if (used) continue;
-
- bnode = bqueue[i];
- while (bnode != INVALID) {
- UEdge uedge = bpred[bnode];
- Node anode = graph->aNode(uedge);
-
- bnode_matching[bnode] = uedge;
-
- bnode = anode_matching[anode] != INVALID ?
- graph->bNode(anode_matching[anode]) : INVALID;
-
- anode_matching[anode] = uedge;
+ UEdge nedge = _rmatching[bnode];
- aused[anode] = true;
- }
- ++matching_size;
+ _matching.set(anode, uedge);
+ _rmatching.set(bnode, uedge);
- }
+ if (nedge == INVALID) break;
+ anode = _graph->aNode(nedge);
}
- return success;
}
- /// \brief An augmenting phase of the Ford-Fulkerson algorithm
- ///
- /// It runs an augmenting phase of the Ford-Fulkerson
- /// algorithm. This phase finds only one augmenting path and
- /// augments only on this paths. The algorithm consists at most
- /// of \f$ O(n) \f$ simple phase and one phase is at most
- /// \f$ O(e) \f$ long.
- bool simpleAugment() {
-
- typename Graph::template ANodeMap<bool> areached(*graph, false);
- typename Graph::template BNodeMap<bool> breached(*graph, false);
+ public:
- typename Graph::template BNodeMap<UEdge> bpred(*graph, INVALID);
+ /// \brief An augmenting phase with single path augementing
+ ///
+ /// This phase finds only one augmenting paths and augments on
+ /// these paths. The algorithm consists at most of \f$ O(n) \f$
+ /// phase and one phase is \f$ O(e) \f$ long.
+ bool simpleAugment() {
+ ++_phase;
+
+ typename Graph::template ANodeMap<UEdge> _pred(*_graph);
- std::vector<Node> queue;
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- if (anode_matching[it] == INVALID) {
+ std::vector<Node> queue, aqueue;
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ if (_rmatching[it] == INVALID) {
queue.push_back(it);
- areached[it] = true;
+ _reached.set(it, _phase);
}
}
- while (!queue.empty()) {
- std::vector<Node> newqueue;
+ bool success = false;
+
+ int level = 0;
+ while (!success && !queue.empty()) {
+ std::vector<Node> nqueue;
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;
- bpred[bnode] = jt;
- if (bnode_matching[bnode] == INVALID) {
- while (bnode != INVALID) {
- UEdge uedge = bpred[bnode];
- anode = graph->aNode(uedge);
-
- bnode_matching[bnode] = uedge;
-
- bnode = anode_matching[anode] != INVALID ?
- graph->bNode(anode_matching[anode]) : INVALID;
-
- anode_matching[anode] = uedge;
-
- }
- ++matching_size;
- return true;
+ Node bnode = queue[i];
+ for (IncEdgeIt jt(*_graph, bnode); jt != INVALID; ++jt) {
+ Node anode = _graph->aNode(jt);
+ if (_matching[anode] == INVALID) {
+ _pred.set(anode, jt);
+ _find_path_bfs(anode, _pred);
+ ++_size;
+ return true;
} else {
- Node newanode = graph->aNode(bnode_matching[bnode]);
- if (!areached[newanode]) {
- areached[newanode] = true;
- newqueue.push_back(newanode);
+ Node nnode = _graph->bNode(_matching[anode]);
+ if (_reached[nnode] != _phase) {
+ _pred.set(anode, jt);
+ _reached.set(nnode, _phase);
+ nqueue.push_back(nnode);
}
}
}
}
- queue.swap(newqueue);
+ ++level;
+ queue.swap(nqueue);
}
- return false;
+ return success;
}
+
+
/// \brief Starts the algorithm.
///
/// Starts the algorithm. It runs augmenting phases until the optimal
@@ -350,6 +361,27 @@
///@{
+ /// \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 _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.
+ /// \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& node) const {
+ if (_graph->aNode(node)) {
+ return _matching[node];
+ } else {
+ return _rmatching[node];
+ }
+ }
+
/// \brief Set true all matching uedge in the map.
///
/// Set true all matching uedge in the map. It does not change the
@@ -357,12 +389,12 @@
/// \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.set(anode_matching[it], true);
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ if (_matching[it] != INVALID) {
+ mm.set(_matching[it], true);
}
}
- return matching_size;
+ return _size;
}
/// \brief Set true all matching uedge in the map and the others to false.
@@ -371,10 +403,10 @@
/// \return The number of the matching edges.
template <typename MatchingMap>
int matching(MatchingMap& mm) const {
- for (UEdgeIt it(*graph); it != INVALID; ++it) {
- mm.set(it, it == anode_matching[graph->aNode(it)]);
+ for (UEdgeIt it(*_graph); it != INVALID; ++it) {
+ mm.set(it, it == _matching[_graph->aNode(it)]);
}
- return matching_size;
+ return _size;
}
///Gives back the matching in an ANodeMap.
@@ -384,10 +416,10 @@
///\return The number of the matching edges.
template<class MatchingMap>
int aMatching(MatchingMap& mm) const {
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- mm.set(it, anode_matching[it]);
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ mm.set(it, _matching[it]);
}
- return matching_size;
+ return _size;
}
///Gives back the matching in a BNodeMap.
@@ -397,36 +429,10 @@
///\return The number of the matching edges.
template<class MatchingMap>
int bMatching(MatchingMap& mm) const {
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- mm.set(it, bnode_matching[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];
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ mm.set(it, _rmatching[it]);
}
- }
-
- /// \brief Gives back the number of the matching edges.
- ///
- /// Gives back the number of the matching edges.
- int matchingSize() const {
- return matching_size;
+ return _size;
}
/// \brief Returns a minimum covering of the nodes.
@@ -438,54 +444,23 @@
template <typename CoverMap>
int coverSet(CoverMap& covering) 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) {
- queue.push_back(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);
- }
-
int size = 0;
- for (ANodeIt it(*graph); it != INVALID; ++it) {
- covering.set(it, !areached[it] && anode_matching[it] != INVALID);
- if (!areached[it] && anode_matching[it] != INVALID) {
- ++size;
- }
- }
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- covering.set(it, breached[it]);
- if (breached[it]) {
- ++size;
- }
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ bool cn = _matching[it] != INVALID &&
+ _reached[_graph->bNode(_matching[it])] == _phase;
+ covering.set(it, cn);
+ if (cn) ++size;
+ }
+ for (BNodeIt it(*_graph); it != INVALID; ++it) {
+ bool cn = _reached[it] != _phase;
+ covering.set(it, cn);
+ if (cn) ++size;
}
return size;
}
/// \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.
@@ -493,43 +468,14 @@
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) {
- queue.push_back(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.set(it, areached[it] || anode_matching[it] == INVALID);
+ for (ANodeIt it(*_graph); it != INVALID; ++it) {
+ barrier.set(it, _matching[it] == INVALID ||
+ _reached[_graph->bNode(_matching[it])] != _phase);
}
}
/// \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.
@@ -537,50 +483,31 @@
template <typename BarrierMap>
void bBarrier(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) {
- queue.push_back(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 (BNodeIt it(*_graph); it != INVALID; ++it) {
+ barrier.set(it, _reached[it] == _phase);
}
+ }
- for (BNodeIt it(*graph); it != INVALID; ++it) {
- barrier.set(it, !breached[it]);
- }
+ /// \brief Gives back the number of the matching edges.
+ ///
+ /// Gives back the number of the matching edges.
+ int matchingSize() const {
+ return _size;
}
/// @}
private:
- ANodeMatchingMap anode_matching;
- BNodeMatchingMap bnode_matching;
- const Graph *graph;
+ typename BpUGraph::template ANodeMap<UEdge> _matching;
+ typename BpUGraph::template BNodeMap<UEdge> _rmatching;
- int matching_size;
+ typename BpUGraph::template BNodeMap<int> _reached;
+
+ int _phase;
+ const Graph *_graph;
+
+ int _size;
};
Modified: lemon/trunk/lemon/pr_bipartite_matching.h
==============================================================================
--- lemon/trunk/lemon/pr_bipartite_matching.h (original)
+++ lemon/trunk/lemon/pr_bipartite_matching.h Tue Aug 28 15:58:54 2007
@@ -59,6 +59,10 @@
public:
+ /// Constructor
+
+ /// Constructor
+ ///
PrBipartiteMatching(const Graph &g) :
_g(g),
_node_num(countBNodes(g)),
@@ -195,14 +199,15 @@
_levels.liftToTop(actlevel);
}
- _matching_size = _node_num;
- for(ANodeIt n(_g);n!=INVALID;++n)
- if(_matching[n]==INVALID) _matching_size--;
- else if (_cov[_g.bNode(_matching[n])]>1) {
+ for(ANodeIt n(_g);n!=INVALID;++n) {
+ if (_matching[n]==INVALID)continue;
+ if (_cov[_g.bNode(_matching[n])]>1) {
_cov[_g.bNode(_matching[n])]--;
- _matching_size--;
_matching[n]=INVALID;
+ } else {
+ ++_matching_size;
}
+ }
}
///Start the algorithm to find a perfect matching
@@ -261,6 +266,7 @@
_empty_level=actlevel;
return false;
}
+ _matching_size = _node_num;
return true;
}
More information about the Lemon-commits
mailing list