Radium Engine  1.5.0
AdjacencyList.hpp
1 #pragma once
2 
3 #include <Core/Containers/AlignedStdVector.hpp>
4 #include <Core/Containers/VectorArray.hpp>
5 #include <Eigen/Core>
6 #include <iostream>
7 
8 namespace Ra {
9 namespace Core {
10 
11 using ParentList = AlignedStdVector<int>;
12 using LevelList = AlignedStdVector<uint8_t>;
13 using ChildrenList = AlignedStdVector<uint8_t>;
14 using Adjacency = AlignedStdVector<ChildrenList>;
15 
20 class RA_CORE_API AdjacencyList
21 {
22  public:
23  enum class ConsistencyStatus {
24  Valid,
25  IncompatibleChildrenAndParentList,
26  WrongParentOrdering,
27  WrongParentIndex,
28  InconsistentParentIndex,
29  NonLeafNodeWithoutChild
30  };
31 
33  // CONSTRUCTOR
35  AdjacencyList();
36  explicit AdjacencyList( const uint n );
37  AdjacencyList( const AdjacencyList& adj );
38  AdjacencyList& operator=( const AdjacencyList& ) = default;
39 
41  // DESTRUCTOR
43  ~AdjacencyList();
44 
46  // NODE
49  uint addRoot();
51  uint addNode( const uint parent );
53  void pruneLeaves( std::vector<uint>& pruned, std::vector<bool>& delete_flag );
55  void pruneLeaves();
64  VectorArray<Eigen::Matrix<uint, 2, 1>> extractEdgeList( bool include_leaf = false ) const;
65 
67  // SIZE
70  inline uint size() const;
72  inline void clear();
73 
75  // QUERY
78  ConsistencyStatus computeConsistencyStatus() const;
80  inline bool isEmpty() const { return ( size() == 0 ); }
82  inline bool isRoot( const uint i ) const;
84  inline bool isLeaf( const uint i ) const;
86  inline bool isBranch( const uint i ) const;
88  inline bool isJoint( const uint i ) const;
90  inline bool isEdge( const uint i, const uint j ) const;
91 
92  inline const Adjacency& children() const { return m_child; }
93 
94  inline const ParentList& parents() const { return m_parent; }
95 
97  // VARIABLE
99  private:
101  Adjacency m_child;
103  ParentList m_parent;
104  LevelList m_level;
105 };
106 
107 RA_CORE_API std::ofstream& operator<<( std::ofstream& ofs, const AdjacencyList& p );
108 
109 inline uint AdjacencyList::size() const {
110  CORE_ASSERT( m_parent.size() == m_child.size(), "List size inconsistency" );
111  return m_parent.size();
112 }
113 
114 inline void AdjacencyList::clear() {
115  m_child.clear();
116  m_parent.clear();
117 }
118 
119 inline bool AdjacencyList::isRoot( const uint i ) const {
120  CORE_ASSERT( i < size(), " Index i out of bounds " );
121  return ( m_parent[i] == -1 );
122 }
123 
124 inline bool AdjacencyList::isLeaf( const uint i ) const {
125  CORE_ASSERT( i < size(), " Index i out of bounds " );
126  return ( m_child[i].size() == 0 );
127 }
128 
129 inline bool AdjacencyList::isBranch( const uint i ) const {
130  CORE_ASSERT( i < size(), " Index i out of bounds " );
131  return ( m_child[i].size() > 1 );
132 }
133 
134 inline bool AdjacencyList::isJoint( const uint i ) const {
135  CORE_ASSERT( i < size(), " Index i out of bounds " );
136  return ( m_child[i].size() == 1 );
137 }
138 
139 inline bool AdjacencyList::isEdge( const uint i, const uint j ) const {
140  CORE_ASSERT( i < size(), " Index i out of bounds " );
141  CORE_ASSERT( j < size(), " Index j out of bounds " );
142  for ( const auto& item : m_child[i] ) {
143  if ( item == j ) return true;
144  }
145  return false;
146 }
147 } // namespace Core
148 } // namespace Ra
void clear()
Clear the vectors.
uint size() const
Return the number of nodes in the graph.
bool isJoint(const uint i) const
Return true if the node is a joint node. ( |child| == 1 )
bool isLeaf(const uint i) const
Return true if the node is a leaf node.
bool isBranch(const uint i) const
Return true if the node is a branch node. ( |child| > 1 )
bool isRoot(const uint i) const
Return true if a node is a root node.
bool isEmpty() const
Return true if the graph is empty.
bool isEdge(const uint i, const uint j) const
Return true if the edge { i, j } exists.
This class implements ContainerIntrospectionInterface for AlignedStdVector.
Definition: VectorArray.hpp:35
Definition: Cage.cpp:3