Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EdgeBasedGraphFactory refactoring #1010

Merged
merged 11 commits into from
May 9, 2014
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ file(GLOB ExtractorGlob Extractor/*.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources})

file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp)
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp)
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources})

Expand Down
145 changes: 145 additions & 0 deletions Contractor/BFSComponentExplorer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#ifndef __BFS_COMPONENT_EXPLORER_H__
#define __BFS_COMPONENT_EXPLORER_H__

#include <queue>
#include <boost/unordered_set.hpp>

#include "../typedefs.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/RestrictionMap.h"

/**
* Explores the components of the given graph while respecting turn restrictions
* and barriers.
*/
template <typename GraphT> class BFSComponentExplorer
{
public:
typedef typename GraphT::NodeIterator NodeIterator;
typedef typename GraphT::EdgeIterator EdgeIterator;

BFSComponentExplorer(const GraphT &dynamicGraph,
const RestrictionMap &restrictions,
const boost::unordered_set<NodeID> &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<std::pair<NodeID, NodeID>> 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<unsigned>::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<unsigned>::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<std::pair<NodeID, NodeID>> &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<NodeID, NodeID> 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<unsigned>::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<unsigned>::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<unsigned> m_component_index_list;
std::vector<NodeID> m_component_index_size;

const GraphT &m_graph;
const RestrictionMap &m_restriction_map;
const boost::unordered_set<NodeID> &m_barrier_nodes;
};

#endif
Loading