Support for 'only_*'-typed turn restrictions.

This commit is contained in:
DennisOSRM
2011-12-02 16:38:10 +01:00
parent f601664620
commit 7be723782a
6 changed files with 62 additions and 35 deletions
+13 -12
View File
@@ -144,7 +144,7 @@ private:
try {
_firstEdge.resize( _numNodes + 1 );
} catch(...) {
cerr << "Not enough RAM on machine" << endl;
ERR("Not enough RAM on machine");
return;
}
_firstEdge[0] = 0;
@@ -164,7 +164,7 @@ private:
threadData.push_back( new _ThreadData( _numNodes ) );
}
cout << "Scanning for useless shortcuts" << endl;
INFO("Scanning for useless shortcuts");
BuildOutgoingGraph();
#pragma omp parallel for
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
@@ -202,7 +202,7 @@ private:
}
}
cout << "Removing edges" << endl;
INFO("Removing edges");
int useful = 0;
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut )
@@ -210,7 +210,7 @@ private:
_graph[useful] = _graph[i];
useful++;
}
cout << "Removed " << _graph.size() - useful << " useless shortcuts" << endl;
INFO("Removed " << _graph.size() - useful << " useless shortcuts");
_graph.resize( useful );
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
@@ -223,6 +223,11 @@ private:
const NodeID node = heapForward->DeleteMin();
const int distance = heapForward->GetKey( node );
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
if ( heapBackward->WasInserted( node ) ) {
const int newDistance = heapBackward->GetKey( node ) + distance;
if ( newDistance < *targetDistance ) {
@@ -231,11 +236,7 @@ private:
}
}
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
const NodeID to = _graph[edge].target;
const int edgeWeight = _graph[edge].data.distance;
assert( edgeWeight > 0 );
@@ -256,15 +257,15 @@ private:
}
}
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data, std::vector< NodeID >* path = NULL ) {
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data ) {
data->_heapForward->Clear();
data->_heapBackward->Clear();
//insert source into heap
data->_heapForward->Insert( source, 0, source );
data->_heapBackward->Insert( target, 0, target );
int targetDistance = (std::numeric_limits< int >::max)();
NodeID middle = (std::numeric_limits<NodeID>::max)();
int targetDistance = std::numeric_limits< int >::max();
NodeID middle = std::numeric_limits<NodeID>::max();
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
if ( data->_heapForward->Size() > 0 ) {
+34 -7
View File
@@ -99,6 +99,7 @@ void EdgeBasedGraphFactory::Run() {
Percent p(_nodeBasedGraph->GetNumberOfNodes());
int numberOfResolvedRestrictions(0);
int nodeBasedEdgeCounter(0);
NodeID onlyToNode(0);
//Loop over all nodes u. Three nested loop look super-linear, but we are dealing with a number linear in the turns only.
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
@@ -110,29 +111,56 @@ void EdgeBasedGraphFactory::Run() {
++nodeBasedEdgeCounter;
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
//loop over all reachable edges (v,w)
bool isOnlyAllowed(false);
//Check every turn restriction originating from this edge if it is an 'only_*'-turn.
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
do {
if(v == secondRestrictionIterator->viaNode) {
if(secondRestrictionIterator->flags.isOnly) {
isOnlyAllowed = true;
onlyToNode = secondRestrictionIterator->toNode;
}
}
++secondRestrictionIterator;
} while(u == secondRestrictionIterator->fromNode);
}
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
//if (u,v,w) is a forbidden turn, continue
bool isTurnProhibited = false;
bool isTurnRestricted(false);
if(isOnlyAllowed && w != onlyToNode) {
// INFO("skipped turn <" << u << "," << v << "," << w << ">, only allowing <" << u << "," << v << "," << onlyToNode << ">");
continue;
}
if( u != w ) { //only add an edge if turn is not a U-turn
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
do {
if( v == secondRestrictionIterator->viaNode && w == secondRestrictionIterator->toNode) {
isTurnProhibited = true;
if(v == secondRestrictionIterator->viaNode) {
if(w == secondRestrictionIterator->toNode) {
isTurnRestricted = true;
}
}
++secondRestrictionIterator;
} while(u == secondRestrictionIterator->fromNode);
}
if( !isTurnProhibited ) { //only add an edge if turn is not prohibited
if( !isTurnRestricted || (isOnlyAllowed && w == onlyToNode) ) { //only add an edge if turn is not prohibited
if(isOnlyAllowed && w == onlyToNode) {
// INFO("Adding 'only_*'-turn <" << u << "," << v << "," << w << ">");
} else if(isOnlyAllowed && w != onlyToNode) {
assert(false);
}
//new costs for edge based edge (e1, e2) = cost (e1) + tc(e1,e2)
const _NodeBasedDynamicGraph::NodeIterator edgeBasedSource = _nodeBasedGraph->GetEdgeData(e1).edgeBasedNodeID;
// INFO("edgeBasedSource: " << edgeBasedSource);
if(edgeBasedSource > _nodeBasedGraph->GetNumberOfEdges()) {
ERR("edgeBasedTarget" << edgeBasedSource << ">" << _nodeBasedGraph->GetNumberOfEdges());
}
const _NodeBasedDynamicGraph::NodeIterator edgeBasedTarget = _nodeBasedGraph->GetEdgeData(e2).edgeBasedNodeID;
// INFO("edgeBasedTarget: " << edgeBasedTarget);
if(edgeBasedTarget > _nodeBasedGraph->GetNumberOfEdges()) {
ERR("edgeBasedTarget" << edgeBasedTarget << ">" << _nodeBasedGraph->GetNumberOfEdges());
}
@@ -145,7 +173,6 @@ void EdgeBasedGraphFactory::Run() {
short turnInstruction = AnalyzeTurn(u, v, w);
//create edge-based graph edge
//EdgeBasedEdge(NodeID s, NodeID t, NodeID v, unsigned n1, EdgeWeight w, bool f, bool b, short ty)
EdgeBasedEdge newEdge(edgeBasedSource, edgeBasedTarget, v, nameID, distance, true, false, turnInstruction);
edgeBasedEdges.push_back(newEdge);
EdgeBasedNode currentNode;