[Lemon-commits] Alpar Juttner: Merge
Lemon HG
hg at lemon.cs.elte.hu
Tue Apr 21 16:33:30 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/0ba8dfce7259
changeset: 632:0ba8dfce7259
user: Alpar Juttner <alpar [at] cs.elte.hu>
date: Tue Apr 21 13:08:19 2009 +0100
description:
Merge
diffstat:
doc/groups.dox | 5 +-
lemon/Makefile.am | 2 +-
lemon/euler.h | 199 ++++++++++--------
lemon/max_matching.h | 515 +++++++++++++++++++++++++++++-----------------
test/CMakeLists.txt | 2 +-
test/Makefile.am | 4 +-
test/euler_test.cc | 216 +++++++++++++------
test/max_matching_test.cc | 136 +++++++++++-
tools/dimacs-solver.cc | 2 +-
9 files changed, 713 insertions(+), 368 deletions(-)
diffs (truncated from 1837 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/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -89,8 +89,8 @@
lemon/lp_skeleton.h \
lemon/list_graph.h \
lemon/maps.h \
+ lemon/matching.h \
lemon/math.h \
- lemon/max_matching.h \
lemon/min_cost_arborescence.h \
lemon/nauty_reader.h \
lemon/path.h \
diff --git a/lemon/euler.h b/lemon/euler.h
--- a/lemon/euler.h
+++ b/lemon/euler.h
@@ -26,33 +26,31 @@
/// \ingroup graph_properties
/// \file
-/// \brief Euler tour
+/// \brief Euler tour iterators and a function for checking the \e Eulerian
+/// property.
///
-///This file provides an Euler tour iterator and ways to check
-///if a digraph is euler.
-
+///This file provides Euler tour iterators and a function to check
+///if a (di)graph is \e Eulerian.
namespace lemon {
- ///Euler iterator for digraphs.
+ ///Euler tour iterator for digraphs.
- /// \ingroup graph_properties
- ///This iterator converts to the \c Arc type of the digraph and using
- ///operator ++, it provides an Euler tour of a \e directed
- ///graph (if there exists).
+ /// \ingroup graph_prop
+ ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
+ ///graph (if there exists) and it converts to the \c Arc type of the digraph.
///
- ///For example
- ///if the given digraph is Euler (i.e it has only one nontrivial component
- ///and the in-degree is equal to the out-degree for all nodes),
- ///the following code will put the arcs of \c g
- ///to the vector \c et according to an
- ///Euler tour of \c g.
+ ///For example, if the given digraph has an Euler tour (i.e it has only one
+ ///non-trivial component and the in-degree is equal to the out-degree
+ ///for all nodes), then the following code will put the arcs of \c g
+ ///to the vector \c et according to an Euler tour of \c g.
///\code
/// std::vector<ListDigraph::Arc> et;
- /// for(DiEulerIt<ListDigraph> e(g),e!=INVALID;++e)
+ /// for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
/// et.push_back(e);
///\endcode
- ///If \c g is not Euler then the resulted tour will not be full or closed.
+ ///If \c g has no Euler tour, then the resulted walk will not be closed
+ ///or not contain all arcs.
///\sa EulerIt
template<typename GR>
class DiEulerIt
@@ -65,53 +63,65 @@
typedef typename GR::InArcIt InArcIt;
const GR &g;
- typename GR::template NodeMap<OutArcIt> nedge;
+ typename GR::template NodeMap<OutArcIt> narc;
std::list<Arc> euler;
public:
///Constructor
+ ///Constructor.
///\param gr A digraph.
- ///\param start The starting point of the tour. If it is not given
- /// the tour will start from the first node.
+ ///\param start The starting point of the tour. If it is not given,
+ ///the tour will start from the first node that has an outgoing arc.
DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
- : g(gr), nedge(g)
+ : g(gr), narc(g)
{
- if(start==INVALID) start=NodeIt(g);
- for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
- while(nedge[start]!=INVALID) {
- euler.push_back(nedge[start]);
- Node next=g.target(nedge[start]);
- ++nedge[start];
- start=next;
+ if (start==INVALID) {
+ NodeIt n(g);
+ while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
+ start=n;
+ }
+ if (start!=INVALID) {
+ for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
+ while (narc[start]!=INVALID) {
+ euler.push_back(narc[start]);
+ Node next=g.target(narc[start]);
+ ++narc[start];
+ start=next;
+ }
}
}
- ///Arc Conversion
+ ///Arc conversion
operator Arc() { return euler.empty()?INVALID:euler.front(); }
+ ///Compare with \c INVALID
bool operator==(Invalid) { return euler.empty(); }
+ ///Compare with \c INVALID
bool operator!=(Invalid) { return !euler.empty(); }
///Next arc of the tour
+
+ ///Next arc of the tour
+ ///
DiEulerIt &operator++() {
Node s=g.target(euler.front());
euler.pop_front();
- //This produces a warning.Strange.
- //std::list<Arc>::iterator next=euler.begin();
typename std::list<Arc>::iterator next=euler.begin();
- while(nedge[s]!=INVALID) {
- euler.insert(next,nedge[s]);
- Node n=g.target(nedge[s]);
- ++nedge[s];
+ while(narc[s]!=INVALID) {
+ euler.insert(next,narc[s]);
+ Node n=g.target(narc[s]);
+ ++narc[s];
s=n;
}
return *this;
}
///Postfix incrementation
+ /// Postfix incrementation.
+ ///
///\warning This incrementation
- ///returns an \c Arc, not an \ref DiEulerIt, as one may
+ ///returns an \c Arc, not a \ref DiEulerIt, as one may
///expect.
Arc operator++(int)
{
@@ -121,30 +131,28 @@
}
};
- ///Euler iterator for graphs.
+ ///Euler tour iterator for graphs.
/// \ingroup graph_properties
- ///This iterator converts to the \c Arc (or \c Edge)
- ///type of the digraph and using
- ///operator ++, it provides an Euler tour of an undirected
- ///digraph (if there exists).
+ ///This iterator provides an Euler tour (Eulerian circuit) of an
+ ///\e undirected graph (if there exists) and it converts to the \c Arc
+ ///and \c Edge types of the graph.
///
- ///For example
- ///if the given digraph if Euler (i.e it has only one nontrivial component
- ///and the degree of each node is even),
+ ///For example, if the given graph has an Euler tour (i.e it has only one
+ ///non-trivial component and the degree of each node is even),
///the following code will print the arc IDs according to an
///Euler tour of \c g.
///\code
- /// for(EulerIt<ListGraph> e(g),e!=INVALID;++e) {
+ /// for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
/// std::cout << g.id(Edge(e)) << std::eol;
/// }
///\endcode
- ///Although the iterator provides an Euler tour of an graph,
- ///it still returns Arcs in order to indicate the direction of the tour.
- ///(But Arc will convert to Edges, of course).
+ ///Although this iterator is for undirected graphs, it still returns
+ ///arcs in order to indicate the direction of the tour.
+ ///(But arcs convert to edges, of course.)
///
- ///If \c g is not Euler then the resulted tour will not be full or closed.
- ///\sa EulerIt
+ ///If \c g has no Euler tour, then the resulted walk will not be closed
+ ///or not contain all edges.
template<typename GR>
class EulerIt
{
@@ -157,7 +165,7 @@
typedef typename GR::InArcIt InArcIt;
const GR &g;
- typename GR::template NodeMap<OutArcIt> nedge;
+ typename GR::template NodeMap<OutArcIt> narc;
typename GR::template EdgeMap<bool> visited;
std::list<Arc> euler;
@@ -165,47 +173,56 @@
///Constructor
- ///\param gr An graph.
- ///\param start The starting point of the tour. If it is not given
- /// the tour will start from the first node.
+ ///Constructor.
+ ///\param gr A graph.
+ ///\param start The starting point of the tour. If it is not given,
+ ///the tour will start from the first node that has an incident edge.
EulerIt(const GR &gr, typename GR::Node start = INVALID)
- : g(gr), nedge(g), visited(g, false)
+ : g(gr), narc(g), visited(g, false)
{
- if(start==INVALID) start=NodeIt(g);
- for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
- while(nedge[start]!=INVALID) {
- euler.push_back(nedge[start]);
- visited[nedge[start]]=true;
- Node next=g.target(nedge[start]);
- ++nedge[start];
- start=next;
- while(nedge[start]!=INVALID && visited[nedge[start]]) ++nedge[start];
+ if (start==INVALID) {
+ NodeIt n(g);
+ while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
+ start=n;
+ }
+ if (start!=INVALID) {
+ for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
+ while(narc[start]!=INVALID) {
+ euler.push_back(narc[start]);
+ visited[narc[start]]=true;
+ Node next=g.target(narc[start]);
+ ++narc[start];
+ start=next;
+ while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
+ }
}
}
- ///Arc Conversion
+ ///Arc conversion
operator Arc() const { return euler.empty()?INVALID:euler.front(); }
- ///Arc Conversion
+ ///Edge conversion
operator Edge() const { return euler.empty()?INVALID:euler.front(); }
- ///\e
+ ///Compare with \c INVALID
bool operator==(Invalid) const { return euler.empty(); }
- ///\e
+ ///Compare with \c INVALID
bool operator!=(Invalid) const { return !euler.empty(); }
///Next arc of the tour
+
+ ///Next arc of the tour
+ ///
EulerIt &operator++() {
Node s=g.target(euler.front());
euler.pop_front();
typename std::list<Arc>::iterator next=euler.begin();
-
- while(nedge[s]!=INVALID) {
- while(nedge[s]!=INVALID && visited[nedge[s]]) ++nedge[s];
- if(nedge[s]==INVALID) break;
+ while(narc[s]!=INVALID) {
+ while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
+ if(narc[s]==INVALID) break;
else {
- euler.insert(next,nedge[s]);
- visited[nedge[s]]=true;
- Node n=g.target(nedge[s]);
- ++nedge[s];
+ euler.insert(next,narc[s]);
+ visited[narc[s]]=true;
+ Node n=g.target(narc[s]);
+ ++narc[s];
s=n;
}
}
More information about the Lemon-commits
mailing list