OutputIterator articulation_points(const Graph& g, OutputIterator out, VertexIndexMap index_map) { return biconnected_components(g, dummy_property_map(), out, index_map).second; }
void make_biconnected_planar(Graph& g, PlanarEmbedding embedding, EdgeIndexMap em, AddEdgeVisitor& vis ) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; typedef typename graph_traits<Graph>::edges_size_type edge_size_t; typedef typename property_traits<PlanarEmbedding>::value_type embedding_value_t; typedef typename embedding_value_t::const_iterator embedding_iterator_t; typedef iterator_property_map <std::vector<std::size_t>::iterator, EdgeIndexMap> component_map_t; edge_size_t n_edges(num_edges(g)); std::vector<vertex_t> articulation_points; std::vector<edge_size_t> component_vector(n_edges); component_map_t component_map(component_vector.begin(), em); biconnected_components(g, component_map, std::back_inserter(articulation_points)); typename std::vector<vertex_t>::iterator ap, ap_end; ap_end = articulation_points.end(); for(ap = articulation_points.begin(); ap != ap_end; ++ap) { vertex_t v(*ap); embedding_iterator_t pi = embedding[v].begin(); embedding_iterator_t pi_end = embedding[v].end(); edge_size_t previous_component(n_edges + 1); vertex_t previous_vertex = graph_traits<Graph>::null_vertex(); for(; pi != pi_end; ++pi) { edge_t e(*pi); vertex_t e_source(source(e,g)); vertex_t e_target(target(e,g)); //Skip self-loops and parallel edges if (e_source == e_target || previous_vertex == e_target) continue; vertex_t current_vertex = e_source == v ? e_target : e_source; edge_size_t current_component = component_map[e]; if (previous_vertex != graph_traits<Graph>::null_vertex() && current_component != previous_component) { vis.visit_vertex_pair(current_vertex, previous_vertex, g); } previous_vertex = current_vertex; previous_component = current_component; } } }
std::pair<std::size_t, OutputIterator> biconnected_components(const Graph & g, ComponentMap comp, OutputIterator out, DiscoverTimeMap discover_time, LowPointMap lowpt, VertexIndexMap index_map) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; std::vector<vertex_t> pred(num_vertices(g)); vertex_t vert = graph_traits<Graph>::null_vertex(); return biconnected_components (g, comp, out, discover_time, lowpt, make_iterator_property_map(pred.begin(), index_map, vert), index_map); }
// This function returns the biconnected components of the graph. std::vector<std::vector<v_index>> blocks_and_cut_vertices() { edge_map bicmp_map; boost::associative_property_map<edge_map> bimap(bicmp_map); std::size_t num_comps = biconnected_components(graph, bimap); // We iterate over every edge and add the vertices of block i into to_return[i]. // to_return[i] could contain repetitions. std::vector<std::vector<v_index>> to_return(num_comps, std::vector<v_index>(0)); typename boost::graph_traits<adjacency_list>::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(graph); ei != ei_end; ++ei) { to_return[bimap[*ei]].push_back(index[source(*ei, graph)]); to_return[bimap[*ei]].push_back(index[target(*ei, graph)]); } return to_return; }
std::pair<std::size_t, OutputIterator> biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, VertexIndexMap index_map) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type; std::vector<vertices_size_type> discover_time(num_vertices(g)); std::vector<vertices_size_type> lowpt(num_vertices(g)); vertices_size_type vst(0); return biconnected_components (g, comp, out, make_iterator_property_map(discover_time.begin(), index_map, vst), make_iterator_property_map(lowpt.begin(), index_map, vst), index_map); }
int main(){ Graph G = udgraph_toy_ex(); // biconnected component is a partition of *edges*, so we need a property_map (for edges) to store the component id for each edge WeightMap wm = get(edge_weight, G); /* we just use the WeightMap (which is just a property_map for edges) to store the components * else we can use the edge_component_t as above... ( need to redefine the `Graph` type, see: http://www.boost.org/doc/libs/1_59_0/libs/graph/example/biconnected_components.cpp ) */ int ncomp = biconnected_components(G, wm); cout << ncomp << " biconnected components" << endl; EdgeIt ei, ei_end; for (tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) cout << source(*ei, G) << "-" << target(*ei, G) << ", belongs to biconnected-component-" << wm[*ei] << endl; cout << endl; // get articulation points vector<Vertex> art_pts; articulation_points(G, back_inserter(art_pts)); cout << art_pts.size() << " articulation points, they are: " << endl; for(vector<Vertex>::iterator it=art_pts.begin(); it!=art_pts.end(); it++) cout << *it << ", "; cout << endl; }
/* * The mex function runs a max-flow min-cut problem. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; int mrows, ncols; int n,nz; /* sparse matrix */ mwIndex *ia, *ja; /* output data */ double *a, *ci; mwIndex *int_a; if (nrhs != 1) { mexErrMsgTxt("1 inputs required."); } /* The first input must be a sparse matrix. */ mrows = mxGetM(prhs[0]); ncols = mxGetN(prhs[0]); if (mrows != ncols || !mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0])) { mexErrMsgTxt("Input must be a noncomplex square sparse matrix."); } n = mrows; /* Get the sparse matrix */ /* recall that we've transposed the matrix */ ja = mxGetIr(prhs[0]); ia = mxGetJc(prhs[0]); nz = ia[n]; plhs[0] = mxCreateDoubleMatrix(n,1,mxREAL); a = mxGetPr(plhs[0]); ci = NULL; if (nlhs > 1) { plhs[1] = mxCreateDoubleMatrix(nz,1,mxREAL); ci = mxGetPr(plhs[1]); } int_a = (mwIndex*)a; for (i=0; i<n; i++) { int_a[i] = MWINDEX_MAX; } biconnected_components(n, ja, ia, (mwIndex*)a, (mwIndex*)ci); expand_index_to_double_zero_special((mwIndex*)a, a, n, 1.0, MWINDEX_MAX); if (nlhs > 1) { expand_index_to_double((mwIndex*)ci, ci, nz, 1.0); } }
OutputIterator articulation_points(const Graph& g, OutputIterator out) { return biconnected_components(g, dummy_property_map(), out, get(vertex_index, g)).second; }
std::size_t biconnected_components(const Graph& g, ComponentMap comp) { return biconnected_components(g, comp, graph_detail::dummy_output_iterator()).first; }
std::pair<std::size_t, OutputIterator> biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out) { return biconnected_components(g, comp, out, get(vertex_index, g)); }