void GraphAL::eraseEdge( size_t n1, size_t n2 ) { DAI_ASSERT( n1 < nrNodes() ); DAI_ASSERT( n2 < nrNodes() ); size_t iter; // Search for edge among neighbors of n1 for( iter = 0; iter < nb(n1).size(); iter++ ) if( nb(n1, iter).node == n2 ) { // Remove it nb(n1).erase( nb(n1).begin() + iter ); break; } // Change the iter and dual values of the subsequent neighbors for( ; iter < nb(n1).size(); iter++ ) { Neighbor &m = nb( n1, iter ); m.iter = iter; nb( m.node, m.dual ).dual = iter; } // Search for edge among neighbors of n2 for( iter = 0; iter < nb(n2).size(); iter++ ) if( nb(n2, iter).node == n1 ) { // Remove it nb(n2).erase( nb(n2).begin() + iter ); break; } // Change the iter and node values of the subsequent neighbors for( ; iter < nb(n2).size(); iter++ ) { Neighbor &m = nb( n2, iter ); m.iter = iter; nb( m.node, m.dual ).dual = iter; } }
void GraphAL::printDot( std::ostream& os ) const { os << "graph GraphAL {" << endl; os << "node[shape=circle,width=0.4,fixedsize=true];" << endl; for( size_t n = 0; n < nrNodes(); n++ ) os << "\tx" << n << ";" << endl; for( size_t n1 = 0; n1 < nrNodes(); n1++ ) foreach( const Neighbor &n2, nb(n1) ) if( n1 < n2 ) os << "\tx" << n1 << " -- x" << n2 << ";" << endl; os << "}" << endl; }
bool GraphAL::isConnected() const { if( nrNodes() == 0 ) { return true; } else { std::vector<bool> incomponent( nrNodes(), false ); incomponent[0] = true; bool found_new_nodes; do { found_new_nodes = false; // For all nodes, check if they are connected with the (growing) component for( size_t n1 = 0; n1 < nrNodes(); n1++ ) if( !incomponent[n1] ) { foreach( const Neighbor &n2, nb(n1) ) { if( incomponent[n2] ) { found_new_nodes = true; incomponent[n1] = true; break; } } } } while( found_new_nodes ); // Check if there are remaining nodes (not in the component) bool all_connected = true; for( size_t n1 = 0; (n1 < nrNodes()) && all_connected; n1++ ) if( !incomponent[n1] ) all_connected = false; return all_connected; // BGL implementation is slower... /* using namespace boost; typedef adjacency_list< vecS, vecS, undirectedS, property<vertex_distance_t, int> > boostGraphAL; typedef pair<size_t, size_t> E; // Copy graph structure into boostGraphAL object vector<E> edges; edges.reserve( nrEdges() ); for( size_t n1 = 0; n1 < nrNodes(); n1++ ) foreach( const Neighbor &n2, nb(n1) ) if( n1 < n2 ) edges.push_back( E( n1, n2 ) ); boostGraphAL g( edges.begin(), edges.end(), nrNodes() ); // Construct connected components using Boost GraphAL Library std::vector<int> component( num_vertices( g ) ); int num_comp = connected_components( g, make_iterator_property_map(component.begin(), get(vertex_index, g)) ); return (num_comp == 1); */ } }
bool GraphAL::isTree() const { typedef vector<Edge> levelType; // first is node, second is its parent vector<levelType> levels; if( nrNodes() == 0 ) return true; else { // start with root node 0 levels.push_back( levelType( 1, Edge( 0, 0 ) ) ); size_t treeSize = 1; bool foundCycle = false; do { levels.push_back( levelType() ); const levelType &prevLevel = levels[levels.size() - 2]; // build new level: add all neighbors of nodes in the previous level // (without backtracking), aborting if a cycle is detected for( size_t e = 0; e < prevLevel.size(); e++ ) { size_t n2 = prevLevel[e].first; // for all nodes n2 in the previous level foreach( const Neighbor &n1, nb(n2) ) { // for all neighbors n1 of n2 if( n1 != prevLevel[e].second ) { // no backtracking allowed for( size_t l = 0; l < levels.size() && !foundCycle; l++ ) for( size_t f = 0; f < levels[l].size() && !foundCycle; f++ ) if( levels[l][f].first == n1 ) // n1 has been visited before -> found a cycle foundCycle = true; if( !foundCycle ) // add n1 (and its parent n2) to current level levels.back().push_back( Edge( n1, n2 ) ); } if( foundCycle ) break; } if( foundCycle ) break; } treeSize += levels.back().size(); } while( (levels.back().size() != 0) && !foundCycle ); if( treeSize == nrNodes() && !foundCycle ) return true; else return false; } }
void GraphAL::eraseNode( size_t n ) { DAI_ASSERT( n < nrNodes() ); // Erase neighbor entry of node n _nb.erase( _nb.begin() + n ); // Adjust neighbor entries of nodes for( size_t n2 = 0; n2 < nrNodes(); n2++ ) { for( size_t iter = 0; iter < nb(n2).size(); ) { Neighbor &m = nb(n2, iter); if( m.node == n ) { // delete this entry, because it points to the deleted node nb(n2).erase( nb(n2).begin() + iter ); } else { // update this entry and the corresponding dual of the neighboring node if( m.node > n ) m.node--; nb( m.node, m.dual ).dual = iter; m.iter = iter++; } } } }
void GraphAL::checkConsistency() const { size_t N = nrNodes(); for( size_t n1 = 0; n1 < N; n1++ ) { size_t iter = 0; foreach( const Neighbor &n2, nb(n1) ) { DAI_ASSERT( n2.iter == iter ); DAI_ASSERT( n2.node < N ); DAI_ASSERT( n2.dual < nb(n2).size() ); DAI_ASSERT( nb(n2, n2.dual) == n1 ); iter++; } }
unsigned ConstraintTree::nrNodes (const CTNode* n) const { unsigned nr = 0; if (n->isLeaf() == false) { for (CTChilds::const_iterator chIt = n->childs().begin(); chIt != n->childs().end(); ++ chIt) { nr += nrNodes (*chIt); } } return nr; }