From 5a13c6cc3f6fb53811bce156a36074e92eac6db3 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Tue, 6 May 2014 23:52:51 +0200 Subject: [PATCH] Move BFSComponentExplorer to own header. --- Contractor/EdgeBasedGraphFactory.cpp | 112 +++---------------- Contractor/EdgeBasedGraphFactory.h | 5 - DataStructures/BFSComponentExplorer.h | 151 ++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 100 deletions(-) create mode 100644 DataStructures/BFSComponentExplorer.h diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index 38d337bc9..ec3d80a1a 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "EdgeBasedGraphFactory.h" #include "../Util/ComputeAngle.h" +#include "../DataStructures/BFSComponentExplorer.h" #include #include @@ -434,8 +435,6 @@ void EdgeBasedGraphFactory::Run( } } - SimpleLogger().Write() << "Identifying components of the road network"; - unsigned node_based_edge_counter = 0; unsigned original_edges_counter = 0; @@ -450,13 +449,20 @@ void EdgeBasedGraphFactory::Run( sizeof(unsigned) ); + SimpleLogger().Write() << "Identifying components of the road network"; + //Run a BFS on the undirected graph and identify small components - std::vector component_index_list; - std::vector component_index_size; - BFSCompentExplorer( component_index_list, component_index_size ); + //TODO move this to a sub function, so we can just use scoping + auto component_explorer = new BFSComponentExplorer( + *m_node_based_graph, + *m_restriction_map, + m_barrier_nodes + ); + + component_explorer->run(); SimpleLogger().Write() << - "identified: " << component_index_size.size() << " many components"; + "identified: " << component_explorer->getNumberOfComponents() << " many components"; SimpleLogger().Write() << "generating edge-expanded nodes"; p.reinit(m_node_based_graph->GetNumberOfNodes()); @@ -495,8 +501,8 @@ void EdgeBasedGraphFactory::Run( //Note: edges that end on barrier nodes or on a turn restriction //may actually be in two distinct components. We choose the smallest const unsigned size_of_component = std::min( - component_index_size[component_index_list[u]], - component_index_size[component_index_list[v]] + component_explorer->getComponentSize(u), + component_explorer->getComponentSize(v) ); const bool component_is_tiny = ( size_of_component < 1000 ); @@ -504,22 +510,15 @@ void EdgeBasedGraphFactory::Run( } } + delete component_explorer; + m_number_of_edge_based_nodes = numbered_edges_count; SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() << " nodes in edge-expanded graph"; + SimpleLogger().Write() << "generating edge-expanded edges"; - std::vector().swap(component_index_size); - BOOST_ASSERT_MSG( - 0 == component_index_size.capacity(), - "component size vector not deallocated" - ); - std::vector().swap(component_index_list); - BOOST_ASSERT_MSG( - 0 == component_index_list.capacity(), - "component index vector not deallocated" - ); std::vector original_edge_data_vector; original_edge_data_vector.reserve(1024*1024); @@ -762,80 +761,3 @@ unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const { return m_number_of_edge_based_nodes; } -void EdgeBasedGraphFactory::BFSCompentExplorer( - std::vector & component_index_list, - std::vector & component_index_size -) const { - std::queue > bfs_queue; - Percent p( m_node_based_graph->GetNumberOfNodes() ); - unsigned current_component, current_component_size; - current_component = current_component_size = 0; - - BOOST_ASSERT( component_index_list.empty() ); - BOOST_ASSERT( component_index_size.empty() ); - - component_index_list.resize( - m_node_based_graph->GetNumberOfNodes(), - std::numeric_limits::max() - ); - - //put unexplorered node with parent pointer into queue - for( NodeID node = 0, end = m_node_based_graph->GetNumberOfNodes(); node < end; ++node) { - if(std::numeric_limits::max() == component_index_list[node]) { - bfs_queue.push(std::make_pair(node, node)); - //mark node as read - component_index_list[node] = current_component; - p.printIncrement(); - while(!bfs_queue.empty()) { - //fetch element from BFS queue - std::pair current_queue_item = bfs_queue.front(); - bfs_queue.pop(); - - const NodeID v = current_queue_item.first; //current node - const NodeID u = current_queue_item.second; //parent - //increment size counter of current component - ++current_component_size; - const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); - if(!is_barrier_node) { - const NodeID to_node_of_only_restriction = m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v); - - for( - EdgeIterator e2 = m_node_based_graph->BeginEdges(v); - e2 < m_node_based_graph->EndEdges(v); - ++e2 - ) { - NodeIterator w = m_node_based_graph->GetTarget(e2); - - if( - to_node_of_only_restriction != std::numeric_limits::max() && - w != to_node_of_only_restriction - ) { - // At an only_-restriction but not at the right turn - continue; - } - if( u != w ) { - //only add an edge if turn is not a U-turn except - //when it is at the end of a dead-end street. - if (!m_restriction_map->CheckIfTurnIsRestricted(u, v, w) ) { - //only add an edge if turn is not prohibited - if(std::numeric_limits::max() == component_index_list[w]) { - //insert next (node, parent) only if w has - //not yet been explored - //mark node as read - component_index_list[w] = current_component; - bfs_queue.push(std::make_pair(w,v)); - p.printIncrement(); - } - } - } - } - } - } - //push size into vector - component_index_size.push_back(current_component_size); - //reset counters; - current_component_size = 0; - ++current_component; - } - } -} diff --git a/Contractor/EdgeBasedGraphFactory.h b/Contractor/EdgeBasedGraphFactory.h index 033c81c4b..87f5127c0 100644 --- a/Contractor/EdgeBasedGraphFactory.h +++ b/Contractor/EdgeBasedGraphFactory.h @@ -145,11 +145,6 @@ private: bool belongsToTinyComponent ); - void BFSCompentExplorer( - std::vector & component_index_list, - std::vector & component_index_size - ) const; - void FlushVectorToStream( std::ofstream & edge_data_file, std::vector & original_edge_data_vector diff --git a/DataStructures/BFSComponentExplorer.h b/DataStructures/BFSComponentExplorer.h new file mode 100644 index 000000000..92b21d9ec --- /dev/null +++ b/DataStructures/BFSComponentExplorer.h @@ -0,0 +1,151 @@ +#ifndef __BFS_COMPONENT_EXPLORER_H__ +#define __BFS_COMPONENT_EXPLORER_H__ + +#include +#include + +#include "../typedefs.h" +#include "DynamicGraph.h" +#include "RestrictionMap.h" + +/** + * Explores the components of the given graph while respecting turn restrictions + * and barriers. + */ +template +class BFSComponentExplorer +{ +public: + typedef typename GraphT::NodeIterator NodeIterator; + typedef typename GraphT::EdgeIterator EdgeIterator; + + BFSComponentExplorer(const GraphT& dynamicGraph, + const RestrictionMap& restrictions, + const boost::unordered_set& barrier_nodes) + : m_graph(dynamicGraph) + , m_restriction_map(restrictions) + , m_barrier_nodes(barrier_nodes) + { + BOOST_ASSERT(m_graph.GetNumberOfNodes() > 0); + } + + /*! + * Returns the size of the component that the node belongs to. + */ + inline unsigned int getComponentSize(NodeID node) + { + BOOST_ASSERT(node < m_component_index_list.size()); + + return m_component_index_size[m_component_index_list[node]]; + } + + inline unsigned int getNumberOfComponents() + { + return m_component_index_size.size(); + } + + /*! + * Computes the component sizes. + */ + void run() + { + std::queue > bfs_queue; + unsigned current_component = 0; + + BOOST_ASSERT( m_component_index_list.empty() ); + BOOST_ASSERT( m_component_index_size.empty() ); + + unsigned num_nodes = m_graph.GetNumberOfNodes(); + + m_component_index_list.resize( + num_nodes, + std::numeric_limits::max() + ); + + BOOST_ASSERT (num_nodes > 0); + + //put unexplorered node with parent pointer into queue + for( NodeID node = 0; node < num_nodes; ++node) { + if(std::numeric_limits::max() == m_component_index_list[node]) { + unsigned size = exploreComponent(bfs_queue, node, current_component); + + //push size into vector + m_component_index_size.push_back(size); + ++current_component; + } + } + } + +private: + /*! + * Explores the current component that starts at node using BFS. + */ + inline unsigned exploreComponent( + std::queue > &bfs_queue, + NodeID node, + unsigned current_component + ) { + bfs_queue.push(std::make_pair(node, node)); + //mark node as read + m_component_index_list[node] = current_component; + + unsigned current_component_size = 1; + + while(!bfs_queue.empty()) { + //fetch element from BFS queue + std::pair current_queue_item = bfs_queue.front(); + bfs_queue.pop(); + + const NodeID v = current_queue_item.first; //current node + const NodeID u = current_queue_item.second; //parent + //increment size counter of current component + ++current_component_size; + const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); + if(!is_barrier_node) { + const NodeID to_node_of_only_restriction = m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); + + for( + EdgeIterator e2 = m_graph.BeginEdges(v); + e2 < m_graph.EndEdges(v); + ++e2 + ) { + NodeIterator w = m_graph.GetTarget(e2); + + if( + to_node_of_only_restriction != std::numeric_limits::max() && + w != to_node_of_only_restriction + ) { + // At an only_-restriction but not at the right turn + continue; + } + + if( u != w ) { + //only add an edge if turn is not a U-turn except + //when it is at the end of a dead-end street. + if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) { + //only add an edge if turn is not prohibited + if(std::numeric_limits::max() == m_component_index_list[w]) { + //insert next (node, parent) only if w has + //not yet been explored + //mark node as read + m_component_index_list[w] = current_component; + bfs_queue.push(std::make_pair(w,v)); + } + } + } + } + } + } + + return current_component_size; + } + + std::vector m_component_index_list; + std::vector m_component_index_size; + + const GraphT& m_graph; + const RestrictionMap& m_restriction_map; + const boost::unordered_set& m_barrier_nodes; +}; + +#endif