void dependency_tree::strong_connect( dependency_node *dnode ) { dnode->index = open_index; dnode->lowlink = open_index; ++open_index; connection_stack.push( dnode ); dnode->on_stack = true; for( std::vector<dependency_node *>::iterator it = dnode->parents.begin(); it != dnode->parents.end(); ++it ) { if( ( *it )->index < 0 ) { strong_connect( *it ); dnode->lowlink = std::min( dnode->lowlink, ( *it )->lowlink ); } else if( ( *it )->on_stack ) { dnode->lowlink = std::min( dnode->lowlink, ( *it )->index ); } } if( dnode->lowlink == dnode->index ) { std::vector<dependency_node *> scc; dependency_node *d; do { d = connection_stack.top(); scc.push_back( d ); connection_stack.pop(); d->on_stack = false; } while( dnode->key != d->key ); strongly_connected_components.push_back( scc ); dnode->on_stack = false; } }
// makes sure to set up Cycle errors properly! void dependency_tree::check_for_strongly_connected_components() { strongly_connected_components = std::vector<std::vector<dependency_node * > >(); open_index = 0; connection_stack = std::stack<dependency_node *>(); for( auto &elem : master_node_map ) { //nodes_on_stack = std::vector<dependency_node*>(); // clear it for the next stack to run if( elem.second.index < 0 ) { strong_connect( &elem.second ); } } // now go through and make a set of these std::set<dependency_node *> in_circular_connection; for( auto &elem : strongly_connected_components ) { if( elem.size() > 1 ) { for( auto &elem_node : elem ) { DebugLog( D_PEDANTIC_INFO, DC_ALL ) << "--" << elem_node->key.str() << "\n"; in_circular_connection.insert( elem_node ); } } } // now go back through this and give them all the circular error code! for( const auto &elem : in_circular_connection ) { ( elem )->all_errors[CYCLIC].push_back( "In Circular Dependency Cycle" ); } }
// makes sure to set up Cycle errors properly! void dependency_tree::check_for_strongly_connected_components() { strongly_connected_components = std::vector<std::vector<dependency_node * > >(); open_index = 0; connection_stack = std::stack<dependency_node *>(); for (std::map<std::string, dependency_node *>::iterator g = master_node_map.begin(); g != master_node_map.end(); ++g) { //nodes_on_stack = std::vector<dependency_node*>(); // clear it for the next stack to run if (g->second->index < 0) { strong_connect(g->second); } } // now go through and make a set of these std::set<dependency_node *> in_circular_connection; for (std::vector<std::vector<dependency_node *> >::iterator it = strongly_connected_components.begin(); it != strongly_connected_components.end(); ++it) { if (it->size() > 1) { for (std::vector<dependency_node *>::iterator node = it->begin(); node != it->end(); ++node) { DebugLog( D_PEDANTIC_INFO, DC_ALL ) << "--" << (*node)->key << "\n"; in_circular_connection.insert(*node); } } } // now go back through this and give them all the circular error code! for (std::set<dependency_node *>::iterator it = in_circular_connection.begin(); it != in_circular_connection.end(); ++it) { (*it)->all_errors[CYCLIC].push_back("In Circular Dependency Cycle"); } }
void dependency_tree::strong_connect(dependency_node *dnode) { dnode->index = open_index; dnode->lowlink = open_index; ++open_index; connection_stack.push(dnode); dnode->on_stack = true; for (int i = 0; i < dnode->parents.size(); ++i) { if (dnode->parents[i]->index < 0) { strong_connect(dnode->parents[i]); dnode->lowlink = std::min(dnode->lowlink, dnode->parents[i]->lowlink); } else if (dnode->parents[i]->on_stack) { dnode->lowlink = std::min(dnode->lowlink, dnode->parents[i]->index); } } if (dnode->lowlink == dnode->index) { std::vector<dependency_node *> scc; dependency_node *d; do { d = connection_stack.top(); scc.push_back(d); connection_stack.pop(); d->on_stack = false; } while (dnode->key != d->key); strongly_connected_components.push_back(scc); dnode->on_stack = false; } }
void strong_connect(const weighted_graf_t& graph, std::vector<std::vector<int>>& components, std::vector<int>& index, std::vector<int>& lowlink, std::vector<int>& stack, int ind, int v) { index[v] = ind; lowlink[v] = ind; ind++; stack.push_back(v); for (const auto& edge : graph[v]) { int w = edge.first; if (index[w] == 0) { strong_connect(graph, components, index, lowlink, stack, ind, w); lowlink[v] = std::min(lowlink[v], lowlink[w]); } else if (index[w] != -1) { lowlink[v] = std::min(lowlink[v], index[w]); } } if (lowlink[v] == index[v]) { // v is root node std::vector<int> component; int w; do { w = stack.back(); stack.pop_back(); component.push_back(w); index[w] = -1; } while (w != v); components.push_back(component); } }
std::vector<std::vector<int>> strongly_connected_components(const weighted_graf_t& graph) { int n = graph.size(), ind = 0; std::vector<int> index(n, 0), lowlink(n, 0), stack; std::vector<std::vector<int>> components; for (int i = 0; i < n; ++i) { if (index[i] == 0) strong_connect(graph, components, index, lowlink, stack, ind, i); } return components; }