diff --git a/Contractor/EdgeBasedGraphFactory.cpp b/Contractor/EdgeBasedGraphFactory.cpp index bf8c16b7d..6c2f0939a 100644 --- a/Contractor/EdgeBasedGraphFactory.cpp +++ b/Contractor/EdgeBasedGraphFactory.cpp @@ -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; } diff --git a/DataStructures/SearchEngine.h b/DataStructures/SearchEngine.h index a02fc7e7e..6269d6e35 100644 --- a/DataStructures/SearchEngine.h +++ b/DataStructures/SearchEngine.h @@ -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 >(nodeHelpDesk->getNumberOfNodes())); + } + else + forwardHeap3->Clear(); + + if(!backwardHeap3.get()) { + backwardHeap3.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData, UnorderedMapStorage >(nodeHelpDesk->getNumberOfNodes())); + } + else + backwardHeap3->Clear(); + } }; template @@ -149,4 +165,7 @@ template SearchEngineHeapPtr SearchEngineData SearchEngineHeapPtr SearchEngineData::forwardHeap2; template SearchEngineHeapPtr SearchEngineData::backwardHeap2; +template SearchEngineHeapPtr SearchEngineData::forwardHeap3; +template SearchEngineHeapPtr SearchEngineData::backwardHeap3; + #endif /* SEARCHENGINE_H_ */ diff --git a/DataStructures/TurnInstructions.h b/DataStructures/TurnInstructions.h index b805a0317..624a8db4c 100644 --- a/DataStructures/TurnInstructions.h +++ b/DataStructures/TurnInstructions.h @@ -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]; diff --git a/Descriptors/BaseDescriptor.h b/Descriptors/BaseDescriptor.h index 2510ee39b..c0eefab7a 100644 --- a/Descriptors/BaseDescriptor.h +++ b/Descriptors/BaseDescriptor.h @@ -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; }; diff --git a/Descriptors/GPXDescriptor.h b/Descriptors/GPXDescriptor.h index b0387daea..3f28a9c15 100644 --- a/Descriptors/GPXDescriptor.h +++ b/Descriptors/GPXDescriptor.h @@ -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 += (""); reply.content += ""; reply.content += ""; - if(distance != UINT_MAX && rawRoute.computedRouted.size()) { + if(rawRoute.lengthOfShortestPath != UINT_MAX && rawRoute.computedShortestPath.size()) { convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp); reply.content += ""; - BOOST_FOREACH(_PathData pathData, rawRoute.computedRouted) { + BOOST_FOREACH(_PathData pathData, rawRoute.computedShortestPath) { sEngine.GetCoordinatesForNodeID(pathData.node, current); convertInternalLatLonToString(current.lat, tmp); diff --git a/Descriptors/JSONDescriptor.h b/Descriptors/JSONDescriptor.h index 873c1facf..f8b441a2c 100644 --- a/Descriptors/JSONDescriptor.h +++ b/Descriptors/JSONDescriptor.h @@ -36,6 +36,7 @@ class JSONDescriptor : public BaseDescriptor{ 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_ */ diff --git a/Plugins/RawRouteData.h b/Plugins/RawRouteData.h index 4a6f53a43..25c280efd 100644 --- a/Plugins/RawRouteData.h +++ b/Plugins/RawRouteData.h @@ -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_ */ diff --git a/Plugins/ViaRoutePlugin.h b/Plugins/ViaRoutePlugin.h index efec305aa..5e60334d4 100644 --- a/Plugins/ViaRoutePlugin.h +++ b/Plugins/ViaRoutePlugin.h @@ -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 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"; } diff --git a/RoutingAlgorithms/AlternativePathRouting.h b/RoutingAlgorithms/AlternativePathRouting.h index 423886108..e8712525e 100644 --- a/RoutingAlgorithms/AlternativePathRouting.h +++ b/RoutingAlgorithms/AlternativePathRouting.h @@ -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 AlternativeRouting : private BasicRoutingInterface{ typedef BasicRoutingInterface super; typedef std::pair 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 alternativePath; std::vector 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 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 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 and 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 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 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 & packedShortestPath) { //compute and unpack and 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 by reusing forward search from s + int upperBoundFor_s_v_Path = INT_MAX;//compute path 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 : " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl; - + // std::cout << " length of : " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl; //compute path 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 : " << upperBoundFor_v_t_Path << " with middle node " << v_t_middle << std::endl; + // std::cout << " length of : " << 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 packedShortestPath; - std::deque packed_s_v_path; - std::deque 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 UnpackEdge; - std::stack unpackStack; - - //TODO: partial unpacking, compute sharing + std::stack 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") << "(" <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 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 : " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl; - - //compute path 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 : " << 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 packedShortestPath; - std::deque packed_s_v_path; - std::deque 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 UnpackEdge; - std::stack 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 packedShortestPath; + inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const std::deque & packedShortestPath) { std::deque 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& searchSpaceIntersection) const { + inline void AlternativeRoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection, std::vector& 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 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 : " << upperBoundFor_s_v_Path << " with middle node " << s_v_middle << std::endl; + //compute path 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 : " << 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 UnpackEdge; + std::stack 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_ */ diff --git a/RoutingAlgorithms/BasicRoutingInterface.h b/RoutingAlgorithms/BasicRoutingInterface.h index e1228256b..a55590a84 100644 --- a/RoutingAlgorithms/BasicRoutingInterface.h +++ b/RoutingAlgorithms/BasicRoutingInterface.h @@ -26,6 +26,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include +#include "../Plugins/RawRouteData.h" + template class BasicRoutingInterface { protected: diff --git a/RoutingAlgorithms/ShortestPathRouting.h b/RoutingAlgorithms/ShortestPathRouting.h index 1ab90cab7..da553f616 100644 --- a/RoutingAlgorithms/ShortestPathRouting.h +++ b/RoutingAlgorithms/ShortestPathRouting.h @@ -33,10 +33,12 @@ public: ~ShortestPathRouting() {} - int operator()(std::vector & phantomNodesVector, std::vector<_PathData> & unpackedPath) { + void operator()(std::vector & 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