[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