Rewiring routing algorithms
This commit is contained in:
parent
7599124aa0
commit
1194bb8ae3
@ -22,6 +22,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define ALTERNATIVEROUTES_H_
|
#define ALTERNATIVEROUTES_H_
|
||||||
|
|
||||||
#include "BasicRoutingInterface.h"
|
#include "BasicRoutingInterface.h"
|
||||||
|
#include "../DataStructures/SearchEngineData.h"
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -30,11 +31,11 @@ const double VIAPATH_ALPHA = 0.15;
|
|||||||
const double VIAPATH_EPSILON = 0.10; //alternative at most 15% longer
|
const double VIAPATH_EPSILON = 0.10; //alternative at most 15% longer
|
||||||
const double VIAPATH_GAMMA = 0.75; //alternative shares at most 75% with the shortest.
|
const double VIAPATH_GAMMA = 0.75; //alternative shares at most 75% with the shortest.
|
||||||
|
|
||||||
template<class QueryDataT>
|
template<class DataFacadeT>
|
||||||
class AlternativeRouting : private BasicRoutingInterface<QueryDataT> {
|
class AlternativeRouting : private BasicRoutingInterface<DataFacadeT> {
|
||||||
typedef BasicRoutingInterface<QueryDataT> super;
|
typedef BasicRoutingInterface<DataFacadeT> super;
|
||||||
typedef typename QueryDataT::Graph SearchGraph;
|
typedef SearchEngineData::QueryGraph SearchGraph;
|
||||||
typedef typename QueryDataT::QueryHeap QueryHeap;
|
typedef SearchEngineData::QueryHeap QueryHeap;
|
||||||
typedef std::pair<NodeID, NodeID> SearchSpaceEdge;
|
typedef std::pair<NodeID, NodeID> SearchSpaceEdge;
|
||||||
|
|
||||||
struct RankedCandidateNode {
|
struct RankedCandidateNode {
|
||||||
@ -48,10 +49,10 @@ class AlternativeRouting : private BasicRoutingInterface<QueryDataT> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SearchGraph * search_graph;
|
const SearchGraph * search_graph;
|
||||||
|
SearchEngineData & engine_working_data;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AlternativeRouting(QueryDataT & qd) : super(qd), search_graph(qd.graph) { }
|
AlternativeRouting(DataFacadeT & qd, SearchEngineData & engine_working_data) : super(qd), search_graph(qd.graph), engine_working_data(engine_working_data) { }
|
||||||
|
|
||||||
~AlternativeRouting() {}
|
~AlternativeRouting() {}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define BASICROUTINGINTERFACE_H_
|
#define BASICROUTINGINTERFACE_H_
|
||||||
|
|
||||||
#include "../DataStructures/RawRouteData.h"
|
#include "../DataStructures/RawRouteData.h"
|
||||||
|
#include "../DataStructures/SearchEngineData.h"
|
||||||
#include "../Util/ContainerUtils.h"
|
#include "../Util/ContainerUtils.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
|
||||||
@ -34,15 +35,22 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
template<class QueryDataT>
|
template<class SearchEngineDataT>
|
||||||
class BasicRoutingInterface : boost::noncopyable{
|
class BasicRoutingInterface : boost::noncopyable{
|
||||||
protected:
|
protected:
|
||||||
QueryDataT & _queryData;
|
SearchEngineDataT * engine_working_data;
|
||||||
public:
|
public:
|
||||||
BasicRoutingInterface(QueryDataT & qd) : _queryData(qd) { }
|
BasicRoutingInterface(SearchEngineDataT * engine_working_data) : engine_working_data(engine_working_data) { }
|
||||||
virtual ~BasicRoutingInterface(){ };
|
virtual ~BasicRoutingInterface(){ };
|
||||||
|
|
||||||
inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const {
|
inline void RoutingStep(
|
||||||
|
SearchEngineData::QueryHeap & _forwardHeap,
|
||||||
|
SearchEngineData::QueryHeap & _backwardHeap,
|
||||||
|
NodeID *middle,
|
||||||
|
int *_upperbound,
|
||||||
|
const int edgeBasedOffset,
|
||||||
|
const bool forwardDirection
|
||||||
|
) const {
|
||||||
const NodeID node = _forwardHeap.DeleteMin();
|
const NodeID node = _forwardHeap.DeleteMin();
|
||||||
const int distance = _forwardHeap.GetKey(node);
|
const int distance = _forwardHeap.GetKey(node);
|
||||||
//SimpleLogger().Write() << "Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance;
|
//SimpleLogger().Write() << "Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance;
|
||||||
@ -63,11 +71,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Stalling
|
//Stalling
|
||||||
for ( typename QueryDataT::Graph::EdgeIterator edge = _queryData.graph->BeginEdges( node ); edge < _queryData.graph->EndEdges(node); ++edge ) {
|
for(
|
||||||
const typename QueryDataT::Graph::EdgeData & data = _queryData.graph->GetEdgeData(edge);
|
EdgeID edge = engine_working_data->BeginEdges( node );
|
||||||
|
edge < engine_working_data->EndEdges(node);
|
||||||
|
++edge
|
||||||
|
) {
|
||||||
|
const typename SearchEngineDataT::EdgeData & data = engine_working_data->GetEdgeData(edge);
|
||||||
bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward;
|
bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward;
|
||||||
if(backwardDirectionFlag) {
|
if(backwardDirectionFlag) {
|
||||||
const NodeID to = _queryData.graph->GetTarget(edge);
|
const NodeID to = engine_working_data->GetTarget(edge);
|
||||||
const int edgeWeight = data.distance;
|
const int edgeWeight = data.distance;
|
||||||
|
|
||||||
assert( edgeWeight > 0 );
|
assert( edgeWeight > 0 );
|
||||||
@ -80,12 +92,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( typename QueryDataT::Graph::EdgeIterator edge = _queryData.graph->BeginEdges( node ); edge < _queryData.graph->EndEdges(node); ++edge ) {
|
for ( EdgeID edge = engine_working_data->BeginEdges( node ); edge < engine_working_data->EndEdges(node); ++edge ) {
|
||||||
const typename QueryDataT::Graph::EdgeData & data = _queryData.graph->GetEdgeData(edge);
|
const typename SearchEngineDataT::EdgeData & data = engine_working_data->GetEdgeData(edge);
|
||||||
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward );
|
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward );
|
||||||
if(forwardDirectionFlag) {
|
if(forwardDirectionFlag) {
|
||||||
|
|
||||||
const NodeID to = _queryData.graph->GetTarget(edge);
|
const NodeID to = engine_working_data->GetTarget(edge);
|
||||||
const int edgeWeight = data.distance;
|
const int edgeWeight = data.distance;
|
||||||
|
|
||||||
assert( edgeWeight > 0 );
|
assert( edgeWeight > 0 );
|
||||||
@ -119,20 +131,20 @@ public:
|
|||||||
edge = recursionStack.top();
|
edge = recursionStack.top();
|
||||||
recursionStack.pop();
|
recursionStack.pop();
|
||||||
|
|
||||||
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
EdgeID smallestEdge = SPECIAL_EDGEID;
|
||||||
int smallestWeight = INT_MAX;
|
int smallestWeight = INT_MAX;
|
||||||
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){
|
for(EdgeID eit = engine_working_data->BeginEdges(edge.first);eit < engine_working_data->EndEdges(edge.first);++eit){
|
||||||
const int weight = _queryData.graph->GetEdgeData(eit).distance;
|
const int weight = engine_working_data->GetEdgeData(eit).distance;
|
||||||
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){
|
if(engine_working_data->GetTarget(eit) == edge.second && weight < smallestWeight && engine_working_data->GetEdgeData(eit).forward){
|
||||||
smallestEdge = eit;
|
smallestEdge = eit;
|
||||||
smallestWeight = weight;
|
smallestWeight = weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(smallestEdge == SPECIAL_EDGEID){
|
if(smallestEdge == SPECIAL_EDGEID){
|
||||||
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.second);eit < _queryData.graph->EndEdges(edge.second);++eit){
|
for(EdgeID eit = engine_working_data->BeginEdges(edge.second);eit < engine_working_data->EndEdges(edge.second);++eit){
|
||||||
const int weight = _queryData.graph->GetEdgeData(eit).distance;
|
const int weight = engine_working_data->GetEdgeData(eit).distance;
|
||||||
if(_queryData.graph->GetTarget(eit) == edge.first && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).backward){
|
if(engine_working_data->GetTarget(eit) == edge.first && weight < smallestWeight && engine_working_data->GetEdgeData(eit).backward){
|
||||||
smallestEdge = eit;
|
smallestEdge = eit;
|
||||||
smallestWeight = weight;
|
smallestWeight = weight;
|
||||||
}
|
}
|
||||||
@ -140,7 +152,7 @@ public:
|
|||||||
}
|
}
|
||||||
assert(smallestWeight != INT_MAX);
|
assert(smallestWeight != INT_MAX);
|
||||||
|
|
||||||
const typename QueryDataT::Graph::EdgeData& ed = _queryData.graph->GetEdgeData(smallestEdge);
|
const typename SearchEngineDataT::EdgeData& ed = engine_working_data->GetEdgeData(smallestEdge);
|
||||||
if(ed.shortcut) {//unpack
|
if(ed.shortcut) {//unpack
|
||||||
const NodeID middle = ed.id;
|
const NodeID middle = ed.id;
|
||||||
//again, we need to this in reversed order
|
//again, we need to this in reversed order
|
||||||
@ -151,8 +163,8 @@ public:
|
|||||||
unpackedPath.push_back(
|
unpackedPath.push_back(
|
||||||
_PathData(
|
_PathData(
|
||||||
ed.id,
|
ed.id,
|
||||||
_queryData.nodeHelpDesk->GetNameIndexFromEdgeID(ed.id),
|
engine_working_data->GetNameIndexFromEdgeID(ed.id),
|
||||||
_queryData.nodeHelpDesk->GetTurnInstructionForEdgeID(ed.id),
|
engine_working_data->GetTurnInstructionForEdgeID(ed.id),
|
||||||
ed.distance
|
ed.distance
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -169,20 +181,20 @@ public:
|
|||||||
edge = recursionStack.top();
|
edge = recursionStack.top();
|
||||||
recursionStack.pop();
|
recursionStack.pop();
|
||||||
|
|
||||||
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
EdgeID smallestEdge = SPECIAL_EDGEID;
|
||||||
int smallestWeight = INT_MAX;
|
int smallestWeight = INT_MAX;
|
||||||
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){
|
for(EdgeID eit = engine_working_data->BeginEdges(edge.first);eit < engine_working_data->EndEdges(edge.first);++eit){
|
||||||
const int weight = _queryData.graph->GetEdgeData(eit).distance;
|
const int weight = engine_working_data->GetEdgeData(eit).distance;
|
||||||
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){
|
if(engine_working_data->GetTarget(eit) == edge.second && weight < smallestWeight && engine_working_data->GetEdgeData(eit).forward){
|
||||||
smallestEdge = eit;
|
smallestEdge = eit;
|
||||||
smallestWeight = weight;
|
smallestWeight = weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(smallestEdge == SPECIAL_EDGEID){
|
if(smallestEdge == SPECIAL_EDGEID){
|
||||||
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.second);eit < _queryData.graph->EndEdges(edge.second);++eit){
|
for(EdgeID eit = engine_working_data->BeginEdges(edge.second);eit < engine_working_data->EndEdges(edge.second);++eit){
|
||||||
const int weight = _queryData.graph->GetEdgeData(eit).distance;
|
const int weight = engine_working_data->GetEdgeData(eit).distance;
|
||||||
if(_queryData.graph->GetTarget(eit) == edge.first && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).backward){
|
if(engine_working_data->GetTarget(eit) == edge.first && weight < smallestWeight && engine_working_data->GetEdgeData(eit).backward){
|
||||||
smallestEdge = eit;
|
smallestEdge = eit;
|
||||||
smallestWeight = weight;
|
smallestWeight = weight;
|
||||||
}
|
}
|
||||||
@ -190,7 +202,7 @@ public:
|
|||||||
}
|
}
|
||||||
assert(smallestWeight != INT_MAX);
|
assert(smallestWeight != INT_MAX);
|
||||||
|
|
||||||
const typename QueryDataT::Graph::EdgeData& ed = _queryData.graph->GetEdgeData(smallestEdge);
|
const typename SearchEngineDataT::EdgeData& ed = engine_working_data->GetEdgeData(smallestEdge);
|
||||||
if(ed.shortcut) {//unpack
|
if(ed.shortcut) {//unpack
|
||||||
const NodeID middle = ed.id;
|
const NodeID middle = ed.id;
|
||||||
//again, we need to this in reversed order
|
//again, we need to this in reversed order
|
||||||
@ -204,7 +216,12 @@ public:
|
|||||||
unpackedPath.push_back(t);
|
unpackedPath.push_back(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RetrievePackedPathFromHeap(typename QueryDataT::QueryHeap & _fHeap, typename QueryDataT::QueryHeap & _bHeap, const NodeID middle, std::vector<NodeID>& packedPath) const {
|
inline void RetrievePackedPathFromHeap(
|
||||||
|
SearchEngineData::QueryHeap & _fHeap,
|
||||||
|
SearchEngineData::QueryHeap & _bHeap,
|
||||||
|
const NodeID middle,
|
||||||
|
std::vector<NodeID> & packedPath
|
||||||
|
) const {
|
||||||
NodeID pathNode = middle;
|
NodeID pathNode = middle;
|
||||||
while(pathNode != _fHeap.GetData(pathNode).parent) {
|
while(pathNode != _fHeap.GetData(pathNode).parent) {
|
||||||
pathNode = _fHeap.GetData(pathNode).parent;
|
pathNode = _fHeap.GetData(pathNode).parent;
|
||||||
@ -220,7 +237,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RetrievePackedPathFromSingleHeap(typename QueryDataT::QueryHeap & search_heap, const NodeID middle, std::vector<NodeID>& packed_path) const {
|
inline void RetrievePackedPathFromSingleHeap(SearchEngineData::QueryHeap & search_heap, const NodeID middle, std::vector<NodeID>& packed_path) const {
|
||||||
NodeID pathNode = middle;
|
NodeID pathNode = middle;
|
||||||
while(pathNode != search_heap.GetData(pathNode).parent) {
|
while(pathNode != search_heap.GetData(pathNode).parent) {
|
||||||
pathNode = search_heap.GetData(pathNode).parent;
|
pathNode = search_heap.GetData(pathNode).parent;
|
||||||
|
@ -25,12 +25,15 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include "BasicRoutingInterface.h"
|
#include "BasicRoutingInterface.h"
|
||||||
|
|
||||||
|
#include "../DataStructures/SearchEngineData.h"
|
||||||
|
|
||||||
template<class QueryDataT>
|
template<class QueryDataT>
|
||||||
class ShortestPathRouting : public BasicRoutingInterface<QueryDataT>{
|
class ShortestPathRouting : public BasicRoutingInterface<QueryDataT>{
|
||||||
typedef BasicRoutingInterface<QueryDataT> super;
|
typedef BasicRoutingInterface<QueryDataT> super;
|
||||||
typedef typename QueryDataT::QueryHeap QueryHeap;
|
typedef typename QueryDataT::QueryHeap QueryHeap;
|
||||||
|
SearchEngineData & engine_working_data;
|
||||||
public:
|
public:
|
||||||
ShortestPathRouting( QueryDataT & qd) : super(qd) {}
|
ShortestPathRouting( QueryDataT & qd, SearchEngineData & engine_working_data) : super(qd), engine_working_data(engine_working_data) {}
|
||||||
|
|
||||||
~ShortestPathRouting() {}
|
~ShortestPathRouting() {}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user