void topological_sort(VertexListGraph& g, OutputIterator result, const bgl_named_params<P, T, R>& params) { typedef topo_sort_visitor<OutputIterator> TopoVisitor; depth_first_search(g, params.visitor(TopoVisitor(result))); }
static void build_domains(Postprocessor *pp, Linkage sublinkage) { size_t link, i, d; const char *s; pp->pp_data.N_domains = 0; for (link = 0; link<sublinkage->num_links; link++) { assert (sublinkage->link_array[link].lw != SIZE_MAX); if (NULL == sublinkage->link_array[link].link_name) continue; s = sublinkage->link_array[link].link_name; if (pp_linkset_match(pp->knowledge->ignore_these_links, s)) continue; if (pp_linkset_match(pp->knowledge->domain_starter_links, s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); if (pp_linkset_match(pp->knowledge->domain_contains_links, s)) add_link_to_domain(pp, link); depth_first_search(pp, sublinkage, sublinkage->link_array[link].rw, sublinkage->link_array[link].lw, link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS, "raise value of PP_MAX_DOMAINS"); } else if (pp_linkset_match(pp->knowledge->urfl_domain_starter_links, s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); /* always add the starter link to its urfl domain */ add_link_to_domain(pp, link); bad_depth_first_search(pp, sublinkage,sublinkage->link_array[link].rw, sublinkage->link_array[link].lw, link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS,"raise PP_MAX_DOMAINS value"); } else if (pp_linkset_match(pp->knowledge->urfl_only_domain_starter_links, s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); /* do not add the starter link to its urfl_only domain */ d_depth_first_search(pp, sublinkage, sublinkage->link_array[link].lw, sublinkage->link_array[link].lw, sublinkage->link_array[link].rw, link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS,"raise PP_MAX_DOMAINS value"); } else if (pp_linkset_match(pp->knowledge->left_domain_starter_links, s)) { setup_domain_array(pp, pp->pp_data.N_domains, s, link); /* do not add the starter link to a left domain */ left_depth_first_search(pp, sublinkage, sublinkage->link_array[link].lw, sublinkage->link_array[link].rw, link); pp->pp_data.N_domains++; assert(pp->pp_data.N_domains<PP_MAX_DOMAINS,"raise PP_MAX_DOMAINS value"); } } /* sort the domains by size */ qsort((void *) pp->pp_data.domain_array, pp->pp_data.N_domains, sizeof(Domain), (int (*)(const void *, const void *)) domain_compare); /* sanity check: all links in all domains have a legal domain name */ for (d = 0; d < pp->pp_data.N_domains; d++) { i = find_domain_name(pp, pp->pp_data.domain_array[d].string); if (i == SIZE_MAX) prt_error("Error: post_process(): Need an entry for %s in LINK_TYPE_TABLE", pp->pp_data.domain_array[d].string); pp->pp_data.domain_array[d].type = i; } }
int biconnected(network *n, int *compnodes, int *compdemands, double *compcuts) { int i, vertnum = n->vertnum; vertex *verts = n->verts; elist *e; int count1 = 0, count2 = 0; int num_comps = 0; char is_art_point; verts[0].scanned = TRUE; verts[0].comp = 0; for (i=1; i<vertnum; i++) verts[i].scanned = FALSE; for(i = 1; i < vertnum; i++){ if (!verts[i].scanned){ is_art_point = FALSE; verts[i].low = verts[i].dfnumber = ++count1; verts[i].scanned = TRUE; e = verts[i].first; if (!e->other_end){ if (e->next_edge) e = e->next_edge; else continue; } e->data->tree_edge = TRUE; depth_first_search(e->other, &count1, &count2); is_art_point = e->other->is_art_point; for(e = e->next_edge; e; e = e->next_edge){ if (!e->other_end) continue; if (!e->other->scanned){ is_art_point = TRUE; e->data->tree_edge = TRUE; depth_first_search(e->other, &count1, &count2); } } verts[i].is_art_point = is_art_point; } } for (i=1; i<vertnum; i++) verts[i].scanned = FALSE; for (i = 1; i < vertnum; i++){ if (!verts[i].scanned){ verts[i].scanned = TRUE; verts[i].comp = ++num_comps; for (e = verts[i].first;e; e = e->next_edge){ if (!e->other_end) continue; if (!e->other->scanned) compute_comp_nums(e->other, verts[i].comp, &num_comps, verts[i].is_art_point); } } } for (i = 1; i < vertnum; i++){ compnodes[verts[i].comp]++; compdemands[verts[i].comp] += verts[i].demand; for (e = verts[i].first; e; e = e->next_edge){ if (e->other->comp != verts[i].comp) compcuts[verts[i].comp] += e->data->weight; } } return (num_comps); }
int main() { graph_link gl; init_graph(&gl); insert_vertex(&gl, 'A'); insert_vertex(&gl, 'B'); insert_vertex(&gl, 'C'); insert_vertex(&gl, 'D'); insert_vertex(&gl, 'E'); insert_vertex(&gl, 'F'); insert_vertex(&gl, 'G'); insert_vertex(&gl, 'H'); insert_vertex(&gl, 'I'); insert_vertex(&gl, 'J'); insert_vertex(&gl, 'K'); insert_vertex(&gl, 'L'); insert_vertex(&gl, 'M'); insert_edge(&gl, 'A', 'B'); insert_edge(&gl, 'A', 'C'); insert_edge(&gl, 'A', 'F'); insert_edge(&gl, 'A', 'L'); insert_edge(&gl, 'B', 'M'); insert_edge(&gl, 'L', 'J'); insert_edge(&gl, 'L', 'M'); insert_edge(&gl, 'J', 'M'); insert_edge(&gl, 'D', 'E'); insert_edge(&gl, 'G', 'H'); insert_edge(&gl, 'G', 'I'); insert_edge(&gl, 'G', 'K'); insert_edge(&gl, 'H', 'K'); printf("\n"); show_graph(&gl); printf("Depth First Search(DFS) all nodes of the graph: \n"); depth_first_search(&gl, 'D'); printf("Nul\n"); printf("Breadth First Search(BFS) all nodes of the graph: \n"); breadth_first_search(&gl, 'A'); printf("Nul\n"); printf("Non connect graph DFS: \n"); components(&gl); printf("Nul\n"); //int v = get_first_neighbor(&gl, 'A'); //printf("The first neighbor node of 'A' is: %d\n", v); //int v1 = get_next_neighbor(&gl, 'B', 'E'); //printf("The next neighbor node of 'B' and 'E' is: %d\n", v1); //printf("\n"); //delete_edge(&gl, 'B', 'C'); //show_graph(&gl); //delete_vertex(&gl, 'C'); destroy_graph(&gl); }
void condensation(const std::set<int>& nodes, const std::map<int,std::set<int>>& edges, std::map<int,std::set<int>>& components, std::set<int>& condensation_nodes, std::map<int,std::set<int>>& condensation_edges) { // Initialize data structures for unsorted condensation std::unordered_map<int,std::set<int>> unsorted_components; std::unordered_map<int,int> unsorted_component_assignments; std::set<int> unsorted_condensation_nodes; std::map<int,std::set<int>> unsorted_condensation_edges; // Find strongly connected components with Kosaraju's algorithm // Note: First sort nodes by DFS post-order. Then, pick root nodes // in DFS post-order and perform DFS on graph transpose. The first // DFS that visits a node determines the strongly connected // component it belongs to. const auto& transpose_edges = transpose(nodes, edges); std::stack<int> dfs_stack; std::unordered_map<int,bool> is_sorted, is_condensed; for (const auto& root : nodes) { if (!is_sorted[root]) { for (const auto& node : depth_first_search(root, edges)) { if (!is_sorted[node]) { is_sorted[node] = true; dfs_stack.push(node); } } } } while (!dfs_stack.empty()) { const auto& root = dfs_stack.top(); dfs_stack.pop(); if (!is_condensed[root]) { const int index = unsorted_condensation_nodes.size(); unsorted_condensation_nodes.insert(index); for (const auto& node : depth_first_search(root, transpose_edges)) { if (!is_condensed[node]) { is_condensed[node] = true; unsorted_component_assignments[node] = index; unsorted_components[index].insert(node); } } } } // Find edges in unsorted condensation for (const auto& node : nodes) { const auto& unsorted_component = unsorted_component_assignments[node]; for (const auto& neighbor : get_neighbors(node, edges)) { const auto& neighbor_unsorted_component = unsorted_component_assignments[neighbor]; if (unsorted_component != neighbor_unsorted_component) { unsorted_condensation_edges[unsorted_component].insert(neighbor_unsorted_component); } } } // Topologically sort condensation const auto& sorted_to_unsorted = topological_sort(unsorted_condensation_nodes, unsorted_condensation_edges); // Record sorted condensation to output components.clear(); condensation_nodes.clear(); condensation_edges.clear(); for (size_t i = 0; i < unsorted_condensation_nodes.size(); ++i) { condensation_nodes.insert(i); } std::unordered_map<int,int> unsorted_to_sorted; for (const auto& component : condensation_nodes) { const auto& unsorted_component = sorted_to_unsorted[component]; unsorted_to_sorted[unsorted_component] = component; } for (const auto& unsorted_component : unsorted_condensation_nodes) { const auto& component = unsorted_to_sorted[unsorted_component]; components[component] = unsorted_components[unsorted_component]; for (const auto& neighbor_unsorted_component : unsorted_condensation_edges[unsorted_component]) { condensation_edges[component].insert(unsorted_to_sorted[neighbor_unsorted_component]); } } }
/** * This function provides a topological sort of the directed * acyclic graph provided as its input * @param orders dag as a vector of vectors * @param sortedOrders result sorted topologically */ void taskOrder( std::vector<std::vector<int> > const& orders, std::vector<int>& sortedOrders) { depth_first_search( orders, sortedOrders); }