Radium Engine  1.5.20
Loading...
Searching...
No Matches
AdjacencyList.cpp
1#include <Core/Containers/AdjacencyList.hpp>
2
3#include <fstream>
4
5namespace Ra {
6namespace Core {
7
9AdjacencyList::AdjacencyList() : m_child(), m_parent() {}
10AdjacencyList::AdjacencyList( const uint n ) : m_child( n ), m_parent( n, -1 ) {}
12 m_child( adj.m_child ), m_parent( adj.m_parent ) {}
13
16
19 uint idx = size();
20 m_child.push_back( ChildrenList() );
21 m_parent.push_back( -1 );
22 m_level.push_back( 0 );
23 return idx;
24}
25
26uint AdjacencyList::addNode( const uint parent ) {
27 CORE_ASSERT( ( parent < size() ), "Index parent out of bounds" );
28 uint idx = size();
29 m_child.push_back( ChildrenList() );
30 m_parent.push_back( parent );
31 m_level.push_back( m_level[parent] + 1 );
32 m_child[parent].push_back( idx );
33 return idx;
34}
35
37 pruned.clear();
38 delete_flag.clear();
39 delete_flag.resize( this->size(), false );
40 std::vector<bool> prune_flag = delete_flag;
41 for ( uint i = 0; i < this->size(); ++i ) {
42 if ( this->isLeaf( i ) && !this->isRoot( i ) ) {
43 delete_flag[i] = true;
44 prune_flag[i] = true;
45 }
46 else { pruned.push_back( i ); }
47 }
48
49 for ( uint j = this->size(); j > 0; --j ) {
50 const uint i = j - 1;
51 if ( prune_flag[i] ) {
52 this->m_parent.erase( this->m_parent.begin() + i );
53 this->m_child.erase( this->m_child.begin() + i );
54 prune_flag.erase( prune_flag.begin() + i );
55 ++j;
56 }
57 }
58
59 for ( uint i = 0; i < this->size(); ++i ) {
60 this->m_parent[i] =
61 ( ( this->m_parent[i] == -1 ) || ( delete_flag[i] ) ) ? -1 : pruned[this->m_parent[i]];
62 for ( auto it = this->m_child[i].begin(); it != this->m_child[i].end(); ++it ) {
63 if ( delete_flag[( *it )] ) {
64 this->m_child[i].erase( it );
65 --it;
66 }
67 else { *it = pruned[*it]; }
68 }
69 }
70}
71
77
79 using Edge = Eigen::Matrix<uint, 2, 1>;
80 VectorArray<Edge> edgeList;
81
82 for ( uint i = 0; i < m_child.size(); ++i ) {
83 if ( include_leaf && isLeaf( i ) ) {
84 Edge e;
85 e( 0 ) = i;
86 e( 1 ) = i;
87 edgeList.push_back( e );
88 }
89 else {
90 for ( const auto& edge : m_child[i] ) {
91 Edge e;
92 e( 0 ) = i;
93 e( 1 ) = edge;
94 edgeList.push_back( e );
95 }
96 }
97 }
98 return edgeList;
99}
100
101AdjacencyList::ConsistencyStatus AdjacencyList::computeConsistencyStatus() const {
102 // Note: we abort at the first error found to keep the error backtrace
103 if ( m_parent.size() != m_child.size() ) {
104 return ConsistencyStatus::IncompatibleChildrenAndParentList;
105 }
106
107 for ( uint node = 0; node < size(); ++node ) {
108 if ( m_parent.at( node ) >= int( node ) ) { return ConsistencyStatus::WrongParentOrdering; }
109 if ( m_parent.at( node ) < -1 ) { return ConsistencyStatus::WrongParentIndex; }
110
111 for ( const auto& child : m_child.at( node ) ) {
112 if ( m_parent.at( child ) != int( node ) ) {
113 return ConsistencyStatus::InconsistentParentIndex;
114 }
115 }
116
117 if ( isLeaf( node ) != ( m_child.at( node ).size() == 0 ) ) {
118 return ConsistencyStatus::NonLeafNodeWithoutChild;
119 }
120 }
121 return ConsistencyStatus::Valid;
122}
123
124std::ofstream& operator<<( std::ofstream& ofs, const AdjacencyList& adj ) {
125 const std::string header { "ADJACENCYLIST\n" };
126 const std::string comment { "#ID PARENT nCHILDREN CHILDREN\n" };
127 const uint size = adj.size();
128
129 ofs << header + comment + std::to_string( size ) + "\n";
130 for ( uint i = 0; i < size; ++i ) {
131 uint c;
132 ofs << std::to_string( i ) + " " + std::to_string( adj.parents()[i] ) + " " +
133 std::to_string( c = adj.children()[i].size() );
134 for ( uint j = 0; j < c; ++j ) {
135 ofs << " " + std::to_string( adj.children()[i][j] );
136 }
137 ofs << "\n";
138 }
139 return ofs;
140}
141
142} // namespace Core
143} // namespace Ra
T at(T... args)
T begin(T... args)
AdjacencyList()
CONSTRUCTOR.
ConsistencyStatus computeConsistencyStatus() const
Return true if the graph is consistent.
uint size() const
Return the number of nodes in the graph.
void pruneLeaves()
Prune the leaves of the graph.
uint addRoot()
Return the index of the added root.
bool isLeaf(const uint i) const
Return true if the node is a leaf node.
bool isRoot(const uint i) const
Return true if a node is a root node.
VectorArray< Eigen::Matrix< uint, 2, 1 > > extractEdgeList(bool include_leaf=false) const
uint addNode(const uint parent)
Return the index of the added leaf.
This class implements ContainerIntrospectionInterface for AlignedStdVector.
T clear(T... args)
T end(T... args)
T erase(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
T push_back(T... args)
T resize(T... args)
T size(T... args)
T to_string(T... args)