Main MRPT website > C++ reference
MRPT logo
CDirectedTree.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2014, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef MRPT_DIRECTED_TREE_H
10 #define MRPT_DIRECTED_TREE_H
11 
12 #include <mrpt/utils/utils_defs.h>
13 
14 /*---------------------------------------------------------------
15  Class
16  ---------------------------------------------------------------*/
17 namespace mrpt
18 {
19  namespace graphs
20  {
22 
23  /** A special kind of graph in the form of a tree with directed edges and optional edge annotations of templatized type "TYPE_EDGES".
24  * The tree is represented by means of:
25  * - \a root: The ID of the root node.
26  * - \a edges_to_children: A map from node ID to all the edges to its children.
27  *
28  * This class is less general than CDirectedGraph but more efficient to traverse (see \a visitDepthFirst and \a visitBreadthFirst).
29  *
30  * If annotations in edges are not required, you can leave TYPE_EDGES to its default type "uint8_t".
31  * \sa CDirectedGraph, CDijkstra, mrpt::graphs::CNetworkOfPoses,
32  * \ingroup mrpt_graphs_grp
33  */
34  template <class TYPE_EDGES = uint8_t>
36  {
37  public:
38  struct TEdgeInfo
39  {
40  TNodeID id; //!< The ID of the child node.
41  bool reverse; //!< True if edge direction is child->parent, false if it's parent->child.
42  TYPE_EDGES data; //!< User data for this edge.
43  };
44  typedef std::list<TEdgeInfo> TListEdges;
45  typedef std::map<TNodeID,TListEdges> TMapNode2ListEdges;
46 
47  /** @name Data
48  @{ */
49  TNodeID root; //!< The root of the tree
50  TMapNode2ListEdges edges_to_children; //!< The edges of each node
51  /** @} */
52 
53  /** @name Utilities
54  @{ */
55 
56  /** Empty all edge data and set "root" to INVALID_NODEID */
57  void clear() { edges_to_children.clear(); root = INVALID_NODEID; }
58 
59  /** Virtual base class for user-defined visitors */
60  struct Visitor
61  {
63 
64  /** Virtual method to be implemented by the user and which will be called during the visit to a graph with visitDepthFirst or visitBreadthFirst
65  * Specifically, the method will be called once for each <b>edge</b> in the tree.
66  * \param parent [IN] The ID of the parent node.
67  * \param edge_to_child [IN] The edge information from the parent to "edge_to_child.id"
68  * \param depth_level [IN] The "depth level" of the child node "edge_to_child.id" (root node is at 0, its children are at 1, etc.).
69  */
70  virtual void OnVisitNode( const TNodeID parent, const typename tree_t::TEdgeInfo &edge_to_child, const size_t depth_level ) = 0;
71  };
72 
73  /** Depth-first visit of all children nodes of a given root (itself excluded from the visit), invoking a user-provided function for each node/edge. \sa visitBreadthFirst */
74  void visitDepthFirst( const TNodeID root, Visitor & user_visitor, const size_t root_depth_level =0 ) const
75  {
76  const size_t next_depth_level = root_depth_level+1;
77  typename TMapNode2ListEdges::const_iterator itChildren = edges_to_children.find(root);
78  if (itChildren==edges_to_children.end()) return; // No children
79  const TListEdges &children = itChildren->second;
80  for (typename TListEdges::const_iterator itEdge=children.begin();itEdge!=children.end();++itEdge)
81  {
82  user_visitor.OnVisitNode(root,*itEdge,next_depth_level);
83  visitDepthFirst(itEdge->id,user_visitor, next_depth_level); // Recursive depth-first call.
84  }
85  }
86 
87  /** Breadth-first visit of all children nodes of a given root (itself excluded from the visit), invoking a user-provided function for each node/edge. \sa visitDepthFirst */
88  void visitBreadthFirst( const TNodeID root, Visitor & user_visitor, const size_t root_depth_level =0 ) const
89  {
90  const size_t next_depth_level = root_depth_level+1;
91  typename TMapNode2ListEdges::const_iterator itChildren = edges_to_children.find(root);
92  if (itChildren==edges_to_children.end()) return; // No children
93  const TListEdges &children = itChildren->second;
94  for (typename TListEdges::const_iterator itEdge=children.begin();itEdge!=children.end();++itEdge)
95  user_visitor.OnVisitNode(root,*itEdge,next_depth_level);
96  for (typename TListEdges::const_iterator itEdge=children.begin();itEdge!=children.end();++itEdge)
97  visitDepthFirst(itEdge->id,user_visitor,next_depth_level); // Recursive breath-first call.
98  }
99 
100  /** Return a text representation of the tree spanned in a depth-first view, as in this example:
101  * \code
102  * 0
103  * -> 1
104  * -> 2
105  * -> 4
106  * -> 5
107  * -> 3
108  * \endcode
109  */
110  std::string getAsTextDescription() const
111  {
112  std::ostringstream s;
113  struct CMyVisitor : public mrpt::graphs::CDirectedTree<TYPE_EDGES>::Visitor
114  {
115  std::ostringstream &m_s;
116  CMyVisitor(std::ostringstream &s) : m_s(s) { }
117  virtual void OnVisitNode( const TNodeID parent, const typename mrpt::graphs::CDirectedTree<TYPE_EDGES>::Visitor::tree_t::TEdgeInfo &edge_to_child, const size_t depth_level ) {
118  m_s << std::string(depth_level*5, ' ') << (edge_to_child.reverse ? "<-" : "->" ) //;
119  << edge_to_child.id << std::endl;
120  }
121  };
122  CMyVisitor myVisitor(s);
123  s << root << std::endl;
124  visitDepthFirst( root, myVisitor );
125  return s.str();
126  }
127 
128  };
129 
130  /** @} */
131  } // End of namespace
132 } // End of namespace
133 #endif
void visitBreadthFirst(const TNodeID root, Visitor &user_visitor, const size_t root_depth_level=0) const
Breadth-first visit of all children nodes of a given root (itself excluded from the visit)...
Definition: CDirectedTree.h:88
TMapNode2ListEdges edges_to_children
The edges of each node.
Definition: CDirectedTree.h:50
A special kind of graph in the form of a tree with directed edges and optional edge annotations of te...
Definition: CDirectedTree.h:35
std::list< TEdgeInfo > TListEdges
Definition: CDirectedTree.h:44
const Scalar * const_iterator
Definition: eigen_plugins.h:24
CDirectedTree< TYPE_EDGES > tree_t
Definition: CDirectedTree.h:62
Virtual base class for user-defined visitors.
Definition: CDirectedTree.h:60
bool reverse
True if edge direction is child->parent, false if it's parent->child.
Definition: CDirectedTree.h:41
std::string getAsTextDescription() const
Return a text representation of the tree spanned in a depth-first view, as in this example: ...
virtual void OnVisitNode(const TNodeID parent, const typename tree_t::TEdgeInfo &edge_to_child, const size_t depth_level)=0
Virtual method to be implemented by the user and which will be called during the visit to a graph wit...
TNodeID root
The root of the tree.
Definition: CDirectedTree.h:49
TNodeID id
The ID of the child node.
Definition: CDirectedTree.h:40
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
uint64_t TNodeID
The type for node IDs in graphs of different types.
TYPE_EDGES data
User data for this edge.
Definition: CDirectedTree.h:42
std::map< TNodeID, TListEdges > TMapNode2ListEdges
Definition: CDirectedTree.h:45
void visitDepthFirst(const TNodeID root, Visitor &user_visitor, const size_t root_depth_level=0) const
Depth-first visit of all children nodes of a given root (itself excluded from the visit)...
Definition: CDirectedTree.h:74
void clear()
Empty all edge data and set "root" to INVALID_NODEID.
Definition: CDirectedTree.h:57
#define INVALID_NODEID



Page generated by Doxygen 1.8.8 for MRPT 1.2.2 SVN:Unversioned directory at Tue Oct 14 02:14:08 UTC 2014