Implemented T-Test and output of route options

This commit is contained in:
DennisOSRM 2012-06-19 17:26:34 +02:00
parent 5ebc4b392f
commit 61efd41194
11 changed files with 544 additions and 488 deletions

View File

@ -248,7 +248,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
if(turnInstruction == TurnInstructions.UTurn)
distance += uturnPenalty;
if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
distance += TurnInstructions.AccessRestrictionPenaly;
distance += TurnInstructions.AccessRestrictionPenalty;
turnInstruction |= TurnInstructions.AccessRestrictionFlag;
}

View File

@ -56,6 +56,8 @@ struct SearchEngineData {
static HeapPtr backwardHeap;
static HeapPtr forwardHeap2;
static HeapPtr backwardHeap2;
static HeapPtr forwardHeap3;
static HeapPtr backwardHeap3;
inline void InitializeOrClearFirstThreadLocalStorage() {
if(!forwardHeap.get()) {
@ -84,6 +86,20 @@ struct SearchEngineData {
else
backwardHeap2->Clear();
}
inline void InitializeOrClearThirdThreadLocalStorage() {
if(!forwardHeap3.get()) {
forwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
forwardHeap3->Clear();
if(!backwardHeap3.get()) {
backwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage<NodeID, int> >(nodeHelpDesk->getNumberOfNodes()));
}
else
backwardHeap3->Clear();
}
};
template<class EdgeData, class GraphT>
@ -149,4 +165,7 @@ template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<Edge
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap2;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap2;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::forwardHeap3;
template<class EdgeData, class GraphT> SearchEngineHeapPtr SearchEngineData<EdgeData, GraphT>::backwardHeap3;
#endif /* SEARCHENGINE_H_ */

View File

@ -46,7 +46,7 @@ struct TurnInstructionsClass {
const static short AccessRestrictionFlag = (1<<14);
const static short InverseAccessRestrictionFlag = ~(1<<14);
const static int AccessRestrictionPenaly = 1 << 15; //unrelated to the bit set in the restriction flag
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag
// std::string TurnStrings[16];
// std::string Ordinals[12];

View File

@ -48,7 +48,7 @@ public:
BaseDescriptor() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() { }
virtual void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) = 0;
virtual void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) = 0;
virtual void SetConfig(const _DescriptorConfig & config) = 0;
};

View File

@ -33,20 +33,20 @@ private:
std::string tmp;
public:
void SetConfig(const _DescriptorConfig& c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) {
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content += "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">";
reply.content += "<rte>";
if(distance != UINT_MAX && rawRoute.computedRouted.size()) {
if(rawRoute.lengthOfShortestPath != UINT_MAX && rawRoute.computedShortestPath.size()) {
convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
BOOST_FOREACH(_PathData pathData, rawRoute.computedRouted) {
BOOST_FOREACH(_PathData pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
convertInternalLatLonToString(current.lat, tmp);

View File

@ -36,6 +36,7 @@ class JSONDescriptor : public BaseDescriptor<SearchEngineT>{
private:
_DescriptorConfig config;
DescriptionFactory descriptionFactory;
DescriptionFactory alternateDescriptionFactory;
_Coordinate current;
unsigned numberOfEnteredRestrictedAreas;
struct {
@ -48,15 +49,15 @@ public:
JSONDescriptor() : numberOfEnteredRestrictedAreas(0) {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, const unsigned durationOfTrip) {
void Run(http::Reply & reply, const RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine) {
WriteHeaderToOutput(reply.content);
if(durationOfTrip != INT_MAX) {
if(rawRoute.lengthOfShortestPath != INT_MAX) {
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
reply.content += "0,"
"\"status_message\": \"Found route between points\",";
//Get all the coordinates for the computed route
BOOST_FOREACH(_PathData & pathData, rawRoute.computedRouted) {
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedShortestPath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
descriptionFactory.AppendSegment(current, pathData );
}
@ -67,7 +68,7 @@ public:
"\"status_message\": \"Cannot find route between points\",";
}
descriptionFactory.Run(sEngine, config.z, durationOfTrip);
descriptionFactory.Run(sEngine, config.z, rawRoute.lengthOfShortestPath);
reply.content += "\"route_geometry\": ";
if(config.geometry) {
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
@ -77,85 +78,9 @@ public:
reply.content += ","
"\"route_instructions\": [";
numberOfEnteredRestrictedAreas = 0;
if(config.instructions) {
//Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
//Fetch data from Factory and generate a string from it.
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
reply.content += ",";
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
intToString(roundAbout.leaveAtExit+1, tmpInstruction);
reply.content += tmpInstruction;
roundAbout.leaveAtExit = 0;
} else {
intToString(currentInstruction, tmpInstruction);
reply.content += tmpInstruction;
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
intToString(segment.duration, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
}
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
++roundAbout.leaveAtExit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
}
if(durationOfTrip != INT_MAX) {
reply.content += ",[\"";
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "\",\"";
reply.content += "\",";
reply.content += "0";
reply.content += ",";
intToString(prefixSumOfNecessarySegments-1, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content += "0";
reply.content += ",\"";
reply.content += "\",\"";
reply.content += Azimuth::Get(0.0);
reply.content += "\",";
reply.content += "0.0";
reply.content += "]";
}
BuildTextualDescription(descriptionFactory, reply, rawRoute.lengthOfShortestPath, sEngine);
} else {
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
@ -163,11 +88,11 @@ public:
}
}
reply.content += "],";
// INFO("Entered " << numberOfEnteredRestrictedAreas << " restricted areas");
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, durationOfTrip - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenaly));
descriptionFactory.BuildRouteSummary(descriptionFactory.entireLength, rawRoute.lengthOfShortestPath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content += "\"route_summary\": {"
"\"total_distance\":";
reply.content += "\"route_summary\":";
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += descriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
@ -179,12 +104,54 @@ public:
"\"end_point\":\"";
reply.content += sEngine.GetEscapedNameForNameID(descriptionFactory.summary.destName);
reply.content += "\"";
reply.content += "},";
reply.content += "}";
reply.content +=",";
//only one alternative route is computed at this time, so this is hardcoded
if(rawRoute.lengthOfAlternativePath != INT_MAX) {
alternateDescriptionFactory.SetStartSegment(phantomNodes.startPhantom);
//Get all the coordinates for the computed route
BOOST_FOREACH(const _PathData & pathData, rawRoute.computedAlternativePath) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
alternateDescriptionFactory.AppendSegment(current, pathData );
}
alternateDescriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
}
alternateDescriptionFactory.Run(sEngine, config.z, rawRoute.lengthOfAlternativePath);
//give an array of alternative routes
reply.content += "\"alternative_geometries\": [";
if(config.geometry) {
//Generate the linestrings for each alternative
alternateDescriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
}
reply.content += "],";
reply.content += "\"alternative_instructions\":[";
if(config.instructions) {
reply.content += "[";
//Generate instructions for each alternative
BuildTextualDescription(alternateDescriptionFactory, reply, rawRoute.lengthOfAlternativePath, sEngine);
reply.content += "]";
}
reply.content += "],";
reply.content += "\"alternative_summaries\":[";
//Generate route summary (length, duration) for each alternative
alternateDescriptionFactory.BuildRouteSummary(alternateDescriptionFactory.entireLength, rawRoute.lengthOfAlternativePath - ( numberOfEnteredRestrictedAreas*TurnInstructions.AccessRestrictionPenalty));
reply.content += "{";
reply.content += "\"total_distance\":";
reply.content += alternateDescriptionFactory.summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += alternateDescriptionFactory.summary.durationString;
reply.content += "}";
reply.content += "],";
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
std::string tmp;
if(config.geometry && INT_MAX != durationOfTrip) {
if(config.geometry && INT_MAX != rawRoute.lengthOfShortestPath) {
for(unsigned i = 0; i < rawRoute.segmentEndCoordinates.size(); ++i) {
reply.content += "[";
if(rawRoute.segmentEndCoordinates[i].startPhantom.location.isSet())
@ -231,5 +198,88 @@ public:
"\"version\": 0.3,"
"\"status\":";
}
inline void BuildTextualDescription(DescriptionFactory & descriptionFactory, http::Reply & reply, const int lengthOfRoute, const SearchEngineT &sEngine) {
//Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction;
//Fetch data from Factory and generate a string from it.
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
short currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
numberOfEnteredRestrictedAreas += (currentInstruction != segment.turnInstruction);
if(TurnInstructions.TurnIsNecessary( currentInstruction) ) {
if(TurnInstructions.EnterRoundAbout == currentInstruction) {
roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments){
reply.content += ",";
}
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == currentInstruction) {
intToString(TurnInstructions.EnterRoundAbout, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "-";
intToString(roundAbout.leaveAtExit+1, tmpInstruction);
reply.content += tmpInstruction;
roundAbout.leaveAtExit = 0;
} else {
intToString(currentInstruction, tmpInstruction);
reply.content += tmpInstruction;
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
intToString(segment.duration, tmpDuration);
reply.content += tmpDuration;
reply.content += ",\"";
intToString(segment.length, tmpLength);
reply.content += tmpLength;
reply.content += "m\",\"";
reply.content += Azimuth::Get(segment.bearing);
reply.content += "\",";
intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing;
reply.content += "]";
}
} else if(TurnInstructions.StayOnRoundAbout == currentInstruction) {
++roundAbout.leaveAtExit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
}
if(INT_MAX != lengthOfRoute) {
reply.content += ",[\"";
intToString(TurnInstructions.ReachedYourDestination, tmpInstruction);
reply.content += tmpInstruction;
reply.content += "\",\"";
reply.content += "\",";
reply.content += "0";
reply.content += ",";
intToString(prefixSumOfNecessarySegments-1, tmpLength);
reply.content += tmpLength;
reply.content += ",";
reply.content += "0";
reply.content += ",\"";
reply.content += "\",\"";
reply.content += Azimuth::Get(0.0);
reply.content += "\",";
reply.content += "0.0";
reply.content += "]";
}
}
};
#endif /* JSON_DESCRIPTOR_H_ */

View File

@ -22,10 +22,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define RAWROUTEDATA_H_
struct RawRouteData {
std::vector< _PathData > computedRouted;
std::vector< _PathData > computedShortestPath;
std::vector< _PathData > computedAlternativePath;
std::vector< PhantomNodes > segmentEndCoordinates;
std::vector< _Coordinate > rawViaNodeCoordinates;
unsigned checkSum;
int lengthOfShortestPath;
int lengthOfAlternativePath;
};
#endif /* RAWROUTEDATA_H_ */

View File

@ -112,38 +112,39 @@ public:
// INFO("Brute force lookup of coordinate " << i);
searchEngine->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i]);
}
unsigned distance = 0;
//unsigned distance = 0;
for(unsigned i = 0; i < phantomNodeVector.size()-1; ++i) {
PhantomNodes segmentPhantomNodes;
segmentPhantomNodes.startPhantom = phantomNodeVector[i];
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1];
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
}
distance = searchEngine->shortestPath(rawRoute.segmentEndCoordinates, rawRoute.computedRouted);
std::vector<_PathData> alternative;
if(1 == rawRoute.segmentEndCoordinates.size()) {
INFO("Checking for alternative paths");
int distance2 = searchEngine->alternativePaths(rawRoute.segmentEndCoordinates[0], alternative);
}
std::cout << "latitude,longitude" << std::endl;
for(unsigned i = 0; i < rawRoute.computedRouted.size(); ++i) {
_Coordinate current;
searchEngine->GetCoordinatesForNodeID(rawRoute.computedRouted[i].node, current);
std::cout << current.lat/100000. << "," << current.lon/100000. << std::endl;
}
std::cout << std::endl;
// INFO("Checking for alternative paths");
searchEngine->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute);
std::cout << "latitude,longitude" << std::endl;
for(unsigned i = 0; i <alternative.size(); ++i) {
_Coordinate current;
searchEngine->GetCoordinatesForNodeID(alternative[i].node, current);
std::cout << current.lat/100000. << "," << current.lon/100000. << std::endl;
} else {
searchEngine->shortestPath(rawRoute.segmentEndCoordinates, rawRoute);
}
std::cout << std::endl;
// std::cout << "latitude,longitude" << std::endl;
// for(unsigned i = 0; i < rawRoute.computedShortestPath.size(); ++i) {
// _Coordinate current;
// searchEngine->GetCoordinatesForNodeID(rawRoute.computedShortestPath[i].node, current);
// std::cout << current.lat/100000. << "," << current.lon/100000. << std::endl;
// }
// std::cout << std::endl;
//
// std::cout << "latitude,longitude" << std::endl;
// for(unsigned i = 0; i < rawRoute.computedAlternativePath.size(); ++i) {
// _Coordinate current;
// searchEngine->GetCoordinatesForNodeID(rawRoute.computedAlternativePath[i].node, current);
// std::cout << current.lat/100000. << "," << current.lon/100000. << std::endl;
// }
// std::cout << std::endl;
if(INT_MAX == distance ) {
if(INT_MAX == rawRoute.lengthOfShortestPath ) {
DEBUG( "Error occurred, single path not found" );
}
reply.status = http::Reply::ok;
@ -197,7 +198,7 @@ public:
// INFO("Number of segments: " << rawRoute.segmentEndCoordinates.size());
desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEngine, distance);
desc->Run(reply, rawRoute, phantomNodes, *searchEngine);
if("" != JSONParameter) {
reply.content += ")\n";
}

View File

@ -25,12 +25,15 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "BasicRoutingInterface.h"
const double VIAPATH_ALPHA = 0.25;
const double VIAPATH_EPSILON = 0.25;
const double VIAPATH_GAMMA = 0.80;
template<class QueryDataT>
class AlternativeRouting : private BasicRoutingInterface<QueryDataT>{
typedef BasicRoutingInterface<QueryDataT> super;
typedef std::pair<NodeID, int> PreselectedNode;
typedef typename QueryDataT::HeapPtr HeapPtr;
struct RankedCandidateNode {
RankedCandidateNode(NodeID n, int l, int s) : node(n), length(l), sharing(s) {}
@ -47,18 +50,18 @@ public:
~AlternativeRouting() {}
int operator()(const PhantomNodes & phantomNodePair, std::vector<_PathData> & unpackedPath) {
void operator()(const PhantomNodes & phantomNodePair, RawRouteData & rawRouteData) {
if(!phantomNodePair.AtLeastOnePhantomNodeIsUINTMAX()) {
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX;
return;
}
std::vector<NodeID> alternativePath;
std::vector<NodeID> viaNodeCandidates;
int _lengthOfShortestPath = INT_MAX;
INFO("Checking for alternative between (" << phantomNodePair.startPhantom.location << ") and (" << phantomNodePair.targetPhantom.location << ")");
typename QueryDataT::HeapPtr & forwardHeap = super::_queryData.forwardHeap;
typename QueryDataT::HeapPtr & backwardHeap = super::_queryData.backwardHeap;
typename QueryDataT::HeapPtr & forwardHeap2 = super::_queryData.forwardHeap2;
typename QueryDataT::HeapPtr & backwardHeap2 = super::_queryData.backwardHeap2;
HeapPtr & forwardHeap = super::_queryData.forwardHeap;
HeapPtr & backwardHeap = super::_queryData.backwardHeap;
HeapPtr & forwardHeap2 = super::_queryData.forwardHeap2;
HeapPtr & backwardHeap2 = super::_queryData.backwardHeap2;
//Initialize Queues
super::_queryData.InitializeOrClearFirstThreadLocalStorage();
@ -87,17 +90,20 @@ public:
}
std::sort(viaNodeCandidates.begin(), viaNodeCandidates.end());
int size = std::unique(viaNodeCandidates.begin(), viaNodeCandidates.end())- viaNodeCandidates.begin();
std::cout << "middle: " << middle << ", other: ";
for(unsigned i = 0; i < size; ++i)
if(middle != viaNodeCandidates[i])
std::cout << viaNodeCandidates[i] << " ";
std::cout << std::endl;
// std::cout << "middle: " << middle << ", other: ";
// for(unsigned i = 0; i < size; ++i)
// if(middle != viaNodeCandidates[i])
// std::cout << viaNodeCandidates[i] << " ";
// std::cout << std::endl;
viaNodeCandidates.resize(size);
INFO("found " << viaNodeCandidates.size() << " nodes in search space intersection");
// INFO("found " << viaNodeCandidates.size() << " nodes in search space intersection");
//
// INFO("upper bound: " << _upperBound);
std::deque<NodeID> packedShortestPath;
INFO("upper bound: " << _upperBound);
//TODO: save (packed) shortest path of shortest path and keep it for later use.
//save (packed) shortest path of shortest path and keep it for later use.
//we need it during the checks and dont want to recompute it always
super::RetrievePackedPathFromHeap(forwardHeap, backwardHeap, middle, packedShortestPath);
//ch-pruning of via nodes in both search spaces
@ -107,19 +113,19 @@ public:
if(node == middle)
continue;
// std::cout << "via path over " << node << std::endl;
int sharing = approximateAmountOfSharing(middle, node, forwardHeap, backwardHeap);
// std::cout << "via path over " << node << std::endl;
int sharing = approximateAmountOfSharing(node, forwardHeap, backwardHeap, packedShortestPath);
int length1 = forwardHeap->GetKey(node);
int length2 = backwardHeap->GetKey(node);
// std::cout << " length: " << length1+length2 << std::endl;
bool lengthPassed = (length1+length2 < _upperBound*1.25);
// std::cout << " length passed: " << (lengthPassed ? "yes" : "no") << std::endl;
// std::cout << " apx-sharing: " << sharing << std::endl;
bool sharingPassed = (sharing <= _upperBound*0.8);
// std::cout << " apx-sharing passed: " << ( sharingPassed ? "yes" : "no") << std::endl;
bool stretchPassed = length1+length2 - sharing < 1.25*(_upperBound-sharing);
// std::cout << " apx-stretch passed: " << ( stretchPassed ? "yes" : "no") << std::endl;
// std::cout << " length: " << length1+length2 << std::endl;
bool lengthPassed = (length1+length2 < _upperBound*(1+VIAPATH_EPSILON));
// std::cout << " length passed: " << (lengthPassed ?osrm "yes" : "no") << std::endl;
// std::cout << " apx-sharing: " << sharing << std::endl;
bool sharingPassed = (sharing <= _upperBound*VIAPATH_GAMMA);
// std::cout << " apx-sharing passed: " << ( sharingPassed ? "yes" : "no") << std::endl;
bool stretchPassed = length1+length2 - sharing < (1.+VIAPATH_EPSILON)*(_upperBound-sharing);
// std::cout << " apx-stretch passed: " << ( stretchPassed ? "yes" : "no") << std::endl;
if(lengthPassed && sharingPassed && stretchPassed)
nodesThatPassPreselection.push_back(std::make_pair(node, length1+length2));
@ -127,177 +133,153 @@ public:
std::vector<RankedCandidateNode > rankedCandidates;
INFO(nodesThatPassPreselection.size() << " out of " << viaNodeCandidates.size() << " passed preselection");
// INFO(nodesThatPassPreselection.size() << " out of " << viaNodeCandidates.size() << " passed preselection");
//prioritizing via nodes
BOOST_FOREACH(const PreselectedNode node, nodesThatPassPreselection) {
int lengthOfViaPath = 0;
int sharingOfViaPath = 0;
computeLengthAndSharingOfViaPath(phantomNodePair, node, &lengthOfViaPath, &sharingOfViaPath, offset, middle);
computeLengthAndSharingOfViaPath(phantomNodePair, node, &lengthOfViaPath, &sharingOfViaPath, offset, packedShortestPath);
rankedCandidates.push_back(RankedCandidateNode(node.first, lengthOfViaPath, sharingOfViaPath));
}
std::sort(rankedCandidates.begin(), rankedCandidates.end());
NodeID selectedViaNode = UINT_MAX;
int lengthOfViaPath = INT_MAX;
BOOST_FOREACH(const RankedCandidateNode candidate, rankedCandidates){
//conduct T-Test
if(viaNodeCandidatePasses_T_Test(forwardHeap, backwardHeap, forwardHeap2, backwardHeap2, candidate, offset, middle, _upperBound)) {
if(viaNodeCandidatePasses_T_Test(forwardHeap, backwardHeap, forwardHeap2, backwardHeap2, candidate, offset, middle, _upperBound, &lengthOfViaPath)) {
// select first admissable
selectedViaNode = candidate.node;
break;
}
}
//compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues
//Same (co-)routines necessary as for computing length and sharing
if(selectedViaNode != UINT_MAX) {
//Unpack shortest path and alternative, if they exist
if(INT_MAX != _upperBound)
super::UnpackPath(packedShortestPath, rawRouteData.computedShortestPath);
retrievePackedViaPath(forwardHeap, backwardHeap, forwardHeap2, backwardHeap2, selectedViaNode, unpackedPath);
}
return 0;
if(selectedViaNode != UINT_MAX)
retrievePackedViaPath(forwardHeap, backwardHeap, forwardHeap2, backwardHeap2, selectedViaNode, rawRouteData.computedAlternativePath);
rawRouteData.lengthOfShortestPath = _upperBound;
rawRouteData.lengthOfAlternativePath = lengthOfViaPath;
}
private:
inline void retrievePackedViaPath(typename QueryDataT::HeapPtr & _forwardHeap1, typename QueryDataT::HeapPtr & _backwardHeap1, typename QueryDataT::HeapPtr & _forwardHeap2, typename QueryDataT::HeapPtr & _backwardHeap2, const NodeID viaNode, std::vector<_PathData> & unpackedPath) {
//unpack <s,..,v,..,t> by exploring search spaces from v
inline void retrievePackedViaPath(HeapPtr & _forwardHeap1, HeapPtr & _backwardHeap1, HeapPtr & _forwardHeap2, HeapPtr & _backwardHeap2, const NodeID viaNode, std::vector<_PathData> & unpackedPath) {
//unpack s,v
std::deque<NodeID> packed_s_v_path, packed_v_t_path;
std::cout << "1" << std::endl;
// std::cout << "1" << std::endl;
super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, viaNode, packed_s_v_path);
std::cout << "2" << std::endl;
// std::cout << "2" << std::endl;
packed_s_v_path.resize(packed_s_v_path.size()-1);
super::RetrievePackedPathFromHeap(_forwardHeap2, _backwardHeap1, viaNode, packed_v_t_path);
std::cout << "3" << std::endl;
// std::cout << "3" << std::endl;
packed_s_v_path.insert(packed_s_v_path.end(),packed_v_t_path.begin(), packed_v_t_path.end() );
std::cout << "4" << std::endl;
// std::cout << "4" << std::endl;
for(unsigned i = 0; i < packed_s_v_path.size(); ++i)
std::cout << packed_s_v_path[i] << " " << std::endl;
std::cout << std::endl;
// for(unsigned i = 0; i < packed_s_v_path.size(); ++i)
// std::cout << packed_s_v_path[i] << " " << std::endl;
// std::cout << std::endl;
super::UnpackPath(packed_s_v_path, unpackedPath);
}
inline void computeLengthAndSharingOfViaPath(const PhantomNodes & phantomNodePair, const PreselectedNode& node, int *lengthOfViaPath, int *sharingOfViaPath, const int offset, const NodeID middleOfShortestPath) {
inline void computeLengthAndSharingOfViaPath(const PhantomNodes & phantomNodePair, const PreselectedNode& node, int *lengthOfViaPath, int *sharingOfViaPath, const int offset, const std::deque<NodeID> & packedShortestPath) {
//compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues
//only half-searches have to be done at this stage
std::cout << "deep check for via path " << node.first << std::endl;
// std::cout << "deep check for via path " << node.first << std::endl;
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
typename QueryDataT::HeapPtr & existingForwardHeap = super::_queryData.forwardHeap;
typename QueryDataT::HeapPtr & existingBackwardHeap = super::_queryData.backwardHeap;
typename QueryDataT::HeapPtr & newForwardHeap = super::_queryData.forwardHeap2;
typename QueryDataT::HeapPtr & newBackwardHeap = super::_queryData.backwardHeap2;
HeapPtr & existingForwardHeap = super::_queryData.forwardHeap;
HeapPtr & existingBackwardHeap = super::_queryData.backwardHeap;
HeapPtr & newForwardHeap = super::_queryData.forwardHeap2;
HeapPtr & newBackwardHeap = super::_queryData.backwardHeap2;
NodeID s_v_middle = UINT_MAX;
int upperBoundFor_s_v_Path = INT_MAX;//existingForwardHeap->GetKey(node.first);
//compute path <s,..,v> by reusing forward search from s
int upperBoundFor_s_v_Path = INT_MAX;//compute path <s,..,v> by reusing forward search from s
newBackwardHeap->Insert(node.first, 0, node.first);
while(newBackwardHeap->Size() > 0){
super::RoutingStep(newBackwardHeap, existingForwardHeap, &s_v_middle, &upperBoundFor_s_v_Path, 2*offset, false);
while (newBackwardHeap->Size() > 0) {
super::RoutingStep(newBackwardHeap, existingForwardHeap, &s_v_middle, &upperBoundFor_s_v_Path, 2 * offset, false);
}
std::cout << " length of <s,..,v>: " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl;
// std::cout << " length of <s,..,v>: " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl;
//compute path <v,..,t> by reusing backward search from t
NodeID v_t_middle = UINT_MAX;
int upperBoundFor_v_t_Path = INT_MAX;//existingBackwardHeap->GetKey(node.first);
int upperBoundFor_v_t_Path = INT_MAX;
newForwardHeap->Insert(node.first, 0, node.first);
while(newForwardHeap->Size() > 0){
super::RoutingStep(newForwardHeap, existingBackwardHeap, &v_t_middle, &upperBoundFor_v_t_Path, 2*offset, true);
while (newForwardHeap->Size() > 0) {
super::RoutingStep(newForwardHeap, existingBackwardHeap,
&v_t_middle, &upperBoundFor_v_t_Path, 2 * offset, true);
}
std::cout << " length of <v,..,t>: " << upperBoundFor_v_t_Path << " with middle node " << v_t_middle << std::endl;
// std::cout << " length of <v,..,t>: " << upperBoundFor_v_t_Path << " with middle node " << v_t_middle << std::endl;
*lengthOfViaPath = upperBoundFor_s_v_Path + upperBoundFor_v_t_Path;
// std::cout << " exact length of via path: " << *lengthOfViaPath << std::endl;
*lengthOfViaPath = upperBoundFor_s_v_Path+upperBoundFor_v_t_Path;
std::cout << " exact length of via path: " << *lengthOfViaPath << std::endl;
std::deque<NodeID> packedShortestPath;
std::deque<NodeID> packed_s_v_path;
std::deque<NodeID> packed_v_t_path;
std::deque < NodeID > packed_s_v_path;
std::deque < NodeID > packed_v_t_path;
//retrieve packed paths
std::cout << " retrieving packed path for middle nodes " << middleOfShortestPath << "," << s_v_middle << "," << v_t_middle << " (shorstest, sv, vt)" << std::endl;
super::RetrievePackedPathFromHeap(existingForwardHeap, existingBackwardHeap, middleOfShortestPath, packedShortestPath);
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, s_v_middle, packed_s_v_path);
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, v_t_middle,packed_v_t_path);
std::cout << "packed sv: ";
for(unsigned i = 0; i < packed_s_v_path.size(); ++i) {
std::cout << packed_s_v_path[i] << " ";
}
std::cout << std::endl;
std::cout << "packed vt: ";
for(unsigned i = 0; i < packed_v_t_path.size(); ++i) {
std::cout << packed_v_t_path[i] << " ";
}
std::cout << std::endl;
std::cout << "packed shortest: ";
for(unsigned i = 0; i < packedShortestPath.size(); ++i) {
std::cout << packedShortestPath[i] << " ";
}
std::cout << std::endl;
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, v_t_middle, packed_v_t_path);
typedef std::pair<NodeID, NodeID> UnpackEdge;
std::stack<UnpackEdge > unpackStack;
//TODO: partial unpacking, compute sharing
std::stack<UnpackEdge> unpackStack;
//partial unpacking, compute sharing
//First partially unpack s-->v until paths deviate, note length of common path.
std::cout << "length of packed sv-path: " << packed_s_v_path.size() << ", length of packed shortest path: " << packedShortestPath.size() << std::endl;
for(unsigned i = 0, lengthOfPackedPath = std::min(packed_s_v_path.size(), packedShortestPath.size() ) - 1; (i < lengthOfPackedPath) && unpackStack.empty(); ++i ) {
std::cout << " checking indices [" << i << "] and [" << (i+1) << "]" << std::endl;
if(packed_s_v_path[i] == packedShortestPath[i] && packed_s_v_path[i+1] == packedShortestPath[i+1]) {
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i+1]);
// std::cout << "length of packed sv-path: " << packed_s_v_path.size() << ", length of packed shortest path: " << packedShortestPath.size() << std::endl;
for (unsigned i = 0, lengthOfPackedPath = std::min( packed_s_v_path.size(), packedShortestPath.size()) - 1; (i < lengthOfPackedPath) && unpackStack.empty(); ++i) {
// std::cout << " checking indices [" << i << "] and [" << (i + 1) << "]" << std::endl;
if (packed_s_v_path[i] == packedShortestPath[i] && packed_s_v_path[i + 1] == packedShortestPath[i + 1]) {
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]);
*sharingOfViaPath += super::_queryData.graph->GetEdgeData(edgeID).distance;
} else {
if(packed_s_v_path[i] == packedShortestPath[i]) {
unpackStack.push(std::make_pair(packed_s_v_path[i], packed_s_v_path[i+1]));
unpackStack.push(std::make_pair(packedShortestPath[i], packedShortestPath[i+1]));
if (packed_s_v_path[i] == packedShortestPath[i]) {
unpackStack.push( std::make_pair(packed_s_v_path[i], packed_s_v_path[i + 1]));
unpackStack.push( std::make_pair(packedShortestPath[i], packedShortestPath[i + 1]));
}
}
}
while(!unpackStack.empty()) {
UnpackEdge shortestPathEdge = unpackStack.top(); unpackStack.pop();
UnpackEdge viaPathEdge = unpackStack.top(); unpackStack.pop();
std::cout << " unpacking edges (" << shortestPathEdge.first << "," << shortestPathEdge.second << ") and (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInShortestPath = super::_queryData.graph->FindEdgeInEitherDirection(shortestPathEdge.first, shortestPathEdge.second);
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
std::cout << " ids are " << edgeIDInShortestPath << " (shortest) and " << edgeIDInViaPath << " (via)" << std::endl;
while (!unpackStack.empty()) {
const UnpackEdge shortestPathEdge = unpackStack.top();
unpackStack.pop();
const UnpackEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
// std::cout << " unpacking edges (" << shortestPathEdge.first << "," << shortestPathEdge.second << ") and (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInShortestPath = super::_queryData.graph->FindEdgeInEitherDirection( shortestPathEdge.first, shortestPathEdge.second);
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
// std::cout << " ids are " << edgeIDInShortestPath << " (shortest) and " << edgeIDInViaPath << " (via)" << std::endl;
bool IsShortestPathEdgeShortCut = super::_queryData.graph->GetEdgeData(edgeIDInShortestPath).shortcut;
bool IsViaEdgeShortCut = super::_queryData.graph->GetEdgeData(edgeIDInViaPath).shortcut;
const NodeID middleOfShortestPath = !IsShortestPathEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInShortestPath).id;
const NodeID middleOfViaPath = !IsViaEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInViaPath).id;
const NodeID middleOfShortestPath = !IsShortestPathEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInShortestPath).id;
const NodeID middleOfViaPath = !IsViaEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInViaPath ).id;
if(IsShortestPathEdgeShortCut || IsViaEdgeShortCut) {
if(middleOfShortestPath != middleOfViaPath) { // unpack first segment
if (IsShortestPathEdgeShortCut || IsViaEdgeShortCut) {
if (middleOfShortestPath != middleOfViaPath) { // unpack first segment
//put first segment of via edge on stack, else take the segment already available
if(IsViaEdgeShortCut)
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath));
else
unpackStack.push(viaPathEdge);
if (IsViaEdgeShortCut)
unpackStack.push( std::make_pair(viaPathEdge.first, middleOfViaPath));
else unpackStack.push(viaPathEdge);
//put first segment of shortest path edge on stack if not a shortcut, else take the segment already available
if(IsShortestPathEdgeShortCut)
unpackStack.push(std::make_pair(shortestPathEdge.first, middleOfShortestPath));
else
unpackStack.push(shortestPathEdge);
if (IsShortestPathEdgeShortCut)
unpackStack.push( std::make_pair(shortestPathEdge.first, middleOfShortestPath));
else unpackStack.push(shortestPathEdge);
} else { // unpack second segment
if(IsViaEdgeShortCut)
unpackStack.push(std::make_pair(middleOfViaPath, viaPathEdge.second));
else
unpackStack.push(viaPathEdge);
if (IsViaEdgeShortCut)
unpackStack.push( std::make_pair(middleOfViaPath, viaPathEdge.second));
else unpackStack.push(viaPathEdge);
//put first segment of shortest path edge on stack if not a shortcut, else take the segment already available
if(IsShortestPathEdgeShortCut)
unpackStack.push(std::make_pair(middleOfShortestPath, shortestPathEdge.second ));
else
unpackStack.push(shortestPathEdge);
//put first segment of shortest path edge on stack if not a shortcut, else take the segment already available
if (IsShortestPathEdgeShortCut)
unpackStack.push( std::make_pair(middleOfShortestPath, shortestPathEdge.second));
else unpackStack.push(shortestPathEdge);
//add length of first segment to amount of sharing
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
@ -305,252 +287,82 @@ private:
}
}
}
std::cout << "sharing of SV-Path: " << *sharingOfViaPath << std::endl;
// std::cout << "sharing of SV-Path: " << *sharingOfViaPath << std::endl;
//Second, partially unpack v-->t in reverse until paths deviate and note lengths
unsigned viaPathIndex = packed_v_t_path.size()-1;
unsigned shortestPathIndex = packedShortestPath.size() -1;
std::cout << "length of packed vt-path: " << packed_v_t_path.size() << ", length of packed shortest path: " << packedShortestPath.size() << std::endl;
for( ; viaPathIndex>0 && shortestPathIndex>0; ) {
// std::cout << " checking indices [" << shortestPathIndex << "] and [" << (shortestPathIndex-1) << "] (shortest) as well as [" << shortestPathIndex << "] and [" << (shortestPathIndex-1) << "]" << std::endl;
if(packed_v_t_path[viaPathIndex-1] == packedShortestPath[shortestPathIndex-1] && packed_v_t_path[viaPathIndex] == packedShortestPath[shortestPathIndex]) {
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex]);
// std::cout << "Id of edge (" << packed_v_t_path[viaPathIndex-1] << "," << packed_v_t_path[viaPathIndex] << ") : " << edgeID << std::endl;
*sharingOfViaPath += super::_queryData.graph->GetEdgeData(edgeID).distance;
unsigned viaPathIndex = packed_v_t_path.size() - 1;
unsigned shortestPathIndex = packedShortestPath.size() - 1;
// std::cout << "length of packed vt-path: " << packed_v_t_path.size() << ", length of packed shortest path: " << packedShortestPath.size() << std::endl;
for (; viaPathIndex > 0 && shortestPathIndex > 0;) {
// std::cout << " checking indices [" << shortestPathIndex << "] and [" << (shortestPathIndex-1) << "] (shortest) as well as [" << shortestPathIndex << "] and [" << (shortestPathIndex-1) << "]" << std::endl;
if (packed_v_t_path[viaPathIndex - 1] == packedShortestPath[shortestPathIndex - 1] && packed_v_t_path[viaPathIndex] == packedShortestPath[shortestPathIndex]) {
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection( packed_v_t_path[viaPathIndex - 1], packed_v_t_path[viaPathIndex]);
// std::cout << "Id of edge (" << packed_v_t_path[viaPathIndex-1] << "," << packed_v_t_path[viaPathIndex] << ") : " << edgeID << std::endl;
*sharingOfViaPath += super::_queryData.graph->GetEdgeData( edgeID).distance;
} else {
if(packed_v_t_path[viaPathIndex] == packedShortestPath[shortestPathIndex]) {
unpackStack.push(std::make_pair(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex]));
unpackStack.push(std::make_pair(packedShortestPath[shortestPathIndex-1], packedShortestPath[shortestPathIndex]));
if (packed_v_t_path[viaPathIndex] == packedShortestPath[shortestPathIndex]) {
unpackStack.push( std::make_pair( packed_v_t_path[viaPathIndex - 1] , packed_v_t_path[viaPathIndex] ));
unpackStack.push( std::make_pair( packedShortestPath[shortestPathIndex - 1] , packedShortestPath[shortestPathIndex] ));
}
}
--viaPathIndex; --shortestPathIndex;
--viaPathIndex;
--shortestPathIndex;
}
while(!unpackStack.empty()) {
UnpackEdge shortestPathEdge = unpackStack.top(); unpackStack.pop();
UnpackEdge viaPathEdge = unpackStack.top(); unpackStack.pop();
std::cout << " unpacking edges (" << shortestPathEdge.first << "," << shortestPathEdge.second << ") and (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInShortestPath = super::_queryData.graph->FindEdgeInEitherDirection(shortestPathEdge.first, shortestPathEdge.second);
// std::cout << "!" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
std::cout << " ids are " << edgeIDInShortestPath << " (shortest) and " << edgeIDInViaPath << " (via)" << std::endl;
while (!unpackStack.empty()) {
const UnpackEdge shortestPathEdge = unpackStack.top();
unpackStack.pop();
const UnpackEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
// std::cout << " unpacking edges (" << shortestPathEdge.first << "," << shortestPathEdge.second << ") and (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInShortestPath = super::_queryData.graph->FindEdgeInEitherDirection(shortestPathEdge.first, shortestPathEdge.second);
// std::cout << "!" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection( viaPathEdge.first, viaPathEdge.second);
// std::cout << " ids are " << edgeIDInShortestPath << " (shortest) and " << edgeIDInViaPath << " (via)" << std::endl;
bool IsShortestPathEdgeShortCut = super::_queryData.graph->GetEdgeData(edgeIDInShortestPath).shortcut;
bool IsViaEdgeShortCut = super::_queryData.graph->GetEdgeData(edgeIDInViaPath).shortcut;
bool IsViaEdgeShortCut = super::_queryData.graph->GetEdgeData( edgeIDInViaPath).shortcut;
const NodeID middleOfShortestPath = !IsShortestPathEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInShortestPath).id;
const NodeID middleOfViaPath = !IsViaEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInViaPath).id;
const NodeID middleOfShortestPath = !IsShortestPathEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInShortestPath).id;
const NodeID middleOfViaPath = !IsViaEdgeShortCut ? UINT_MAX : super::_queryData.graph->GetEdgeData(edgeIDInViaPath ).id;
std::cout << " shortest shrtcut: " << (IsShortestPathEdgeShortCut ? "yes": "no") << "(" <<middleOfShortestPath << ") , via shrtcut: "
<< (IsViaEdgeShortCut ? "yes" : "no") << "(" << middleOfViaPath << ")" << std::endl;
// std::cout << " shortest shrtcut: " << (IsShortestPathEdgeShortCut ? "yes" : "no") << "(" << middleOfShortestPath << ") , via shrtcut: " << (IsViaEdgeShortCut ? "yes" : "no") << "(" << middleOfViaPath << ")" << std::endl;
if(IsShortestPathEdgeShortCut || IsViaEdgeShortCut) {
if(middleOfShortestPath == middleOfViaPath) { // unpack first segment
if (IsShortestPathEdgeShortCut || IsViaEdgeShortCut) {
if (middleOfShortestPath == middleOfViaPath) { // unpack first segment
//put first segment of via edge on stack, else take the segment already available
std::cout << " unpacking first segment" << std::endl;
if(IsViaEdgeShortCut)
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath));
else
unpackStack.push(viaPathEdge);
// std::cout << " unpacking first segment" << std::endl;
if (IsViaEdgeShortCut)
unpackStack.push( std::make_pair(viaPathEdge.first, middleOfViaPath));
else unpackStack.push(viaPathEdge);
//put first segment of shortest path edge on stack if not a shortcut, else take the segment already available
if(IsShortestPathEdgeShortCut)
unpackStack.push(std::make_pair(shortestPathEdge.first, middleOfShortestPath));
else
unpackStack.push(shortestPathEdge);
if (IsShortestPathEdgeShortCut)
unpackStack.push( std::make_pair(shortestPathEdge.first, middleOfShortestPath));
else unpackStack.push(shortestPathEdge);
//add length of first segment to amount of sharing
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
*sharingOfViaPath += super::_queryData.graph->GetEdgeData(edgeIDInViaPath).distance;
*sharingOfViaPath += super::_queryData.graph->GetEdgeData( edgeIDInViaPath).distance;
} else { // unpack second segment
std::cout << " unpacking second segment" << std::endl;
if(IsViaEdgeShortCut)
unpackStack.push(std::make_pair(middleOfViaPath, viaPathEdge.second));
else
unpackStack.push(viaPathEdge);
// std::cout << " unpacking second segment" << std::endl;
if (IsViaEdgeShortCut)
unpackStack.push( std::make_pair(middleOfViaPath, viaPathEdge.second));
else unpackStack.push(viaPathEdge);
//put first segment of shortest path edge on stack if not a shortcut, else take the segment already available
if(IsShortestPathEdgeShortCut)
unpackStack.push(std::make_pair(middleOfShortestPath, shortestPathEdge.second ));
else
unpackStack.push(shortestPathEdge);
//put first segment of shortest path edge on stack if not a shortcut, else take the segment already available
if (IsShortestPathEdgeShortCut)
unpackStack.push( std::make_pair(middleOfShortestPath, shortestPathEdge.second));
else unpackStack.push(shortestPathEdge);
}
}
}
std::cout << "sharing of SVT-Path: " << *sharingOfViaPath << std::endl;
// std::cout << "sharing of SVT-Path: " << *sharingOfViaPath << std::endl;
}
inline bool viaNodeCandidatePasses_T_Test(typename QueryDataT::HeapPtr & _forwardHeap1, typename QueryDataT::HeapPtr & _backwardHeap1, typename QueryDataT::HeapPtr & _forwardHeap2, typename QueryDataT::HeapPtr & _backwardHeap2, const RankedCandidateNode& candidate, const int offset, const NodeID middleOfShortestPath, const int lengthOfShortestPath) {
bool hasPassed_T_Test = true;
std::cout << "computing via path for T-Test " << candidate.node << std::endl;
int lengthOfViaPath = 0;
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
typename QueryDataT::HeapPtr & existingForwardHeap = super::_queryData.forwardHeap;
typename QueryDataT::HeapPtr & existingBackwardHeap = super::_queryData.backwardHeap;
typename QueryDataT::HeapPtr & newForwardHeap = super::_queryData.forwardHeap2;
typename QueryDataT::HeapPtr & newBackwardHeap = super::_queryData.backwardHeap2;
NodeID s_v_middle = UINT_MAX;
int upperBoundFor_s_v_Path = INT_MAX;//existingForwardHeap->GetKey(node.first);
//compute path <s,..,v> by reusing forward search from s
newBackwardHeap->Insert(candidate.node, 0, candidate.node);
while(newBackwardHeap->Size() > 0){
super::RoutingStep(newBackwardHeap, existingForwardHeap, &s_v_middle, &upperBoundFor_s_v_Path, 2*offset, false);
}
std::cout << " length of <s,..,v>: " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl;
//compute path <v,..,t> by reusing backward search from t
NodeID v_t_middle = UINT_MAX;
int upperBoundFor_v_t_Path = INT_MAX;//existingBackwardHeap->GetKey(node.first);
newForwardHeap->Insert(candidate.node, 0, candidate.node);
while(newForwardHeap->Size() > 0){
super::RoutingStep(newForwardHeap, existingBackwardHeap, &v_t_middle, &upperBoundFor_v_t_Path, 2*offset, true);
}
std::cout << " length of <v,..,t>: " << upperBoundFor_v_t_Path << " with middle node " << v_t_middle << std::endl;
lengthOfViaPath = upperBoundFor_s_v_Path+upperBoundFor_v_t_Path;
std::cout << " exact length of via path: " << lengthOfViaPath << std::endl;
std::cout << " T-Test shall pass with length 0.25*" << (lengthOfShortestPath) << "=" << 0.25*(lengthOfShortestPath) << std::endl;
// std::deque<NodeID> packedShortestPath;
std::deque<NodeID> packed_s_v_path;
std::deque<NodeID> packed_v_t_path;
//retrieve packed paths
std::cout << " retrieving packed path for middle nodes " << middleOfShortestPath << "," << s_v_middle << "," << v_t_middle << " (shorstest, sv, vt)" << std::endl;
// super::RetrievePackedPathFromHeap(existingForwardHeap, existingBackwardHeap, middleOfShortestPath, packedShortestPath);
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, s_v_middle, packed_s_v_path);
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, v_t_middle,packed_v_t_path);
std::cout << "packed sv: ";
for(unsigned i = 0; i < packed_s_v_path.size(); ++i) {
std::cout << packed_s_v_path[i] << " ";
}
std::cout << std::endl;
std::cout << "packed vt: ";
for(unsigned i = 0; i < packed_v_t_path.size(); ++i) {
std::cout << packed_v_t_path[i] << " ";
}
std::cout << std::endl;
// std::cout << "packed shortest: ";
// for(unsigned i = 0; i < packedShortestPath.size(); ++i) {
// std::cout << packedShortestPath[i] << " ";
// }
// std::cout << std::endl;
NodeID s_P = s_v_middle, t_P = v_t_middle;
const int T_threshold = VIAPATH_EPSILON * lengthOfShortestPath;
int unpackedUntilDistance = 0;
typedef std::pair<NodeID, NodeID> UnpackEdge;
std::stack<UnpackEdge > unpackStack;
//partial unpacking until target of edge is the first endpoint of a non-shortcut edge farther away than threshold
//First partially unpack s-->v until paths deviate, note length of common path.
std::cout << "unpacking sv-path until a node of non-shortcut edge is farther away than " << T_threshold << std::endl;
for(unsigned i = packed_s_v_path.size()-1; (i > 0) && unpackStack.empty(); --i ) {
std::cout << " checking indices [" << i << "] and [" << (i+1) << "]" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection(packed_s_v_path[i-1], packed_s_v_path[i]);
int lengthOfCurrentEdge = super::_queryData.graph->GetEdgeData(edgeID).distance;
if(lengthOfCurrentEdge + unpackedUntilDistance > T_threshold) {
unpackStack.push(std::make_pair(packed_s_v_path[i-1], packed_s_v_path[i]));
} else {
unpackedUntilDistance += lengthOfCurrentEdge;
s_P = packed_s_v_path[i-1];
}
}
while(!unpackStack.empty()) {
UnpackEdge viaPathEdge = unpackStack.top(); unpackStack.pop();
std::cout << " unpacking edge (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
std::cout << " id is " << edgeIDInViaPath << " (via)" << std::endl;
typename QueryDataT::Graph::EdgeData currentEdgeData = super::_queryData.graph->GetEdgeData(edgeIDInViaPath);
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if( IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
typename QueryDataT::Graph::EdgeIterator edgeIDOfFirstSegment = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
typename QueryDataT::Graph::EdgeIterator edgeIDOfSecondSegment = super::_queryData.graph->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfFirstSegment = super::_queryData.graph->GetEdgeData(edgeIDOfFirstSegment).distance;
int lengthOfSecondSegment = super::_queryData.graph->GetEdgeData(edgeIDOfSecondSegment).distance;
//attention: !unpacking in reverse!
//Check if second segment is the one to go over treshold? if yes add second segment to stack, else push first segment to stack and add distance of second one.
if(unpackedUntilDistance+lengthOfSecondSegment > T_threshold ) {
unpackStack.push(std::make_pair(middleOfViaPath, viaPathEdge.second));
} else {
unpackedUntilDistance+=lengthOfSecondSegment;
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath));
}
} else { // edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance;
s_P = viaPathEdge.second;
}
}
std::cout << "threshold: " << T_threshold << ", unpackedDistance: " << unpackedUntilDistance << ", s_P: " << s_P << std::endl;
int lengthOfPathT_Test_Path = unpackedUntilDistance;
unpackedUntilDistance = 0;
//partial unpacking until target of edge is the first endpoint of a non-shortcut edge farther away than threshold
//First partially unpack s-->v until paths deviate, note length of common path.
std::cout << "unpacking vt-path until a node of non-shortcut edge is farther away than " << T_threshold << std::endl;
for(unsigned i = 0, lengthOfPackedPath = packed_v_t_path.size()-1; (i < lengthOfPackedPath) && unpackStack.empty(); ++i ) {
std::cout << " checking indices [" << i << "] and [" << (i+1) << "]" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i+1]);
int lengthOfCurrentEdge = super::_queryData.graph->GetEdgeData(edgeID).distance;
if(lengthOfCurrentEdge + unpackedUntilDistance > T_threshold) {
unpackStack.push(std::make_pair(packed_v_t_path[i], packed_v_t_path[i+1]));
} else {
unpackedUntilDistance += lengthOfCurrentEdge;
t_P = packed_v_t_path[i+1];
}
}
while(!unpackStack.empty()) {
UnpackEdge viaPathEdge = unpackStack.top(); unpackStack.pop();
std::cout << " unpacking edge (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
std::cout << " id is " << edgeIDInViaPath << " (via)" << std::endl;
typename QueryDataT::Graph::EdgeData currentEdgeData = super::_queryData.graph->GetEdgeData(edgeIDInViaPath);
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if( IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
typename QueryDataT::Graph::EdgeIterator edgeIDOfFirstSegment = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
typename QueryDataT::Graph::EdgeIterator edgeIDOfSecondSegment = super::_queryData.graph->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfFirstSegment = super::_queryData.graph->GetEdgeData(edgeIDOfFirstSegment).distance;
int lengthOfSecondSegment = super::_queryData.graph->GetEdgeData(edgeIDOfSecondSegment).distance;
//Check if first segment is the one to go over treshold? if yes first segment to stack, else push second segment to stack and add distance of first one.
if(unpackedUntilDistance+lengthOfFirstSegment > T_threshold ) {
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath));
} else {
unpackedUntilDistance+=lengthOfFirstSegment;
unpackStack.push(std::make_pair(middleOfViaPath, viaPathEdge.second));
}
} else { // edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance;
t_P = viaPathEdge.second;
}
}
lengthOfPathT_Test_Path += unpackedUntilDistance;
std::cout << "check if path (" << s_P << "," << t_P << ") is not less than " << lengthOfPathT_Test_Path << ", while shortest path has length: " << lengthOfShortestPath << std::endl;
//TODO: Run query and compare distances.
std::cout << "passed T-Test: " << (hasPassed_T_Test ? "yes" : "no") << std::endl;
return hasPassed_T_Test;
}
inline int approximateAmountOfSharing(const NodeID middleNodeIDOfShortestPath, const NodeID middleNodeIDOfAlternativePath, typename QueryDataT::HeapPtr & _forwardHeap, typename QueryDataT::HeapPtr & _backwardHeap) {
std::deque<NodeID> packedShortestPath;
inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const std::deque<NodeID> & packedShortestPath) {
std::deque<NodeID> packedAlternativePath;
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfShortestPath, packedShortestPath);
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath);
int sharing = 0;
int aindex = 0;
//compute forward sharing
while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) {
@ -568,11 +380,10 @@ private:
sharing += super::_queryData.graph->GetEdgeData(edgeID).distance;
--aindex; --bindex;
}
return sharing;
}
inline void AlternativeRoutingStep(typename QueryDataT::HeapPtr & _forwardHeap, typename QueryDataT::HeapPtr & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection, std::vector<NodeID>& searchSpaceIntersection) const {
inline void AlternativeRoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection, std::vector<NodeID>& searchSpaceIntersection) const {
const NodeID node = _forwardHeap->DeleteMin();
const int distance = _forwardHeap->GetKey(node);
@ -582,7 +393,7 @@ private:
const int newDistance = _backwardHeap->GetKey(node) + distance;
if(newDistance < *_upperbound ){
if(newDistance>=0 ) {
INFO("upper bound decrease to: " << newDistance);
// INFO("upper bound decrease to: " << newDistance);
*middle = node;
*_upperbound = newDistance;
}
@ -590,7 +401,7 @@ private:
}
//0.8 implies an epsilon of 25%
if((distance-edgeBasedOffset)*0.8 > *_upperbound){
if((distance-edgeBasedOffset)*VIAPATH_GAMMA > *_upperbound){
_forwardHeap->DeleteAll();
return;
}
@ -625,7 +436,170 @@ private:
return 0;
}
//conduct T-Test
inline bool viaNodeCandidatePasses_T_Test( HeapPtr& existingForwardHeap, HeapPtr& existingBackwardHeap, HeapPtr& newForwardHeap, HeapPtr& newBackwardHeap, const RankedCandidateNode& candidate, const int offset, const NodeID middleOfShortestPath, const int lengthOfShortestPath, int * lengthOfViaPath) {
// std::cout << "computing via path for T-Test " << candidate.node << std::endl;
// int lengthOfViaPath = 0;
super::_queryData.InitializeOrClearSecondThreadLocalStorage();
NodeID s_v_middle = UINT_MAX;
int upperBoundFor_s_v_Path = INT_MAX;
//compute path <s,..,v> by reusing forward search from s
newBackwardHeap->Insert(candidate.node, 0, candidate.node);
while (newBackwardHeap->Size() > 0) {
super::RoutingStep(newBackwardHeap, existingForwardHeap, &s_v_middle, &upperBoundFor_s_v_Path, 0, false);
}
// std::cout << " length of <s,..,v>: " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl;
//compute path <v,..,t> by reusing backward search from t
NodeID v_t_middle = UINT_MAX;
int upperBoundFor_v_t_Path = INT_MAX;
newForwardHeap->Insert(candidate.node, 0, candidate.node);
while (newForwardHeap->Size() > 0) {
super::RoutingStep(newForwardHeap, existingBackwardHeap, &v_t_middle, &upperBoundFor_v_t_Path, 0, true);
}
// std::cout << " length of <v,..,t>: " << upperBoundFor_v_t_Path << " with middle node " << v_t_middle << std::endl;
*lengthOfViaPath = upperBoundFor_s_v_Path + upperBoundFor_v_t_Path;
// std::cout << " exact length of via path: " << lengthOfViaPath << std::endl;
// std::cout << " T-Test shall pass with length 0.25*" << (lengthOfShortestPath) << "=" << 0.25 * (lengthOfShortestPath) << std::endl;
std::deque < NodeID > packed_s_v_path;
std::deque < NodeID > packed_v_t_path;
//retrieve packed paths
// std::cout << " retrieving packed path for middle nodes " << middleOfShortestPath << "," << s_v_middle << "," << v_t_middle << " (shorstest, sv, vt)" << std::endl;
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, s_v_middle, packed_s_v_path);
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, v_t_middle, packed_v_t_path);
// std::cout << "packed sv: ";
// for (unsigned i = 0; i < packed_s_v_path.size(); ++i) {
// std::cout << packed_s_v_path[i] << " ";
// }
// std::cout << std::endl;
// std::cout << "packed vt: ";
// for (unsigned i = 0; i < packed_v_t_path.size(); ++i) {
// std::cout << packed_v_t_path[i] << " ";
// }
// std::cout << std::endl;
// std::cout << "packed shortest: ";
// for(unsigned i = 0; i < packedShortestPath.size(); ++i) {
// std::cout << packedShortestPath[i] << " ";
// }
// std::cout << std::endl;
NodeID s_P = s_v_middle, t_P = v_t_middle;
const int T_threshold = VIAPATH_EPSILON * lengthOfShortestPath;
int unpackedUntilDistance = 0;
typedef std::pair<NodeID, NodeID> UnpackEdge;
std::stack<UnpackEdge> unpackStack;
//partial unpacking until target of edge is the first endpoint of a non-shortcut edge farther away than threshold
//First partially unpack s-->v until paths deviate, note length of common path.
// std::cout << "unpacking sv-path until a node of non-shortcut edge is farther away than " << T_threshold << std::endl;
for (unsigned i = packed_s_v_path.size() - 1; (i > 0) && unpackStack.empty(); --i) {
// std::cout << " checking indices [" << i << "] and [" << (i + 1) << "]" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection( packed_s_v_path[i - 1], packed_s_v_path[i]);
int lengthOfCurrentEdge = super::_queryData.graph->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) {
unpackStack.push(std::make_pair(packed_s_v_path[i - 1], packed_s_v_path[i]));
} else {
unpackedUntilDistance += lengthOfCurrentEdge;
s_P = packed_s_v_path[i - 1];
}
}
while (!unpackStack.empty()) {
const UnpackEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
// std::cout << " unpacking edge (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
// std::cout << " id is " << edgeIDInViaPath << " (via)" << std::endl;
typename QueryDataT::Graph::EdgeData currentEdgeData = super::_queryData.graph->GetEdgeData(edgeIDInViaPath);
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if (IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
typename QueryDataT::Graph::EdgeIterator edgeIDOfFirstSegment = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
typename QueryDataT::Graph::EdgeIterator edgeIDOfSecondSegment = super::_queryData.graph->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfFirstSegment = super::_queryData.graph->GetEdgeData(edgeIDOfFirstSegment).distance;
int lengthOfSecondSegment = super::_queryData.graph->GetEdgeData(edgeIDOfSecondSegment).distance;
//attention: !unpacking in reverse!
//Check if second segment is the one to go over treshold? if yes add second segment to stack, else push first segment to stack and add distance of second one.
if (unpackedUntilDistance + lengthOfSecondSegment >= T_threshold) {
unpackStack.push(std::make_pair(middleOfViaPath, viaPathEdge.second));
} else {
unpackedUntilDistance += lengthOfSecondSegment;
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath));
}
} else {
// edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance;
s_P = viaPathEdge.first;
}
}
// std::cout << "threshold: " << T_threshold << ", unpackedDistance: " << unpackedUntilDistance << ", s_P: " << s_P << std::endl;
int lengthOfPathT_Test_Path = unpackedUntilDistance;
unpackedUntilDistance = 0;
//partial unpacking until target of edge is the first endpoint of a non-shortcut edge farther away than threshold
//First partially unpack s-->v until paths deviate, note length of common path.
// std::cout << "unpacking vt-path until a node of non-shortcut edge is farther away than " << T_threshold << std::endl;
for (unsigned i = 0, lengthOfPackedPath = packed_v_t_path.size() - 1; (i < lengthOfPackedPath) && unpackStack.empty(); ++i) {
// std::cout << " checking indices [" << i << "] and [" << (i + 1) << "]" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeID = super::_queryData.graph->FindEdgeInEitherDirection( packed_v_t_path[i], packed_v_t_path[i + 1]);
int lengthOfCurrentEdge = super::_queryData.graph->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) {
unpackStack.push( std::make_pair(packed_v_t_path[i], packed_v_t_path[i + 1]));
} else {
unpackedUntilDistance += lengthOfCurrentEdge;
t_P = packed_v_t_path[i + 1];
}
}
while (!unpackStack.empty()) {
const UnpackEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
// std::cout << " unpacking edge (" << viaPathEdge.first << "," << viaPathEdge.second << ")" << std::endl;
typename QueryDataT::Graph::EdgeIterator edgeIDInViaPath = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
// std::cout << " id is " << edgeIDInViaPath << " (via)" << std::endl;
typename QueryDataT::Graph::EdgeData currentEdgeData = super::_queryData.graph->GetEdgeData(edgeIDInViaPath);
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if (IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
typename QueryDataT::Graph::EdgeIterator edgeIDOfFirstSegment = super::_queryData.graph->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
typename QueryDataT::Graph::EdgeIterator edgeIDOfSecondSegment = super::_queryData.graph->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfFirstSegment = super::_queryData.graph->GetEdgeData( edgeIDOfFirstSegment).distance;
int lengthOfSecondSegment = super::_queryData.graph->GetEdgeData( edgeIDOfSecondSegment).distance;
//Check if first segment is the one to go over treshold? if yes first segment to stack, else push second segment to stack and add distance of first one.
if (unpackedUntilDistance + lengthOfFirstSegment >= T_threshold) {
unpackStack.push( std::make_pair(viaPathEdge.first, middleOfViaPath));
} else {
unpackedUntilDistance += lengthOfFirstSegment;
unpackStack.push( std::make_pair(middleOfViaPath, viaPathEdge.second));
}
} else {
// edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance;
t_P = viaPathEdge.second;
}
}
lengthOfPathT_Test_Path += unpackedUntilDistance;
// std::cout << "check if path (" << s_P << "," << t_P << ") is not less than " << lengthOfPathT_Test_Path << ", while shortest path has length: " << lengthOfShortestPath << std::endl;
//Run query and compare distances.
HeapPtr& forwardHeap = super::_queryData.forwardHeap3;
HeapPtr& backwardHeap = super::_queryData.backwardHeap3;
super::_queryData.InitializeOrClearThirdThreadLocalStorage();
int _upperBound = INT_MAX;
NodeID middle = UINT_MAX;
forwardHeap->Insert(s_P, 0, s_P);
backwardHeap->Insert(t_P, 0, t_P);
//exploration from s and t until deletemin/(1+epsilon) > _lengthOfShortestPath
while (forwardHeap->Size() + backwardHeap->Size() > 0) {
if (forwardHeap->Size() > 0) {
super::RoutingStep(forwardHeap, backwardHeap, &middle, &_upperBound, offset, true);
}
if (backwardHeap->Size() > 0) {
super::RoutingStep(backwardHeap, forwardHeap, &middle, &_upperBound, offset, false);
}
}
// std::cout << "lengthOfPathT_Test_Path: " << lengthOfPathT_Test_Path << ", _upperBound: " << _upperBound << std::endl;
bool hasPassed_T_Test = (_upperBound == lengthOfPathT_Test_Path);
// std::cout << "passed T-Test: " << (hasPassed_T_Test ? "yes" : "no") << std::endl;
return hasPassed_T_Test;
}
};
#endif /* ALTERNATIVEROUTES_H_ */

View File

@ -26,6 +26,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cassert>
#include <climits>
#include "../Plugins/RawRouteData.h"
template<class QueryDataT>
class BasicRoutingInterface {
protected:

View File

@ -33,10 +33,12 @@ public:
~ShortestPathRouting() {}
int operator()(std::vector<PhantomNodes> & phantomNodesVector, std::vector<_PathData> & unpackedPath) {
void operator()(std::vector<PhantomNodes> & phantomNodesVector, RawRouteData & rawRouteData) {
BOOST_FOREACH(PhantomNodes & phantomNodePair, phantomNodesVector) {
if(!phantomNodePair.AtLeastOnePhantomNodeIsUINTMAX())
return INT_MAX;
if(!phantomNodePair.AtLeastOnePhantomNodeIsUINTMAX()) {
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX;
return;
}
}
int distance1 = 0;
int distance2 = 0;
@ -115,7 +117,8 @@ public:
//No path found for both target nodes?
if(INT_MAX == _localUpperbound1 && INT_MAX == _localUpperbound2) {
return INT_MAX;
rawRouteData.lengthOfShortestPath = rawRouteData.lengthOfAlternativePath = INT_MAX;
return;
}
if(UINT_MAX == middle1) {
searchFrom1stStartNode = false;
@ -215,30 +218,34 @@ public:
// INFO("length path2: " << distance2);
if(distance1 <= distance2){
//remove consecutive duplicates
std::cout << "unclean 1: ";
for(unsigned i = 0; i < packedPath1.size(); ++i)
std::cout << packedPath1[i] << " ";
std::cout << std::endl;
_RemoveConsecutiveDuplicatesFromContainer(packedPath1);
// std::cout << "unclean 1: ";
// for(unsigned i = 0; i < packedPath1.size(); ++i)
// std::cout << packedPath1[i] << " ";
// std::cout << std::endl;
// std::cout << "cleaned 1: ";
// for(unsigned i = 0; i < packedPath1.size(); ++i)
// std::cout << packedPath1[i] << " ";
// std::cout << std::endl;
super::UnpackPath(packedPath1, unpackedPath);
// super::UnpackPath(packedPath1, rawRouteData.computedShortestPath);
} else {
std::cout << "unclean 2: ";
for(unsigned i = 0; i < packedPath2.size(); ++i)
std::cout << packedPath2[i] << " ";
std::cout << std::endl;
_RemoveConsecutiveDuplicatesFromContainer(packedPath2);
std::swap(packedPath1, packedPath2);
// std::cout << "unclean 2: ";
// for(unsigned i = 0; i < packedPath2.size(); ++i)
// std::cout << packedPath2[i] << " ";
// std::cout << std::endl;
// _RemoveConsecutiveDuplicatesFromContainer(packedPath2);
// std::cout << "cleaned 2: ";
// for(unsigned i = 0; i < packedPath2.size(); ++i)
// std::cout << packedPath2[i] << " ";
// std::cout << std::endl;
super::UnpackPath(packedPath2, unpackedPath);
// super::UnpackPath(packedPath2, unpackedPath);
}
_RemoveConsecutiveDuplicatesFromContainer(packedPath1);
super::UnpackPath(packedPath1, rawRouteData.computedShortestPath);
rawRouteData.lengthOfShortestPath = std::min(distance1, distance2);
// INFO("Found via route with distance " << std::min(distance1, distance2));
return std::min(distance1, distance2);
return;
}
private:
template<class ContainerT>