From 546091f81933ca12cd28e4b15cbd3db5ee66ed0a Mon Sep 17 00:00:00 2001 From: Justin Viiret Date: Tue, 21 Mar 2017 13:09:53 +1100 Subject: [PATCH] ng_calc_components: filter vertices from ug --- src/nfagraph/ng_calc_components.cpp | 41 +++++++++-------------------- src/nfagraph/ng_util.h | 16 +++++++++++ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/nfagraph/ng_calc_components.cpp b/src/nfagraph/ng_calc_components.cpp index a7d8dd69..e0689366 100644 --- a/src/nfagraph/ng_calc_components.cpp +++ b/src/nfagraph/ng_calc_components.cpp @@ -64,6 +64,7 @@ #include #include +#include using namespace std; @@ -219,28 +220,6 @@ vector findShellEdges(const NGHolder &g, return shell_edges; } -static -void removeVertices(const flat_set &verts, NFAUndirectedGraph &ug, - ue2::unordered_map &old2new, - ue2::unordered_map &new2old) { - for (auto v : verts) { - assert(contains(old2new, v)); - auto uv = old2new.at(v); - clear_vertex(uv, ug); - remove_vertex(uv, ug); - old2new.erase(v); - new2old.erase(uv); - } -} - -static -void renumberVertices(NFAUndirectedGraph &ug) { - u32 vertexIndex = 0; - for (auto uv : vertices_range(ug)) { - put(boost::vertex_index, ug, uv, vertexIndex++); - } -} - /** * Common code called by calc- and recalc- below. Splits the given holder into * one or more connected components, adding them to the comps deque. @@ -286,15 +265,21 @@ void splitIntoComponents(unique_ptr g, new2old.emplace(m.second, m.first); } - // Remove shells from undirected graph and renumber so we have dense - // vertex indices. - removeVertices(head_shell, ug, old2new, new2old); - removeVertices(tail_shell, ug, old2new, new2old); - renumberVertices(ug); + // Filter shell vertices from undirected graph. + unordered_set shell_undir_vertices; + for (auto v : head_shell) { + shell_undir_vertices.insert(old2new.at(v)); + } + for (auto v : tail_shell) { + shell_undir_vertices.insert(old2new.at(v)); + } + auto filtered_ug = boost::make_filtered_graph( + ug, boost::keep_all(), make_bad_vertex_filter(&shell_undir_vertices)); + // Actually run the connected components algorithm. map split_components; const u32 num = connected_components( - ug, boost::make_assoc_property_map(split_components)); + filtered_ug, boost::make_assoc_property_map(split_components)); assert(num > 0); if (num == 1 && shell_edges.empty()) { diff --git a/src/nfagraph/ng_util.h b/src/nfagraph/ng_util.h index f3fa1354..1d3a6f32 100644 --- a/src/nfagraph/ng_util.h +++ b/src/nfagraph/ng_util.h @@ -124,6 +124,22 @@ bad_edge_filter make_bad_edge_filter(const EdgeSet *e) { return bad_edge_filter(e); } +/** \brief vertex graph filter. */ +template +struct bad_vertex_filter { + bad_vertex_filter() = default; + explicit bad_vertex_filter(const VertexSet *bad_v) : bad_vertices(bad_v) {} + bool operator()(const typename VertexSet::value_type &v) const { + return !contains(*bad_vertices, v); /* keep vertices not in bad set */ + } + const VertexSet *bad_vertices = nullptr; +}; + +template +bad_vertex_filter make_bad_vertex_filter(const VertexSet *v) { + return bad_vertex_filter(v); +} + /** Visitor that records back edges */ template class BackEdges : public boost::default_dfs_visitor {