/*! Returns a topologically sorted image list. If \a image is non-NULL, an array containing the image and all its transitive dependencies is returned. If \a image is NULL, all loaded images are returned. In either case dependencies are listed before images depending on them. \param image The image specifying the tree of images that shall be sorted. If NULL, all loaded images are sorted. \param _list On success it will be set to an array of the sorted images. The caller is responsible for free()ing it. \param sortFlags The image flag that shall be used for sorting. Images that already have this flag set are ignored (and their dependencies, unless they are also reachable via another path). The flag will be set on all returned images. \return The number of images in the returned array or an error code on failure. */ ssize_t get_sorted_image_list(image_t* image, image_t*** _list, uint32 sortFlag) { image_t** list; list = (image_t**)malloc(sLoadedImageCount * sizeof(image_t*)); if (list == NULL) { FATAL("memory shortage in get_sorted_image_list()"); *_list = NULL; return B_NO_MEMORY; } memset(list, 0, sLoadedImageCount * sizeof(image_t*)); *_list = list; if (image != NULL) return topological_sort(image, 0, list, sortFlag); // no image given -- sort all loaded images uint32 count = 0; image = sLoadedImages.head; while (image != NULL) { count = topological_sort(image, count, list, sortFlag); image = image->next; } return count; }
static int topological_sort(int node_id) { EG_PATH_PTR path_ptr; EG_NODE_PTR *children; int k,len; EG_NODE_PTR child_ptr; expl_graph[node_id]->visited = 2; UPDATE_MIN_MAX_NODE_NOS(node_id); path_ptr = expl_graph[node_id]->path_ptr; while (path_ptr != NULL) { children = path_ptr->children; len = path_ptr->children_len; for (k = 0; k < len; k++) { child_ptr = children[k]; if (child_ptr->visited == 2 && error_on_cycle) RET_ERR(err_cycle_detected); if (child_ptr->visited == 0) { RET_ON_ERR(topological_sort(child_ptr->id)); expand_sorted_egraph(index_to_sort + 1); sorted_expl_graph[index_to_sort++] = child_ptr; } child_ptr->shared += 1; } path_ptr = path_ptr->next; } expl_graph[node_id]->visited = 1; return BP_TRUE; }
int sort_one_egraph(int root_id, int root_index, int count) { roots[root_index] = (ROOT)MALLOC(sizeof(struct ObservedFactNode)); roots[root_index]->id = root_id; roots[root_index]->count = count; if (expl_graph[root_id]->visited == 1) { /* * This top-goal is also a sub-goal of another top-goal. This * should occur only when INIT_VISITED_FLAGS is suppressed * (i.e. we have more than one observed goal in learning). */ if (suppress_init_flags) return BP_TRUE; } if (expl_graph[root_id]->visited != 0) RET_INTERNAL_ERR; RET_ON_ERR(topological_sort(root_id)); expand_sorted_egraph(index_to_sort + 1); sorted_expl_graph[index_to_sort] = expl_graph[root_id]; index_to_sort++; sorted_egraph_size = index_to_sort; /* initialize flags after use */ if (!suppress_init_flags) INIT_VISITED_FLAGS; return BP_TRUE; }
int main() { int nodes; int **graph; int i, j; char data[256]; int row, col; char *ptr; int *indegree; gets(data); nodes = atoi((const char *)strtok(data, " ")); indegree = malloc(sizeof(*indegree) * nodes); graph = malloc(sizeof(*graph) * nodes); for (i = 0; i < nodes; i++) { graph[i] = malloc(sizeof(**graph) * nodes); for (j = 0; j < nodes; j++) graph[i][j] = 0; } for (i = 0; i < nodes; i++) { gets(data); row = atoi((const char *)strtok(data, " ")); while ((ptr = strtok(NULL, " ")) != NULL) { graph[row][atoi(ptr)] = 1; indegree[atoi(ptr)]++; } } // print(graph, nodes); topological_sort(graph, indegree, nodes); }
int main() { int N; int k; int d; int scnt, i, j; scanf("%d %d", &N, &k); for (i = 1; i <= k; i++) { scanf("%d", &scnt); for (j = 1; j <= scnt; j++) { scanf("%d", &d); insert_edge(i, d); incoming[d]++; dprintf("%d to incoming[%d] : %d\n", i, d, incoming[d]); } } start = end = 0; j = 1; while (incoming[j++]); j--; int boss = j; for (; j <= k; j++) if (incoming[j] == 0) queue[end++] = j; for (; j <= N; j++) if (incoming[j] == 0) parent[j] = boss; topological_sort(); for (i = 1; i <= N; i++) printf("%d\n", parent[i]); return 0; }
TEST(TopologicalSortTest, Arbitrary) { vector<vector<int>> graf = {{}, {}, {}, {}}; vector<int> expect({0, 1, 2, 3}); vector<int> result = topological_sort(graf); std::sort(result.begin(), result.end()); EXPECT_EQ(expect, result); }
coda topological_sort_SelfTest(graph Gin){ graph G=graphInit(9, GRAPH_IS_ORIENTED); for (int i=1; i<10; graphAddNode(G, i, NULL), i++); //graphAddArch(G, 0, 1, NULL); graphAddArch(G, 1, 2, NULL); graphAddArch(G, 2, 8, NULL); graphAddArch(G, 3, 2, NULL); graphAddArch(G, 3, 7, NULL); graphAddArch(G, 7, 8, NULL); graphAddArch(G, 4, 5, NULL); coda C=topological_sort(G); coda_iterator I=codaIteratorInit(C, NULL, FORWARD_ITERATION); int x; while ((x=coda_NextNum(I))!=CODA_ITERATION_END) printf(">%d\n",(int)x); codaIteratorFree(I); puts("\n ---------\n"); return NULL; }
LIST * order( FRAME * frame, int flags ) { LIST * arg = lol_get( frame->args, 0 ); LIST * result = L0; int src; LISTITER iter = list_begin( arg ); LISTITER const end = list_end( arg ); /* We need to create a graph of order dependencies between the passed * objects. We assume there are no duplicates passed to 'add_pair'. */ int length = list_length( arg ); int * * graph = ( int * * )BJAM_CALLOC( length, sizeof( int * ) ); int * order = ( int * )BJAM_MALLOC( ( length + 1 ) * sizeof( int ) ); for ( src = 0; iter != end; iter = list_next( iter ), ++src ) { /* For all objects this one depends upon, add elements to 'graph'. */ LIST * dependencies = var_get( frame->module, list_item( iter ) ); int index = 0; LISTITER dep_iter = list_begin( dependencies ); LISTITER const dep_end = list_end( dependencies ); graph[ src ] = ( int * )BJAM_CALLOC( list_length( dependencies ) + 1, sizeof( int ) ); for ( ; dep_iter != dep_end; dep_iter = list_next( dep_iter ) ) { int const dst = list_index( arg, list_item( dep_iter ) ); if ( dst != -1 ) graph[ src ][ index++ ] = dst; } graph[ src ][ index ] = -1; } topological_sort( graph, length, order ); { int index = length - 1; for ( ; index >= 0; --index ) { int i; LISTITER iter = list_begin( arg ); LISTITER const end = list_end( arg ); for ( i = 0; i < order[ index ]; ++i, iter = list_next( iter ) ); result = list_push_back( result, object_copy( list_item( iter ) ) ); } } /* Clean up */ { int i; for ( i = 0; i < length; ++i ) BJAM_FREE( graph[ i ] ); BJAM_FREE( graph ); BJAM_FREE( order ); } return result; }
LIST *order( PARSE *parse, FRAME *frame ) { LIST* arg = lol_get( frame->args, 0 ); LIST* tmp; LIST* result = 0; int src, dst; /* We need to create a graph of order dependencies between the passed objects. We assume that there are no duplicates passed to 'add_pair'. */ int length = list_length(arg); int** graph = (int**)calloc(length, sizeof(int*)); int* order = (int*)malloc((length+1)*sizeof(int)); if ( DEBUG_PROFILE ) profile_memory( length*sizeof(int*) + (length+1)*sizeof(int) ); for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) { /* For all object this one depend upon, add elements to 'graph' */ LIST* dependencies = var_get(tmp->string); int index = 0; graph[src] = (int*)calloc(list_length(dependencies)+1, sizeof(int)); if ( DEBUG_PROFILE ) profile_memory( (list_length(dependencies)+1)*sizeof(int) ); for(; dependencies; dependencies = dependencies->next) { int dst = list_index(arg, dependencies->string); if (dst != -1) graph[src][index++] = dst; } graph[src][index] = -1; } topological_sort(graph, length, order); { int index = length-1; for(; index >= 0; --index) { int i; tmp = arg; for (i = 0; i < order[index]; ++i, tmp = tmp->next); result = list_new(result, tmp->string); } } /* Clean up */ { int i; for(i = 0; i < length; ++i) free(graph[i]); free(graph); free(order); } return result; }
int main(){ Graph G = DAG_toy_ex(); vector<Vertex> c; // container topological_sort(G, back_inserter(c)); cout << "A topological ordering: "; for ( vector<Vertex>::reverse_iterator ii=c.rbegin(); ii!=c.rend(); ++ii) cout << (*ii) << " "; cout << endl; }
void PhyEngine::threadLoop() { //Do a topological sort of the graph (sorts in reverse topological order) vector<unsigned> revTopoOrder; topological_sort(engineGraph_, back_inserter(revTopoOrder), b::vertex_index_map(b::identity_property_map())); //The main loop of this engine thread try{ while(true) { b::this_thread::interruption_point(); //Check message queue for ReconfigSets ReconfigSet currentReconfigSet; while(reconfigQueue_.tryPop(currentReconfigSet)) { vector< ParametricReconfig >::iterator paramIt; for(paramIt = currentReconfigSet.paramReconfigs.begin(); paramIt != currentReconfigSet.paramReconfigs.end(); ++paramIt) { reconfigureParameter(*paramIt); } } //Go through components in topological order for(vector<unsigned>::reverse_iterator i = revTopoOrder.rbegin(); i != revTopoOrder.rend(); ++i) { if(i == revTopoOrder.rbegin()) //First component in the graph { components_[*i]->doProcess(); } else { InEdgeIterator edgeIt, edgeItEnd; for(b::tie(edgeIt, edgeItEnd) = in_edges(*i, engineGraph_); edgeIt != edgeItEnd; ++edgeIt) { //If there's data available in an input buffer, process it while( engineGraph_[*edgeIt].theBuffer->hasData() ) { components_[*i]->doProcess(); } } } } } } catch(IrisException& ex) { LOG(LFATAL) << "Error in engine " << engineName_ << ": " << ex.what() << " - Engine thread exiting."; } catch(b::thread_interrupted&) { LOG(LINFO) << "Thread in Engine " << engineName_ << " interrupted"; } }
LIST *order( FRAME *frame, int flags ) { LIST* arg = lol_get( frame->args, 0 ); LIST* tmp; LIST* result = 0; int src; /* We need to create a graph of order dependencies between the passed objects. We assume that there are no duplicates passed to 'add_pair'. */ int length = list_length(arg); int** graph = (int**)BJAM_CALLOC(length, sizeof(int*)); int* order = (int*)BJAM_MALLOC((length+1)*sizeof(int)); for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) { /* For all object this one depend upon, add elements to 'graph' */ LIST* dependencies = var_get(tmp->value); int index = 0; graph[src] = (int*)BJAM_CALLOC(list_length(dependencies)+1, sizeof(int)); for(; dependencies; dependencies = dependencies->next) { int dst = list_index(arg, dependencies->value); if (dst != -1) graph[src][index++] = dst; } graph[src][index] = -1; } topological_sort(graph, length, order); { int index = length-1; for(; index >= 0; --index) { int i; tmp = arg; for (i = 0; i < order[index]; ++i, tmp = tmp->next); result = list_new(result, object_copy(tmp->value)); } } /* Clean up */ { int i; for(i = 0; i < length; ++i) BJAM_FREE(graph[i]); BJAM_FREE(graph); BJAM_FREE(order); } return result; }
// method finds maximum-weight path in graph void Graph::generate_consensus(string *pconsensus) { auto& consensus = *pconsensus; vector<int> next_node(nodes_.size(), -1); vector<int> dp(nodes_.size(), -1); int max_weight = numeric_limits<int>::min(); int start_node_id = -1; // topological sort on reverse graph if (!is_sorted) { topological_sort(); } reverse(nodes_order_.begin(), nodes_order_.end()); // now no node is visited before all its children are visited // when iterating over nodes for (auto id : nodes_order_) { auto& node = nodes_[id]; const Edges& out_edges = node->getOutEdges(); if (out_edges.empty()) { // if the node has no outgoing edges, weight of heaviest // path starting at that node is zero: d(u) = 0 dp[id] = 0; next_node[id] = id; } else { // otherwise, for each outgoing edge(u, v) compute w(e) + d(v) // and set d(u) to be the largest value attained this way for (auto& e : out_edges) { int weight = e.second->getLabels().size(); if (weight + dp[e.first] > dp[id]) { dp[id] = weight + dp[e.first]; next_node[id] = e.first; } } // update max if (dp[id] > max_weight) { max_weight = dp[id]; start_node_id = id; } } } // generate consensus sequence int curr_id = start_node_id; while (curr_id != next_node[curr_id]) { consensus += nodes_[curr_id]->base(); curr_id = next_node[curr_id]; } consensus += nodes_[curr_id]->base(); }
int main () { struct digraph *G = new_digraph (5); struct digraph *tc_G; /* make a funny digraph */ insert_edge (G, 0, 1); insert_edge (G, 1, 2); //insert_edge (G, 2, 3); insert_edge (G, 3, 4); insert_edge (G, 4, 0); /* is the digraph connected? */ if (is_connected (G)) printf ("connected!\n"); else printf ("not connected!\n"); /* print the adjacency matrix */ printf ("adjacency matrix for G:\n"); print_adj_matrix (G); /* find the transitive closure */ tc_G = Warshall (G); /* print the adjacency matrix for the transitive closure */ printf ("adjacency matrix for transitive closure of G:\n"); print_adj_matrix (tc_G); //return 0; /* make a funny DAG */ struct digraph *H = new_digraph (7); insert_edge (H, 3, 4); insert_edge (H, 4, 2); insert_edge (H, 3, 5); insert_edge (H, 5, 2); insert_edge (H, 2, 6); insert_edge (H, 5, 3); insert_edge (H, 6, 1); insert_edge (H, 6, 0); printf ("adjacency matrix for H:\n"); print_adj_matrix (H); if (is_connected (H)) printf ("connected!\n"); else printf ("not connected!\n"); topological_sort (H, 3); //return 0; struct digraph *tc_H = Warshall (H); printf ("transitive closure of H is:\n"); print_adj_matrix (tc_H); return 0; }
void Internal_Graph::topological() { if(c != NULL) { delete c; } c = new container(); topological_sort(this->g, std::back_inserter(*c)); // std::cout << "A topological ordering: "; // for ( container::iterator ii=c->begin(); ii!=c->end(); ++ii) // std::cout << ((*NodeMap)[*ii])->getName() << " "; // std::cout << std::endl; }
int main(int argc, char **argv) { int i; char str[MAX_NUM]; while(scanf("%d %d", &n, &m)!=EOF) { for(i=0; i<n; i++) scanf("%s", map[i]); build_graph(); memset(str, 0, sizeof(str)); memset(visited, 0, sizeof(visited)); topological_sort(str, 0); } }
bool PEDIGREE_GRAPH::build(std::string filename) { std::ifstream input(filename.c_str()); if (!input.is_open()) printErrorAndDie("Failed to open pedigree file " + filename); std::map<std::string, PEDIGREE_NODE*> samples; std::vector<PEDIGREE_NODE*> nodes; std::string line; //std::getline(input, line)); // TO DO: Fix weird expection that occurs if I try to skip header while (std::getline(input, line)){ std::istringstream iss(line); std::string family, child, father, mother; if(! (iss >> family >> child >> father >> mother)) printErrorAndDie("Improperly formated .ped pedigree file " + filename); if (child.compare("0") == 0) printErrorAndDie("Invalid individual id " + child); // Create new nodes for any previously unseen samples that have // an identifier other than 0 if (samples.find(child) == samples.end()){ PEDIGREE_NODE* new_node = new PEDIGREE_NODE(child); nodes.push_back(new_node); samples[child] = new_node; } if (mother.compare("0") != 0 && samples.find(mother) == samples.end()){ PEDIGREE_NODE* new_node = new PEDIGREE_NODE(mother); samples[father] = new_node; nodes.push_back(new_node); } if (father.compare("0") != 0 && samples.find(father) == samples.end()){ PEDIGREE_NODE* new_node = new PEDIGREE_NODE(father); samples[mother] = new_node; nodes.push_back(new_node); } // Store relationships in node instance PEDIGREE_NODE* child_node = samples.find(child)->second; PEDIGREE_NODE* mother_node = (mother.compare("0") == 0 ? NULL : samples.find(mother)->second); PEDIGREE_NODE* father_node = (father.compare("0") == 0 ? NULL : samples.find(father)->second); child_node->set_mother(mother_node); child_node->set_father(father_node); if (mother_node != NULL) mother_node->add_child(child_node); if (father_node != NULL) father_node->add_child(child_node); } input.close(); // Sort nodes in pedigree graph topologically return topological_sort(nodes); }
static uint32 topological_sort(image_t* image, uint32 slot, image_t** initList, uint32 sortFlag) { if (image->flags & sortFlag) return slot; image->flags |= sortFlag; /* make sure we don't visit this one */ for (uint32 i = 0; i < image->num_needed; i++) slot = topological_sort(image->needed[i], slot, initList, sortFlag); initList[slot] = image; return slot + 1; }
CondensationOut build_condensation() { std::vector< Vertex > top_sort = topological_sort(); in_sort.clear(); out_sort.clear(); used.clear(); std::for_each(top_sort.rbegin(), top_sort.rend(), [&cond, &used, &in_sort, this] (const Vertex &v) { if (used.find(v) == used.end()) { this->dfs< Transposed >(v); cond.push_back(vSet(in_sort.begin(), in_sort.end())); in_sort.clear(); } }); return cond; }
int main() { //adjacence_list_t graph = { { 2 }, { 1, 3, 4, 5 }, { 2, 4 }, { 2, 3, 5 }, { 2, 4, 6 }, { 5 } }; //adjacence_list_t graph = { { 2 }, { 1, 3, 5 }, { 2 }, { 5 }, { 2, 4, 6 }, { 5 }, {} }; //adjacence_list_t graph = { { 4 }, {}, { 2 }, { 2, 3, 1 } }; // 1 // ↓ // 4 → 3 // ↓ ↓ // 2 adjacence_list_t graph = { { 4 }, {}, { 2 }, { 2, 3 } }; for ( auto& v : graph ) for ( auto& i : v ) --i; { const size_t vi = 4; std::cout << "dfs from " << vi << " : "; auto dfs_res = dfs( graph, vi - 1 ); if ( dfs_res.first ) { for ( auto& v : dfs_res.second ) std::cout << v + 1 << " "; std::cout << std::endl; } else std::cout << "Cycle detected!" << std::endl; } { std::cout << "topological_sort: "; auto topo_sort = topological_sort( graph ); if ( topo_sort.first ) { for ( auto& v : topo_sort.second ) std::cout << v + 1 << " "; std::cout << std::endl; } else std::cout << "Cycle detected!" << std::endl; } }
ssize_t get_sorted_image_list(image_t* image, image_t*** _list, uint32 sortFlag) { image_t** list; list = (image_t**)malloc(sLoadedImageCount * sizeof(image_t*)); if (list == NULL) { FATAL("memory shortage in get_sorted_image_list()"); *_list = NULL; return B_NO_MEMORY; } memset(list, 0, sLoadedImageCount * sizeof(image_t*)); *_list = list; return topological_sort(image, 0, list, sortFlag); }
CondensationOut build_condensation() { std::vector< Vertex > top_sort = topological_sort(); in_sort.clear(); out_sort.clear(); used.clear(); cond.clear(); for (auto v = top_sort.rbegin(); v != top_sort.rend(); ++v) { if (used.find(v) == used.end()) { this->dfs< Transposed >(v); cond.push_back(vSet(in_sort.begin(), in_sort.end())); in_sort.clear(); } } return cond; }
inline void dag_shortest_paths (const VertexListGraph& g, typename graph_traits<VertexListGraph>::vertex_descriptor s, DistanceMap distance, WeightMap weight, ColorMap color, PredecessorMap pred, DijkstraVisitor vis, Compare compare, Combine combine, DistInf inf, DistZero zero) { typedef typename graph_traits<VertexListGraph>::vertex_descriptor Vertex; std::vector<Vertex> rev_topo_order; rev_topo_order.reserve(num_vertices(g)); topological_sort(g, std::back_inserter(rev_topo_order)); typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end; for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { put(distance, *ui, inf); put(pred, *ui, *ui); } put(distance, s, zero); vis.discover_vertex(s, g); std::vector<Vertex>::reverse_iterator i; for (i = rev_topo_order.rbegin(); i != rev_topo_order.rend(); ++i) { Vertex u = *i; vis.examine_vertex(u, g); typename graph_traits<VertexListGraph>::out_edge_iterator e, e_end; for (tie(e, e_end) = out_edges(u, g); e != e_end; ++e) { vis.discover_vertex(target(*e, g), g); bool decreased = relax(*e, g, weight, pred, distance, combine, compare); if (decreased) vis.edge_relaxed(*e, g); else vis.edge_not_relaxed(*e, g); } vis.finish_vertex(u, g); } }
int main(){ struct graph g; int directed = 0; init_graph(&g, directed); scanf("%d %d", &(g.num_vertices), &(g.num_edges)); int i = 0; for(; i < g.num_edges; i++){ int x = 0, y =0; scanf("%d %d", &x, &y); insert_edge(&g, x, y, directed); } for(i=1; i < MAX_VERTICES+1; i++){ processed[i] = 0; parent[i] = -1; discovered[i] = 0; entry_time[i] = 0; exit_time[i] = 0; } topological_sort(&g); exit(0); }
vector<int> Graph::max_distances(int source) { /* *Renvoie la distance maximale de la source à chaque sommet. *L'algorithme est une version modifiée de la procédure de recherche de la distance minimale dans un graph acyclique * Bellman Ford *graphe orienté - modification consiste à transformer les +INF à 0 et min au max. */ int n = vertices_number; vector<int> distance; distance.resize(n); deque<int> topo = topological_sort(); distance[topo[0]] = 0; for (int j=1; j<n; j++) distance[topo[j]] = 0; for (int j=1; j<n; j++) { for (int i=0; i<incoming_arcs[topo[j]].size(); i++) { int a = distance[topo[j]]; int b = distance[incoming_arcs[topo[j]][i].vertex_id]; Arc arc = get_arc(incoming_arcs[topo[j]][i].vertex_id, topo[j]); int c = arc.length; distance[topo[j]] = max(a, b + c); } } debug("max distances from %d to 0..%d respectively:\n", source, n-1); for (int i=0; i<n; i++) debug("%d ", distance[i]); debug("\n"); return distance; }
status traverse_graph( graph G, searchorder order, status ( *p_func_f )()) { status rc ; bool *visited; int vertex_cnt, edge_cnt, i; graph_size( G, &vertex_cnt, &edge_cnt ) ; visited = ( bool* )malloc( vertex_cnt * sizeof( bool )) ; if( visited == NULL ) return ERROR ; for( i = 0 ; i < vertex_cnt ; i++ ) visited[i] = FALSE ; for( rc = OK, i = 0 ; i < vertex_cnt && rc == OK ; i++ ) { if( visited[i] == FALSE ) { switch( order ) { case DEPTH_FIRST: rc = depth_first_search( G, i, visited, p_func_f ) ; break ; case BREADTH_FIRST: break ; case TOPOLOGICAL: rc = topological_sort( G, vertex_cnt, p_func_f ) ; i = vertex_cnt ; break ; } } } free( visited ) ; return rc ; }
void topological_sort(char *str, int level) { int i, j; if(level == num) { printf("%s\n", str); return; } for(i=0; i<MAX_NUM; i++) { if(in[i]==0 && !visited[i]) { str[level] = 'A'+i; visited[i] = 1; for(j=0; j<MAX_NUM; j++) if(adj[i][j]) --in[j]; topological_sort(str, level+1); visited[i] = 0; for(j=0; j<MAX_NUM; j++) if(adj[i][j]) ++in[j]; } } }
transitive_reduction(const Graph& g, GraphTR& tr, G_to_TR_VertexMap g_to_tr_map, VertexIndexMap g_index_map ) { typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename graph_traits<Graph>::vertex_iterator VertexIterator; typedef typename std::vector<Vertex>::size_type size_type; std::vector<Vertex> topo_order; topological_sort(g, std::back_inserter(topo_order)); std::vector<size_type> topo_number_storage(num_vertices(g)); iterator_property_map<size_type*, VertexIndexMap, size_type, size_type&> topo_number( &topo_number_storage[0], g_index_map ); { typename std::vector<Vertex>::reverse_iterator it = topo_order.rbegin(); size_type n = 0; for(; it != topo_order.rend(); ++it,++n ) { topo_number[ *it ] = n; } } std::vector< std::vector< bool > > edge_in_closure(num_vertices(g), std::vector<bool>( num_vertices(g), false)); { typename std::vector<Vertex>::reverse_iterator it = topo_order.rbegin(); for( ; it != topo_order.rend(); ++it ) { g_to_tr_map[*it] = add_vertex(tr); } } typename std::vector<Vertex>::iterator it = topo_order.begin(), end = topo_order.end(); for( ; it != end; ++it ) { size_type i = topo_number[ *it ]; edge_in_closure[i][i] = true; std::vector<Vertex> neighbors; //I have to collect the successors of *it and traverse them in //ascending topological order. I didn't know a better way, how to //do that. So what I'm doint is, collection the successors of *it here { typename Graph::out_edge_iterator oi,oi_end; for( tie(oi, oi_end) = out_edges( *it, g ); oi != oi_end; ++oi ) { neighbors.push_back( target( *oi, g ) ); } } { //and run through all vertices in topological order typename std::vector<Vertex>::reverse_iterator rit = topo_order.rbegin(); rend = topo_order.rend(); for(; rit != rend; ++rit ) { //looking if they are successors of *it if( std::find( neighbors.begin(), neighbors.end(), *rit) != neighbors.end() ) { size_type j = topo_number[ *rit ]; if( not edge_in_closure[i][j] ) { for(size_type k = j; k < num_vertices(g); ++k) { if( not edge_in_closure[i][k] ) { //here we need edge_in_closure to be in topological order, edge_in_closure[i][k] = edge_in_closure[j][k]; } } //therefore we only access edge_in_closure only through //topo_number property_map add_edge(g_to_tr_map[*it], g_to_tr_map[*rit], tr); } //if ( not edge_in_ } //if (find ( } //for( typename vector<Vertex>::reverse_iterator } // { } //for( typename vector<Vertex>::iterator } //void transitive_reduction
const vector<uint32_t>& Graph::getNodesIds() { if (!is_sorted) { topological_sort(); } return nodes_order_; }
Graph::Graph(const string& seq, const string& label): next_id_(0), is_sorted(true) { addUnmatchedSequence(seq, label, true); topological_sort(); }