Partially fixes ticket #31 where oneway streets may be be ignored at the start or end of a route

This commit is contained in:
Dennis Luxen 2011-05-30 17:46:56 +00:00
parent 5f6cac9155
commit d761d0fa9d

View File

@ -54,6 +54,37 @@ struct _Statistics {
double preprocTime; double preprocTime;
}; };
struct _InsertedNodes {
NodeID forward1;
NodeID forward2;
NodeID backward1;
NodeID backward2;
_InsertedNodes() : forward1(UINT_MAX), forward2(UINT_MAX), backward1(UINT_MAX), backward2(UINT_MAX) {};
void BackInsert(NodeID n) {
if(backward1 == UINT_MAX) {
backward1 = n;
} else {
backward2 = n;
}
}
void ForwInsert( NodeID n) {
if(forward1 == UINT_MAX) {
forward1 = n;
} else {
forward2 = n;
}
}
inline bool isForwardInserted(NodeID n) {
return forward1 == n || forward2 == n;
}
inline bool isBackwardInserted (NodeID n) {
return backward1 == n || backward2 == n;
}
};
typedef BinaryHeap< NodeID, int, int, _HeapData, DenseStorage< NodeID, unsigned > > _Heap; typedef BinaryHeap< NodeID, int, int, _HeapData, DenseStorage< NodeID, unsigned > > _Heap;
template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformationHelpDesk> template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformationHelpDesk>
@ -84,8 +115,10 @@ public:
bool startReverse = false; bool startReverse = false;
bool targetReverse = false; bool targetReverse = false;
_InsertedNodes _insertedNodes;
_Heap _forwardHeap(nodeHelpDesk->getNumberOfNodes()); _Heap _forwardHeap(nodeHelpDesk->getNumberOfNodes());
_Heap _backwardHeap(nodeHelpDesk->getNumberOfNodes()); _Heap _backwardHeap(nodeHelpDesk->getNumberOfNodes());
NodeID middle = ( NodeID ) 0; NodeID middle = ( NodeID ) 0;
unsigned int _upperbound = std::numeric_limits<unsigned int>::max(); unsigned int _upperbound = std::numeric_limits<unsigned int>::max();
@ -122,30 +155,34 @@ public:
} else if(phantomNodes->startRatio > phantomNodes->targetRatio) { } else if(phantomNodes->startRatio > phantomNodes->targetRatio) {
onSameEdgeReversed = true; onSameEdgeReversed = true;
_Coordinate result;
getNodeInfo(phantomNodes->startNode1, result);
getNodeInfo(phantomNodes->startNode2, result);
EdgeWeight w = _graph->GetEdgeData( currentEdge ).distance; EdgeWeight w = _graph->GetEdgeData( currentEdge ).distance;
_forwardHeap.Insert(phantomNodes->startNode2, absDouble( w*phantomNodes->startRatio), phantomNodes->startNode2); _forwardHeap.Insert(phantomNodes->startNode2, absDouble( w*phantomNodes->startRatio), phantomNodes->startNode2);
_insertedNodes.ForwInsert(phantomNodes->startNode2);
_backwardHeap.Insert(phantomNodes->startNode1, absDouble( w-w*phantomNodes->targetRatio), phantomNodes->startNode1); _backwardHeap.Insert(phantomNodes->startNode1, absDouble( w-w*phantomNodes->targetRatio), phantomNodes->startNode1);
_insertedNodes.BackInsert(phantomNodes->startNode1);
}
} }
} else if(phantomNodes->startNode1 != UINT_MAX) { if(phantomNodes->startNode1 != UINT_MAX) {
EdgeID edge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2); EdgeID edge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2);
if(edge == UINT_MAX){ if(edge == UINT_MAX){
edge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 ); edge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 );
startReverse = true;
}
if(edge == UINT_MAX){ if(edge == UINT_MAX){
return _upperbound; return _upperbound;
} }
startReverse = true;
}
const EdgeData& ed = _graph->GetEdgeData(edge); const EdgeData& ed = _graph->GetEdgeData(edge);
EdgeWeight w = ed.distance; EdgeWeight w = ed.distance;
if( (ed.backward && !startReverse) || (ed.forward && startReverse) )
if( (ed.backward && !startReverse) || (ed.forward && startReverse) ){
_forwardHeap.Insert(phantomNodes->startNode1, absDouble( w*phantomNodes->startRatio), phantomNodes->startNode1); _forwardHeap.Insert(phantomNodes->startNode1, absDouble( w*phantomNodes->startRatio), phantomNodes->startNode1);
if( (ed.backward && startReverse) || (ed.forward && !startReverse) ) _insertedNodes.ForwInsert(phantomNodes->startNode1);
}
if( (ed.backward && startReverse) || (ed.forward && !startReverse) ) {
_forwardHeap.Insert(phantomNodes->startNode2, absDouble(w-w*phantomNodes->startRatio), phantomNodes->startNode2); _forwardHeap.Insert(phantomNodes->startNode2, absDouble(w-w*phantomNodes->startRatio), phantomNodes->startNode2);
_insertedNodes.ForwInsert(phantomNodes->startNode2);
}
} }
if(phantomNodes->targetNode1 != UINT_MAX && !onSameEdgeReversed) { if(phantomNodes->targetNode1 != UINT_MAX && !onSameEdgeReversed) {
EdgeID edge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2); EdgeID edge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2);
@ -160,19 +197,17 @@ public:
const EdgeData& ed = _graph->GetEdgeData(edge); const EdgeData& ed = _graph->GetEdgeData(edge);
EdgeWeight w = ed.distance; EdgeWeight w = ed.distance;
if( (ed.backward && !targetReverse) || (ed.forward && targetReverse) ) if( (ed.backward && !targetReverse) || (ed.forward && targetReverse) ) {
_backwardHeap.Insert(phantomNodes->targetNode2, absDouble( w*phantomNodes->targetRatio), phantomNodes->targetNode2); _backwardHeap.Insert(phantomNodes->targetNode2, absDouble( w*phantomNodes->targetRatio), phantomNodes->targetNode2);
if( (ed.backward && targetReverse) || (ed.forward && !targetReverse) ) _insertedNodes.BackInsert(phantomNodes->targetNode2);
}
if( (ed.backward && targetReverse) || (ed.forward && !targetReverse) ) {
_backwardHeap.Insert(phantomNodes->targetNode1, absDouble(w-w*phantomNodes->targetRatio), phantomNodes->targetNode1); _backwardHeap.Insert(phantomNodes->targetNode1, absDouble(w-w*phantomNodes->targetRatio), phantomNodes->targetNode1);
_insertedNodes.BackInsert(phantomNodes->targetNode1);
}
} }
// double time = get_timestamp(); // double time = get_timestamp();
NodeID sourceHeapNode = 0;
NodeID targetHeapNode = 0;
if(onSameEdgeReversed) {
sourceHeapNode = _forwardHeap.Min();
targetHeapNode = _backwardHeap.Min();
}
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) { while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
if ( _forwardHeap.Size() > 0 ) { if ( _forwardHeap.Size() > 0 ) {
_RoutingStep( &_forwardHeap, &_backwardHeap, true, &middle, &_upperbound ); _RoutingStep( &_forwardHeap, &_backwardHeap, true, &middle, &_upperbound );
@ -191,7 +226,7 @@ public:
NodeID pathNode = middle; NodeID pathNode = middle;
deque< NodeID > packedPath; deque< NodeID > packedPath;
while ( onSameEdgeReversed ? pathNode != sourceHeapNode : pathNode != phantomNodes->startNode1 && pathNode != phantomNodes->startNode2 ) { while ( false == _insertedNodes.isForwardInserted(pathNode) ) {
pathNode = _forwardHeap.GetData( pathNode ).parent; pathNode = _forwardHeap.GetData( pathNode ).parent;
packedPath.push_front( pathNode ); packedPath.push_front( pathNode );
} }
@ -199,7 +234,7 @@ public:
packedPath.push_back( middle ); packedPath.push_back( middle );
pathNode = middle; pathNode = middle;
while ( onSameEdgeReversed ? pathNode != targetHeapNode : pathNode != phantomNodes->targetNode2 && pathNode != phantomNodes->targetNode1 ){ while ( false == _insertedNodes.isBackwardInserted(pathNode) ){
pathNode = _backwardHeap.GetData( pathNode ).parent; pathNode = _backwardHeap.GetData( pathNode ).parent;
packedPath.push_back( pathNode ); packedPath.push_back( pathNode );
} }