std::vector<mitk::TubeGraph::TubeDescriptorType> mitk::TubeGraph::SearchAllPathBetweenVertices(const mitk::TubeGraph::TubeDescriptorType& startTube, const mitk::TubeGraph::TubeDescriptorType& endTube/*, std::vector<unsigned long> barrier*/ ) { //http://lists.boost.org/boost-users/att-9001/maze.cpp //http://www.boost.org/doc/libs/1_49_0/libs/graph/example/bfs.cpp typedef std::map<VertexDescriptorType, EdgeDescriptorType> EdgeMap; typedef boost::associative_property_map<EdgeMap> PredecessorMap; typedef boost::edge_predecessor_recorder<PredecessorMap, boost::on_tree_edge> PredecessorVisitor; typedef boost::dfs_visitor< std::pair<PredecessorVisitor, boost::null_visitor> > DFSVisitor; EdgeMap edgesMap; PredecessorMap predecessorMap(edgesMap); PredecessorVisitor predecessorVisitor(predecessorMap); boost::null_visitor nullVisitor; DFSVisitor visitor = boost::make_dfs_visitor(std::make_pair(predecessorVisitor, nullVisitor)); std::map<VertexDescriptorType, boost::default_color_type> vertexColorMap; std::map<EdgeDescriptorType, boost::default_color_type> edgeColorMap; boost::undirected_dfs(m_Graph, visitor, make_assoc_property_map(vertexColorMap), make_assoc_property_map(edgeColorMap), startTube.second ); std::vector<TubeDescriptorType> solutionPath; solutionPath.push_back(endTube); VertexDescriptorType pathEdgeSource = endTube.first; VertexDescriptorType pathEdgeTarget; MITK_INFO << "Source: ["<< startTube.first<<","<<startTube.second<<"] Target: ["<< endTube.first<<","<<endTube.second<<"]"; MITK_INFO<< "tube ["<<endTube.first<<","<<endTube.second<<"]"; do { if(pathEdgeSource == 10393696) break; EdgeDescriptorType edge = get(predecessorMap, pathEdgeSource); pathEdgeSource = boost::source(edge, m_Graph); pathEdgeTarget = boost::target(edge, m_Graph); TubeDescriptorType tube (pathEdgeSource, pathEdgeTarget); MITK_INFO<< "tube ["<<tube.first<<","<<tube.second<<"]"; solutionPath.push_back(tube); } while (pathEdgeSource != startTube.second); return solutionPath; }
/** Remove any vertices that can't be reached by traversing the graph in * reverse from acceptEod. */ void pruneUnreachable(NGHolder &g) { deque<NFAVertex> dead; if (!hasGreaterInDegree(1, g.acceptEod, g) && !hasGreaterInDegree(0, g.accept, g) && edge(g.accept, g.acceptEod, g).second) { // Trivial case: there are no in-edges to our accepts (other than // accept->acceptEod), so all non-specials are unreachable. for (auto v : vertices_range(g)) { if (!is_special(v, g)) { dead.push_back(v); } } } else { // Walk a reverse graph from acceptEod with Boost's depth_first_visit // call. typedef reverse_graph<NFAGraph, NFAGraph&> RevNFAGraph; RevNFAGraph revg(g.g); map<NFAVertex, default_color_type> colours; depth_first_visit(revg, g.acceptEod, make_dfs_visitor(boost::null_visitor()), make_assoc_property_map(colours)); DEBUG_PRINTF("color map has %zu entries after DFV\n", colours.size()); // All non-special vertices that aren't in the colour map (because they // weren't reached) can be removed. for (auto v : vertices_range(revg)) { if (is_special(v, revg)) { continue; } if (!contains(colours, v)) { dead.push_back(v); } } } if (dead.empty()) { DEBUG_PRINTF("no unreachable vertices\n"); return; } remove_vertices(dead, g, false); DEBUG_PRINTF("removed %zu unreachable vertices\n", dead.size()); }
static vector<NFAVertex> findUnreachable(const NGHolder &g) { const boost::reverse_graph<NFAGraph, const NFAGraph &> revg(g.g); ue2::unordered_map<NFAVertex, boost::default_color_type> colours; colours.reserve(num_vertices(g)); depth_first_visit(revg, g.acceptEod, make_dfs_visitor(boost::null_visitor()), make_assoc_property_map(colours)); // Unreachable vertices are not in the colour map. vector<NFAVertex> unreach; for (auto v : vertices_range(revg)) { if (!contains(colours, v)) { unreach.push_back(v); } } return unreach; }
flat_set<NFAVertex> execute_graph(const NGHolder &running_g, const NGHolder &input_dag, const flat_set<NFAVertex> &input_start_states, const flat_set<NFAVertex> &initial_states) { DEBUG_PRINTF("g has %zu vertices, input_dag has %zu vertices\n", num_vertices(running_g), num_vertices(input_dag)); assert(hasCorrectlyNumberedVertices(running_g)); assert(in_degree(input_dag.acceptEod, input_dag) == 1); map<NFAVertex, boost::default_color_type> colours; /* could just a topo order, but really it is time to pull a slightly bigger * gun: DFS */ RevNFAGraph revg(input_dag.g); map<NFAVertex, dynamic_bitset<> > dfs_states; auto info = makeInfoTable(running_g); auto input_fs = makeStateBitset(running_g, initial_states); for (auto v : input_start_states) { dfs_states[v] = input_fs; } depth_first_visit(revg, input_dag.accept, eg_visitor(running_g, info, input_dag, dfs_states), make_assoc_property_map(colours)); auto states = getVertices(dfs_states[input_dag.accept], info); #ifdef DEBUG DEBUG_PRINTF(" output rstates:"); for (const auto &v : states) { printf(" %u", running_g[v].index); } printf("\n"); #endif return states; }