src/GRAPHGEN/forest.cpp
// Removes duplicate trees inside the forest
Removes duplicate trees inside the forest
Removes duplicate trees inside the forest
bool LineForestHandler::RemoveTrees(bool(*FunctionPtr)(const BinaryDrag<conact>::node* n1, const BinaryDrag<conact>::node* n2), 
                         vector<size_t>& next_tree, 
                         BinaryDrag<conact>& f, 
                         bool are_end_trees, 
                         vector<size_t>& mapping) {
    bool found = false;
    for (size_t i = 0; i < next_tree.size() - 1; ++i) {
        if (next_tree[i] == i) {
            for (size_t j = i + 1; j < next_tree.size(); ++j) {
                if (next_tree[j] == j) {
                    if (FunctionPtr(f.roots_[i], f.roots_[j])) {
                        next_tree[j] = i;
                        found = true;
                        if (FunctionPtr == equivalent_trees) {
                            IntersectTrees(f.roots_[i], f.roots_[j]);
                        }
                    }
                }
            }
        }
    }
    if (!found)
        return false;
    size_t new_index = 0;
    for (size_t i = 0; i < next_tree.size(); ++i) {
        if (next_tree[i] == i) {
            next_tree[i] = new_index;
            ++new_index;
        }
        else {
            next_tree[i] = next_tree[next_tree[i]];
        }
    }
    new_index = 0;
    for (size_t i = 0; i < next_tree.size(); ++i) {
        if (next_tree[i] != new_index) {
            f.roots_[i] = nullptr;
        }
        else {
            ++new_index;
        }
    }
    f.roots_.erase(remove(begin(f.roots_), end(f.roots_), nullptr), end(f.roots_));
    if (are_end_trees) {
        for (size_t i = 0; i < mapping.size(); ++i) {
            mapping[i] = next_tree[mapping[i]];
        }
    }else{
        for (auto& r : f.roots_) {
            UpdateNext(r);
        }
    }
    next_tree.resize(f.roots_.size());
    iota(begin(next_tree), end(next_tree), 0);
    return true;
}
bool LineForestHandler :: RemoveTrees ( bool ( * FunctionPtr ) ( const BinaryDrag < conact > :: node * n1 , const BinaryDrag < conact > :: node * n2 ) , vector < size_t > & next_tree , BinaryDrag < conact > & f , bool are_end_trees , vector < size_t > & mapping ) { bool found = false ; for ( size_t i = 0 ; i < next_tree . size ( ) - 1 ; ++ i ) { if ( next_tree [ i ] == i ) { for ( size_t j = i + 1 ; j < next_tree . size ( ) ; ++ j ) { if ( next_tree [ j ] == j ) { if ( FunctionPtr ( f . roots_ [ i ] , f . roots_ [ j ] ) ) { next_tree [ j ] = i ; found = true ; if ( FunctionPtr == equivalent_trees ) { IntersectTrees ( f . roots_ [ i ] , f . roots_ [ j ] ) ; } } } } } } if ( ! found ) return false ; size_t new_index = 0 ; for ( size_t i = 0 ; i < next_tree . size ( ) ; ++ i ) { if ( next_tree [ i ] == i ) { next_tree [ i ] = new_index ; ++ new_index ; } else { next_tree [ i ] = next_tree [ next_tree [ i ] ] ; } } new_index = 0 ; for ( size_t i = 0 ; i < next_tree . size ( ) ; ++ i ) { if ( next_tree [ i ] != new_index ) { f . roots_ [ i ] = nullptr ; } else { ++ new_index ; } } f . roots_ . erase ( remove ( begin ( f . roots_ ) , end ( f . roots_ ) , nullptr ) , end ( f . roots_ ) ) ; if ( are_end_trees ) { for ( size_t i = 0 ; i < mapping . size ( ) ; ++ i ) { mapping [ i ] = next_tree [ mapping [ i ] ] ; } } else { for ( auto & r : f . roots_ ) { UpdateNext ( r ) ; } } next_tree . resize ( f . roots_ . size ( ) ) ; iota ( begin ( next_tree ) , end ( next_tree ) , 0 ) ; return true ; }
Removes duplicate trees inside the forest
Removes duplicate trees inside the forest
// Find which trees are identical and mark them in next_tree // Flatten the trees indexes // Remove roots that are now useless // If we are dealing with end trees then we need to update the  // mapping main-end trees because it changed // If we are dealing with main trees then we need to update the  // id of the next tree because they changed