half-implemented local optimality test for single via node alternative
routes. Partial unpacking working, but actual test not yet conducted.
This commit is contained in:
parent
7f0d40f459
commit
5ebc4b392f
@ -25,6 +25,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include "BasicRoutingInterface.h"
|
||||
|
||||
const double VIAPATH_EPSILON = 0.25;
|
||||
|
||||
template<class QueryDataT>
|
||||
class AlternativeRouting : private BasicRoutingInterface<QueryDataT>{
|
||||
typedef BasicRoutingInterface<QueryDataT> super;
|
||||
@ -56,7 +58,7 @@ public:
|
||||
typename QueryDataT::HeapPtr & forwardHeap = super::_queryData.forwardHeap;
|
||||
typename QueryDataT::HeapPtr & backwardHeap = super::_queryData.backwardHeap;
|
||||
typename QueryDataT::HeapPtr & forwardHeap2 = super::_queryData.forwardHeap2;
|
||||
typename QueryDataT::HeapPtr & backwardHea2 = super::_queryData.backwardHeap2;
|
||||
typename QueryDataT::HeapPtr & backwardHeap2 = super::_queryData.backwardHeap2;
|
||||
|
||||
//Initialize Queues
|
||||
super::_queryData.InitializeOrClearFirstThreadLocalStorage();
|
||||
@ -94,6 +96,9 @@ public:
|
||||
INFO("found " << viaNodeCandidates.size() << " nodes in search space intersection");
|
||||
|
||||
INFO("upper bound: " << _upperBound);
|
||||
//TODO: 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
|
||||
|
||||
//ch-pruning of via nodes in both search spaces
|
||||
|
||||
std::vector< PreselectedNode> nodesThatPassPreselection;
|
||||
@ -137,18 +142,20 @@ public:
|
||||
NodeID selectedViaNode = UINT_MAX;
|
||||
|
||||
BOOST_FOREACH(const RankedCandidateNode candidate, rankedCandidates){
|
||||
//TODO: select first admissable
|
||||
//TODO: conduct T-Test
|
||||
// selectedViaNode = candidate.node;
|
||||
//conduct T-Test
|
||||
if(viaNodeCandidatePasses_T_Test(forwardHeap, backwardHeap, forwardHeap2, backwardHeap2, candidate, offset, middle, _upperBound)) {
|
||||
// select first admissable
|
||||
selectedViaNode = candidate.node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
selectedViaNode = rankedCandidates[0].node;
|
||||
|
||||
//TODO: compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues
|
||||
//TODO: Same (co-)routines necessary as for computing length and sharing
|
||||
|
||||
retrievePackedViaPath(forwardHeap, backwardHeap, forwardHeap, backwardHea2, selectedViaNode, unpackedPath);
|
||||
//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) {
|
||||
|
||||
retrievePackedViaPath(forwardHeap, backwardHeap, forwardHeap2, backwardHeap2, selectedViaNode, unpackedPath);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -157,8 +164,9 @@ private:
|
||||
//unpack s,v
|
||||
std::deque<NodeID> packed_s_v_path, packed_v_t_path;
|
||||
std::cout << "1" << std::endl;
|
||||
//super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, viaNode, packed_s_v_path);
|
||||
super::RetrievePackedPathFromHeap(_forwardHeap1, _backwardHeap2, viaNode, packed_s_v_path);
|
||||
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;
|
||||
packed_s_v_path.insert(packed_s_v_path.end(),packed_v_t_path.begin(), packed_v_t_path.end() );
|
||||
@ -373,6 +381,167 @@ private:
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
std::deque<NodeID> packedAlternativePath;
|
||||
@ -452,14 +621,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void pruneViaNodeCandidates() {
|
||||
|
||||
}
|
||||
|
||||
unsigned computeApproximatedOverlap(const NodeID s, const NodeID t, const NodeID v) {
|
||||
|
||||
}
|
||||
|
||||
unsigned computeOverlap(const NodeID s, const NodeID t, const NodeID v) {
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user