ng_calc_components: filter vertices from ug

This commit is contained in:
Justin Viiret 2017-03-21 13:09:53 +11:00 committed by Matthew Barr
parent 4b3ff085d3
commit 546091f819
2 changed files with 29 additions and 28 deletions

View File

@ -64,6 +64,7 @@
#include <vector> #include <vector>
#include <boost/graph/connected_components.hpp> #include <boost/graph/connected_components.hpp>
#include <boost/graph/filtered_graph.hpp>
using namespace std; using namespace std;
@ -219,28 +220,6 @@ vector<NFAEdge> findShellEdges(const NGHolder &g,
return shell_edges; return shell_edges;
} }
static
void removeVertices(const flat_set<NFAVertex> &verts, NFAUndirectedGraph &ug,
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> &old2new,
ue2::unordered_map<NFAUndirectedVertex, NFAVertex> &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 * Common code called by calc- and recalc- below. Splits the given holder into
* one or more connected components, adding them to the comps deque. * one or more connected components, adding them to the comps deque.
@ -286,15 +265,21 @@ void splitIntoComponents(unique_ptr<NGHolder> g,
new2old.emplace(m.second, m.first); new2old.emplace(m.second, m.first);
} }
// Remove shells from undirected graph and renumber so we have dense // Filter shell vertices from undirected graph.
// vertex indices. unordered_set<NFAUndirectedVertex> shell_undir_vertices;
removeVertices(head_shell, ug, old2new, new2old); for (auto v : head_shell) {
removeVertices(tail_shell, ug, old2new, new2old); shell_undir_vertices.insert(old2new.at(v));
renumberVertices(ug); }
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<NFAUndirectedVertex, u32> split_components; map<NFAUndirectedVertex, u32> split_components;
const u32 num = connected_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); assert(num > 0);
if (num == 1 && shell_edges.empty()) { if (num == 1 && shell_edges.empty()) {

View File

@ -124,6 +124,22 @@ bad_edge_filter<EdgeSet> make_bad_edge_filter(const EdgeSet *e) {
return bad_edge_filter<EdgeSet>(e); return bad_edge_filter<EdgeSet>(e);
} }
/** \brief vertex graph filter. */
template<typename VertexSet>
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<typename VertexSet>
bad_vertex_filter<VertexSet> make_bad_vertex_filter(const VertexSet *v) {
return bad_vertex_filter<VertexSet>(v);
}
/** Visitor that records back edges */ /** Visitor that records back edges */
template <typename BackEdgeSet> template <typename BackEdgeSet>
class BackEdges : public boost::default_dfs_visitor { class BackEdges : public boost::default_dfs_visitor {