[Lemon-commits] [lemon_svn] klao: r1420 - in hugo/trunk: doc src/lemon src/lemon/concept src/test

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:45:18 CET 2006


Author: klao
Date: Mon Dec  6 01:30:44 2004
New Revision: 1420

Added:
   hugo/trunk/doc/developpers_interface.dox
   hugo/trunk/doc/undir_graphs.dox
Modified:
   hugo/trunk/doc/Doxyfile
   hugo/trunk/doc/groups.dox
   hugo/trunk/src/lemon/concept/graph.h
   hugo/trunk/src/lemon/concept/graph_component.h
   hugo/trunk/src/lemon/concept/undir_graph.h
   hugo/trunk/src/lemon/iterable_graph_extender.h
   hugo/trunk/src/lemon/undir_graph_extender.h
   hugo/trunk/src/test/undir_graph_test.cc

Log:
Undirected graph documentation and concept refinements.

* quite a few bug fixes
* concept::UndirGraph is almost complete and looks quite good.


Modified: hugo/trunk/doc/Doxyfile
==============================================================================
--- hugo/trunk/doc/Doxyfile	(original)
+++ hugo/trunk/doc/Doxyfile	Mon Dec  6 01:30:44 2004
@@ -425,12 +425,14 @@
 
 INPUT                  = mainpage.dox \
                          graphs.dox \
+                         undir_graphs.dox \ 
                          named-param.dox \
                          maps.dox \
                          coding_style.dox \
                          groups.dox \
                          namespaces.dox \
 			 license.dox \
+                         developpers_interface.dox \
                          ../src/lemon \
                          ../src/lemon/concept \
                          ../src/test/test_tools.h

Added: hugo/trunk/doc/developpers_interface.dox
==============================================================================
--- (empty file)
+++ hugo/trunk/doc/developpers_interface.dox	Mon Dec  6 01:30:44 2004
@@ -0,0 +1,7 @@
+/*!
+
+\page developpers_interface Developpers' interface to graph structures
+
+Under construction
+
+*/

Modified: hugo/trunk/doc/groups.dox
==============================================================================
--- hugo/trunk/doc/groups.dox	(original)
+++ hugo/trunk/doc/groups.dox	Mon Dec  6 01:30:44 2004
@@ -80,15 +80,27 @@
 */
 
 /**
- at defgroup concept Concept
+ at defgroup concept Concepts
 \brief Skeleton classes and concept checking classes
 
 This group describes the data/algorithm skeletons and concept checking
-classes implemented in LEMON. These classes exist in order to make it
-easier to check if a certain template class or template function is
-correctly implemented.
+classes implemented in LEMON.
+
+One aim of these classes is to make it easier to check if a certain
+class or template function is correctly implemented.
+
+The other (sometimes even more important) aim is to document the concepts.
+
 */
 
+/**
+ at defgroup graph_concepts Graph Structure Concepts
+ at ingroup concept
+\brief Skeleton and concept checking classes for graph structures
+
+This group contains the skeletons and concept checking classes of LEMON's
+graph structures and helper classes used to implement these.
+*/
 
 /**
 @defgroup experimental Experimental Structures and Algorithms

Added: hugo/trunk/doc/undir_graphs.dox
==============================================================================
--- (empty file)
+++ hugo/trunk/doc/undir_graphs.dox	Mon Dec  6 01:30:44 2004
@@ -0,0 +1,9 @@
+/*!
+
+\page undir_graphs Undirected graph structures
+
+The primary data structures of LEMON are the graph classes.
+
+Under construction.
+
+*/

Modified: hugo/trunk/src/lemon/concept/graph.h
==============================================================================
--- hugo/trunk/src/lemon/concept/graph.h	(original)
+++ hugo/trunk/src/lemon/concept/graph.h	Mon Dec  6 01:30:44 2004
@@ -17,7 +17,7 @@
 #ifndef LEMON_CONCEPT_GRAPH_H
 #define LEMON_CONCEPT_GRAPH_H
 
-///\ingroup concept
+///\ingroup graph_concepts
 ///\file
 ///\brief Declaration of Graph.
 
@@ -29,7 +29,7 @@
 namespace lemon {
   namespace concept {
     
-    /// \addtogroup concept
+    /// \addtogroup graph_concepts
     /// @{
 
 //     /// An empty static graph class.

Modified: hugo/trunk/src/lemon/concept/graph_component.h
==============================================================================
--- hugo/trunk/src/lemon/concept/graph_component.h	(original)
+++ hugo/trunk/src/lemon/concept/graph_component.h	Mon Dec  6 01:30:44 2004
@@ -14,7 +14,7 @@
  *
  */
 
-///\ingroup concept
+///\ingroup graph_concepts
 ///\file
 ///\brief The graph components.
 
@@ -28,22 +28,32 @@
 namespace lemon {
   namespace concept {
 
+    /// \addtogroup graph_concepts
+    /// @{
 
     /****************   Graph iterator concepts   ****************/
 
-    /// Skeleton class for graph Node and Edge
+    /// Skeleton class for graph Node and Edge types
 
-    /// \note Because Node and Edge are forbidden to inherit from the same
-    /// base class, this is a template. For Node you should instantiate it
-    /// with character 'n' and for Edge with 'e'.
+    /// This class describes the interface of Node and Edge (and UndirEdge
+    /// in undirected graphs) subtypes of graph types.
+    ///
+    /// \note This class is a template class so that we can use it to
+    /// create graph skeleton classes. The reason for this is than Node
+    /// and Edge types should \em not derive from the same base class.
+    /// For Node you should instantiate it with character 'n' and for Edge
+    /// with 'e'.
 
-    template<char _selector>
+#ifndef DOXYGEN
+    template <char _selector = '0'>
+#endif
     class GraphItem {
     public:
       /// Default constructor.
       
-      /// @warning The default constructor sets the item
-      /// to an undefined value.
+      /// \warning The default constructor is not required to set
+      /// the item to some well-defined value. So you should consider it
+      /// as uninitialized.
       GraphItem() {}
       /// Copy constructor.
       
@@ -71,9 +81,17 @@
       ///
       bool operator!=(GraphItem) const { return false; }
 
-      // Technical requirement. Do we really need this?
-      //      bool operator<(GraphItem) const { return false; }
+      /// Artificial ordering operator.
 
+      /// To allow the use of graph descriptors as key type in std::map or
+      /// similar associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      ///
+      /// \bug This is a technical requirement. Do we really need this?
+      bool operator<(GraphItem) const { return false; }
 
       template<typename _GraphItem>
       struct Constraints {
@@ -88,6 +106,7 @@
 	  //	  b = (ia == ib) && (ia != ib) && (ia < ib);
 	  b = (ia == ib) && (ia != ib);
 	  b = (ia == INVALID) && (ib != INVALID);
+	  b = (ia < ib);
 	}
 
 	const _GraphItem &ia;
@@ -95,6 +114,21 @@
       };
     };
 
+    /// A type describing the concept of graph node
+
+    /// This is an instantiation of \ref GraphItem which can be used as a
+    /// Node subtype in graph skeleton definitions
+    typedef GraphItem<'n'> GraphNode;
+
+    /// A type describing the concept of graph edge
+
+    /// This is an instantiation of \ref GraphItem which can be used as a
+    /// Edge subtype in graph skeleton definitions
+    typedef GraphItem<'e'> GraphEdge;
+
+
+    /**************** Basic features of graphs ****************/
+
     /// An empty base graph class.
   
     /// This class provides the minimal set of features needed for a graph
@@ -629,6 +663,11 @@
     };
 
 
+    /// Class describing the concept of graph maps
+
+    /// This class describes the common interface of the graph maps
+    /// (NodeMap, EdgeMap), that is \ref maps "maps" which can be used to
+    /// associate data to graph descriptors (nodes or edges).
     template <typename Graph, typename Item, typename _Value>
     class GraphMap : public ReadWriteMap<Item, _Value> {
     protected:      
@@ -804,6 +843,8 @@
       };
     };
 
+    /// @}
+
   }
 
 }

Modified: hugo/trunk/src/lemon/concept/undir_graph.h
==============================================================================
--- hugo/trunk/src/lemon/concept/undir_graph.h	(original)
+++ hugo/trunk/src/lemon/concept/undir_graph.h	Mon Dec  6 01:30:44 2004
@@ -17,7 +17,7 @@
  *
  */
 
-///\ingroup concept
+///\ingroup graph_concepts
 ///\file
 ///\brief Undirected graphs and components of.
 
@@ -30,7 +30,62 @@
 namespace lemon {
   namespace concept {
 
-    /// \todo to be done
+    /// \addtogroup graph_concepts
+    /// @{
+
+
+    /// Skeleton class which describes an edge with direction in \ref
+    /// UndirGraph "undirected graph".
+    template <typename UndirEdge>
+    class UndirGraphEdge : public UndirEdge {
+    public:
+
+      /// \e
+      UndirGraphEdge() {}
+
+      /// \e
+      UndirGraphEdge(const UndirGraphEdge&) {}
+
+      /// \e
+      UndirGraphEdge(Invalid) {}
+
+      /// \brief Constructs a directed version of an undirected edge
+      ///
+      /// \param forward If \c true the direction of the contructed edge
+      /// is the same as the inherent direction of the \c undir_edge; if
+      /// \c false --- the opposite.
+      UndirGraphEdge(UndirEdge undir_edge, bool forward) {
+	ignore_unused_variable_warning(undir_edge);
+	ignore_unused_variable_warning(forward);
+      }
+
+      /// \e
+      UndirGraphEdge& operator=(UndirGraphEdge) { return *this; }
+
+      /// \e
+      bool operator==(UndirGraphEdge) const { return true; }
+      /// \e
+      bool operator!=(UndirGraphEdge) const { return false; }
+
+      /// \e
+      bool operator<(UndirGraphEdge) const { return false; }
+
+      template <typename Edge>
+      struct Constraints {
+	void constraints() {
+	  /// \bug This should be is_base_and_derived ...
+	  UndirEdge ue = e;
+	  ue = e;
+	  Edge forward(ue, true);
+	  Edge backward(ue, false);
+
+	  ignore_unused_variable_warning(forward);
+	  ignore_unused_variable_warning(backward);
+	}
+	Edge e;
+      };
+    };
+    
 
     struct BaseIterableUndirGraphConcept {
 
@@ -43,21 +98,29 @@
 
 	void constraints() {
 	  checkConcept<BaseIterableGraphComponent, Graph>();
-	  checkConcept<GraphItem<'u'>, UndirEdge >();
+	  checkConcept<GraphItem<>, UndirEdge>();
+	  checkConcept<UndirGraphEdge<UndirEdge>, Edge>();
 
-	  /// \bug this should be base_and_derived:
-	  UndirEdge ue = e;
-	  ue = e;
+	  graph.first(ue);
+	  graph.next(ue);
 
+	  const_constraints();
+	}
+	void const_constraints() {
 	  Node n;
 	  n = graph.target(ue);
 	  n = graph.source(ue);
+	  n = graph.oppositeNode(n0, ue);
 
-	  graph.first(ue);
-	  graph.next(ue);
+	  bool b;
+	  b = graph.forward(e);
+	  ignore_unused_variable_warning(b);
 	}
-	const Graph &graph;
+
+	Graph graph;
 	Edge e;
+	Node n0;
+	UndirEdge ue;
       };
 
     };
@@ -76,10 +139,10 @@
 
 	  typedef typename Graph::UndirEdge UndirEdge;
 	  typedef typename Graph::UndirEdgeIt UndirEdgeIt;
-	  typedef typename Graph::UndirIncEdgeIt UndirIncEdgeIt;
+	  typedef typename Graph::IncEdgeIt IncEdgeIt;
 
 	  checkConcept<GraphIterator<Graph, UndirEdge>, UndirEdgeIt>();
-	  checkConcept<GraphIncIterator<Graph, UndirEdge>, UndirIncEdgeIt>();
+	  checkConcept<GraphIncIterator<Graph, UndirEdge>, IncEdgeIt>();
 	}
       };
 
@@ -145,9 +208,228 @@
 
     };
 
+    /// Class describing the concept of Undirected Graphs.
+
+    /// This class describes the common interface of all Undirected
+    /// Graphs.
+    ///
+    /// As all concept describing classes it provides only interface
+    /// without any sensible implementation. So any algorithm for
+    /// undirected graph should compile with this class, but it will not
+    /// run properly, of couse.
+    ///
+    /// In LEMON undirected graphs also fulfill the concept of directed
+    /// graphs (\ref lemon::concept::Graph "Graph Concept"). For
+    /// explanation of this and more see also the page \ref undir_graphs,
+    /// a tutorial about undirected graphs.
+
     class UndirGraph {
     public:
 
+      /// Type describing a node in the graph
+      typedef GraphNode Node;
+
+      /// Type describing an undirected edge
+      typedef GraphItem<'u'> UndirEdge;
+
+      /// Type describing an UndirEdge with direction
+#ifndef DOXYGEN
+      typedef UndirGraphEdge<UndirEdge> Edge;
+#else
+      typedef UndirGraphEdge Edge;
+#endif
+
+      /// Iterator type which iterates over all nodes
+#ifndef DOXYGEN
+      typedef GraphIterator<UndirGraph, Node> NodeIt;
+#else
+      typedef GraphIterator NodeIt;
+#endif
+
+      /// Iterator type which iterates over all undirected edges
+#ifndef DOXYGEN
+      typedef GraphIterator<UndirGraph, UndirEdge> UndirEdgeIt;
+#else
+      typedef GraphIterator UndirEdgeIt;
+#endif
+
+      /// Iterator type which iterates over all directed edges.
+
+      /// Iterator type which iterates over all edges (each undirected
+      /// edge occurs twice with both directions.
+#ifndef DOXYGEN
+      typedef GraphIterator<UndirGraph, Edge> EdgeIt;
+#else
+      typedef GraphIterator EdgeIt;
+#endif
+
+
+      /// Iterator of undirected edges incident to a node
+#ifndef DOXYGEN
+      typedef GraphIncIterator<UndirGraph, UndirEdge, 'u'> IncEdgeIt;
+#else
+      typedef GraphIncIterator IncEdgeIt;
+#endif
+
+      /// Iterator of edges incoming to a node
+#ifndef DOXYGEN
+      typedef GraphIncIterator<UndirGraph, Edge, 'i'> InEdgeIt;
+#else
+      typedef GraphIncIterator InEdgeIt;
+#endif
+
+      /// Iterator of edges outgoing from a node
+#ifndef DOXYGEN
+      typedef GraphIncIterator<UndirGraph, Edge, 'o'> OutEdgeIt;
+#else
+      typedef GraphIncIterator OutEdgeIt;
+#endif
+
+      /// NodeMap template
+#ifdef DOXYGEN
+      typedef GraphMap NodeMap<T>;
+#endif
+
+      /// UndirEdgeMap template
+#ifdef DOXYGEN
+      typedef GraphMap UndirEdgeMap<T>;
+#endif
+
+      /// EdgeMap template
+#ifdef DOXYGEN
+      typedef GraphMap EdgeMap<T>;
+#endif
+
+      template <typename T>
+      class NodeMap : public GraphMap<UndirGraph, Node, T> {
+	typedef GraphMap<UndirGraph, Node, T> Parent;
+      public:
+
+	explicit NodeMap(const UndirGraph &g) : Parent(g) {}
+	NodeMap(const UndirGraph &g, T t) : Parent(g, t) {}
+      };
+
+      template <typename T>
+      class UndirEdgeMap : public GraphMap<UndirGraph, UndirEdge, T> {
+	typedef GraphMap<UndirGraph, UndirEdge, T> Parent;
+      public:
+
+	explicit UndirEdgeMap(const UndirGraph &g) : Parent(g) {}
+	UndirEdgeMap(const UndirGraph &g, T t) : Parent(g, t) {}
+      };
+
+      template <typename T>
+      class EdgeMap : public GraphMap<UndirGraph, Edge, T> {
+	typedef GraphMap<UndirGraph, Edge, T> Parent;
+      public:
+
+	explicit EdgeMap(const UndirGraph &g) : Parent(g) {}
+	EdgeMap(const UndirGraph &g, T t) : Parent(g, t) {}
+      };
+
+      /// Is the Edge oriented "forward"?
+
+      /// Returns whether the given directed edge is same orientation as
+      /// the corresponding undirected edge.
+      ///
+      /// \todo "What does the direction of an undirected edge mean?"
+      bool forward(Edge) const { return true; }
+
+      /// Opposite node on an edge
+
+      /// \return the opposite of the given Node on the given Edge
+      ///
+      /// \todo What should we do if given Node and Edge are not incident?
+      Node oppositeNode(Node, UndirEdge) const { return INVALID; }
+
+      /// First node of the undirected edge.
+
+      /// \return the first node of the given UndirEdge.
+      ///
+      /// Naturally undirectected edges don't have direction and thus
+      /// don't have source and target node. But we use these two methods
+      /// to query the two endnodes of the edge. The direction of the edge
+      /// which arises this way is called the inherent direction of the
+      /// undirected edge, and is used to define the "forward" direction
+      /// of the directed versions of the edges.
+      /// \sa forward
+      Node source(UndirEdge) const { return INVALID; }
+
+      /// Second node of the undirected edge.
+      Node target(UndirEdge) const { return INVALID; }
+
+      /// Source node of the directed edge.
+      Node source(Edge) const { return INVALID; }
+
+      /// Target node of the directed edge.
+      Node target(Edge) const { return INVALID; }
+
+      /// First node of the graph
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void first(Node&) const {}
+      /// Next node of the graph
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void next(Node&) const {}
+
+      /// First undirected edge of the graph
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void first(UndirEdge&) const {}
+      /// Next undirected edge of the graph
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void next(UndirEdge&) const {}
+
+      /// First directed edge of the graph
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void first(Edge&) const {}
+      /// Next directed edge of the graph
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void next(Edge&) const {}
+
+      /// First outgoing edge from a given node
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void firstOut(Edge&, Node) const {}
+      /// Next outgoing edge to a node
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void nextOut(Edge&) const {}
+
+      /// First incoming edge to a given node
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void firstIn(Edge&, Node) const {}
+      /// Next incoming edge to a node
+
+      /// \note This method is part of so called \ref
+      /// developpers_interface "Developpers' interface", so it shouldn't
+      /// be used in an end-user program.
+      void nextIn(Edge&) const {}
+
+
       template <typename Graph>
       struct Constraints {
 	void constraints() {
@@ -190,6 +472,8 @@
 
     };
 
+    /// @}
+
   }
 
 }

Modified: hugo/trunk/src/lemon/iterable_graph_extender.h
==============================================================================
--- hugo/trunk/src/lemon/iterable_graph_extender.h	(original)
+++ hugo/trunk/src/lemon/iterable_graph_extender.h	Mon Dec  6 01:30:44 2004
@@ -157,7 +157,7 @@
 
     };
 
-    class UndirIncEdgeIt : public UndirEdge { 
+    class IncEdgeIt : public UndirEdge { 
       const Graph* graph;
       bool forward;
       friend class IterableUndirGraphExtender;
@@ -165,30 +165,30 @@
       friend class UndirGraphExtender;
     public:
 
-      UndirIncEdgeIt() { }
+      IncEdgeIt() { }
 
-      UndirIncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
+      IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
 
-      explicit UndirIncEdgeIt(const Graph& _graph, const Node &n)
+      explicit IncEdgeIt(const Graph& _graph, const Node &n)
 	: graph(&_graph)
       {
 	_graph._dirFirstOut(*this, n);
       }
 
       // FIXME: Do we need this type of constructor here?
-      // UndirIncEdgeIt(const Graph& _graph, const Edge& e) : 
+      // IncEdgeIt(const Graph& _graph, const Edge& e) : 
       //   UndirEdge(e), graph(&_graph), forward(_graph.forward(e)) { }
       // or
-      // UndirIncEdgeIt(const Graph& _graph, const Node& n,
+      // IncEdgeIt(const Graph& _graph, const Node& n,
       //    Const UndirEdge &e) ... ?
 
-      UndirIncEdgeIt& operator++() {
+      IncEdgeIt& operator++() {
 	graph->_dirNextOut(*this);
 	return *this; 
       }
     };
 
-    Node source(const UndirIncEdgeIt &e) const {
+    Node source(const IncEdgeIt &e) const {
       return _dirSource(e);
     }
 
@@ -197,7 +197,7 @@
     using Parent::source;
 
     /// Target of the given Edge.
-    Node target(const UndirIncEdgeIt &e) const {
+    Node target(const IncEdgeIt &e) const {
       return _dirTarget(e);
     }
 

Modified: hugo/trunk/src/lemon/undir_graph_extender.h
==============================================================================
--- hugo/trunk/src/lemon/undir_graph_extender.h	(original)
+++ hugo/trunk/src/lemon/undir_graph_extender.h	Mon Dec  6 01:30:44 2004
@@ -108,7 +108,7 @@
     /// concept. "What does the direction of an undirected edge mean?"
     bool forward(const Edge &e) const { return e.forward; }
 
-    Node oppsiteNode(const Node &n, const Edge &e) const {
+    Node oppositeNode(const Node &n, const UndirEdge &e) const {
       if( n == Parent::source(e))
 	return Parent::target(e);
       else if( n == Parent::target(e))

Modified: hugo/trunk/src/test/undir_graph_test.cc
==============================================================================
--- hugo/trunk/src/test/undir_graph_test.cc	(original)
+++ hugo/trunk/src/test/undir_graph_test.cc	Mon Dec  6 01:30:44 2004
@@ -33,5 +33,7 @@
   checkConcept<UndirGraph, Graph>();
   checkConcept<ErasableUndirGraph, Graph>();
 
+  checkConcept<UndirGraph, UndirGraph>();
+
   return 0;
 }



More information about the Lemon-commits mailing list