unpacking start and target edge fixes plus some refactoring

This commit is contained in:
Dennis Luxen 2014-03-05 19:17:19 +01:00
parent 985270bb02
commit 3b29eeb6b6
3 changed files with 441 additions and 274 deletions

View File

@ -25,15 +25,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef ALTERNATIVEROUTES_H_ #ifndef ALTERNATIVE_PATH_ROUTING_H
#define ALTERNATIVEROUTES_H_ #define ALTERNATIVE_PATH_ROUTING_H
#include "BasicRoutingInterface.h" #include "BasicRoutingInterface.h"
#include "../DataStructures/SearchEngineData.h" #include "../DataStructures/SearchEngineData.h"
#include "../Util/TimingUtil.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cmath>
#include <vector> #include <vector>
const double VIAPATH_ALPHA = 0.15; const double VIAPATH_ALPHA = 0.15;
@ -74,7 +76,7 @@ public:
engine_working_data(engine_working_data) engine_working_data(engine_working_data)
{ } { }
~AlternativeRouting() {} virtual ~AlternativeRouting() {}
void operator() ( void operator() (
const PhantomNodes & phantom_node_pair, const PhantomNodes & phantom_node_pair,
@ -83,8 +85,8 @@ public:
if( //phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX() || if( //phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX() ||
phantom_node_pair.PhantomNodesHaveEqualLocation() phantom_node_pair.PhantomNodesHaveEqualLocation()
) { ) {
raw_route_data.lengthOfShortestPath = INT_MAX; // raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
raw_route_data.lengthOfAlternativePath = INT_MAX; // raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
SimpleLogger().Write(logDEBUG) << "not executing path search"; SimpleLogger().Write(logDEBUG) << "not executing path search";
return; return;
} }
@ -94,6 +96,7 @@ public:
std::vector<SearchSpaceEdge> forward_search_space; std::vector<SearchSpaceEdge> forward_search_space;
std::vector<SearchSpaceEdge> reverse_search_space; std::vector<SearchSpaceEdge> reverse_search_space;
//Init queues, semi-expensive because access to TSS invokes a sys-call //Init queues, semi-expensive because access to TSS invokes a sys-call
engine_working_data.InitializeOrClearFirstThreadLocalStorage( engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes() super::facade->GetNumberOfNodes()
@ -153,6 +156,8 @@ public:
phantom_node_pair.targetPhantom phantom_node_pair.targetPhantom
); );
SimpleLogger().Write(logDEBUG) << "fwd_offset: " << forward_offset << ", reverse_offset: " << reverse_offset;
//search from s and t till new_min/(1+epsilon) > length_of_shortest_path //search from s and t till new_min/(1+epsilon) > length_of_shortest_path
while(0 < (forward_heap1.Size() + reverse_heap1.Size())){ while(0 < (forward_heap1.Size() + reverse_heap1.Size())){
if(0 < forward_heap1.Size()){ if(0 < forward_heap1.Size()){
@ -179,6 +184,7 @@ public:
} }
} }
sort_unique_resize(via_node_candidate_list); sort_unique_resize(via_node_candidate_list);
SimpleLogger().Write(logDEBUG) << "found " << via_node_candidate_list.size() << " unique via node candidates";
std::vector<NodeID> packed_forward_path; std::vector<NodeID> packed_forward_path;
std::vector<NodeID> packed_reverse_path; std::vector<NodeID> packed_reverse_path;
@ -202,7 +208,10 @@ public:
BOOST_FOREACH(const SearchSpaceEdge & current_edge, forward_search_space) { BOOST_FOREACH(const SearchSpaceEdge & current_edge, forward_search_space) {
const NodeID u = current_edge.first; const NodeID u = current_edge.first;
const NodeID v = current_edge.second; const NodeID v = current_edge.second;
if(packed_forward_path.size() < index_into_forward_path && current_edge == forward_search_space[index_into_forward_path]) { if(
( packed_forward_path.size() < index_into_forward_path ) &&
( current_edge == forward_search_space[index_into_forward_path] )
) {
//current_edge is on shortest path => sharing(u):=queue.GetKey(u); //current_edge is on shortest path => sharing(u):=queue.GetKey(u);
++index_into_forward_path; ++index_into_forward_path;
approximated_forward_sharing[v] = forward_heap1.GetKey(u); approximated_forward_sharing[v] = forward_heap1.GetKey(u);
@ -217,65 +226,87 @@ public:
BOOST_FOREACH(const SearchSpaceEdge & current_edge, reverse_search_space) { BOOST_FOREACH(const SearchSpaceEdge & current_edge, reverse_search_space) {
const NodeID u = current_edge.first; const NodeID u = current_edge.first;
const NodeID v = current_edge.second; const NodeID v = current_edge.second;
if(packed_reverse_path.size() < index_into_reverse_path && current_edge == reverse_search_space[index_into_reverse_path]) { if(
( packed_reverse_path.size() < index_into_reverse_path ) &&
( current_edge == reverse_search_space[index_into_reverse_path] )
) {
//current_edge is on shortest path => sharing(u):=queue.GetKey(u); //current_edge is on shortest path => sharing(u):=queue.GetKey(u);
++index_into_reverse_path; ++index_into_reverse_path;
approximated_reverse_sharing[v] = reverse_heap1.GetKey(u); approximated_reverse_sharing[v] = reverse_heap1.GetKey(u);
} else { } else {
//sharing (s) = sharing (t) //sharing (s) = sharing (t)
boost::unordered_map<NodeID, int>::const_iterator rev_iterator = approximated_reverse_sharing.find(u); boost::unordered_map<NodeID,int>::const_iterator rev_iterator = approximated_reverse_sharing.find(u);
const int rev_sharing = (rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0; const int rev_sharing = (rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0;
approximated_reverse_sharing[v] = rev_sharing; approximated_reverse_sharing[v] = rev_sharing;
} }
} }
std::vector<NodeID> nodes_that_passed_preselection;
SimpleLogger().Write(logDEBUG) << "fwd_search_space size: " << forward_search_space.size() << ", marked " << approximated_forward_sharing.size() << " nodes";
SimpleLogger().Write(logDEBUG) << "rev_search_space size: " << reverse_search_space.size() << ", marked " << approximated_reverse_sharing.size() << " nodes";
std::vector<NodeID> preselected_node_list;
BOOST_FOREACH(const NodeID node, via_node_candidate_list) { BOOST_FOREACH(const NodeID node, via_node_candidate_list) {
boost::unordered_map<NodeID, int>::const_iterator fwd_iterator = approximated_forward_sharing.find(node); boost::unordered_map<NodeID, int>::const_iterator fwd_iterator = approximated_forward_sharing.find(node);
const int fwd_sharing = (fwd_iterator != approximated_forward_sharing.end()) ? fwd_iterator->second : 0; const int fwd_sharing = (fwd_iterator != approximated_forward_sharing.end()) ? fwd_iterator->second : 0;
boost::unordered_map<NodeID, int>::const_iterator rev_iterator = approximated_reverse_sharing.find(node); boost::unordered_map<NodeID, int>::const_iterator rev_iterator = approximated_reverse_sharing.find(node);
const int rev_sharing = (rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0; const int rev_sharing = (rev_iterator != approximated_reverse_sharing.end()) ? rev_iterator->second : 0;
int approximated_sharing = fwd_sharing + rev_sharing; const int approximated_sharing = fwd_sharing + rev_sharing;
int approximated_length = forward_heap1.GetKey(node)+reverse_heap1.GetKey(node); const int approximated_length = forward_heap1.GetKey(node) + reverse_heap1.GetKey(node);
bool lengthPassed = (approximated_length < upper_bound_to_shortest_path_distance*(1+VIAPATH_EPSILON)); const bool length_passes = (approximated_length < upper_bound_to_shortest_path_distance*(1+VIAPATH_EPSILON));
bool sharingPassed = (approximated_sharing <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA); const bool sharing_passes = (approximated_sharing <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA);
bool stretchPassed = approximated_length - approximated_sharing < (1.+VIAPATH_EPSILON)*(upper_bound_to_shortest_path_distance-approximated_sharing); const bool stretch_passes = (approximated_length - approximated_sharing) < ((1.+VIAPATH_EPSILON)*(upper_bound_to_shortest_path_distance-approximated_sharing));
if(lengthPassed && sharingPassed && stretchPassed) { if( length_passes && sharing_passes && stretch_passes ) {
nodes_that_passed_preselection.push_back(node); preselected_node_list.push_back(node);
} }
} }
SimpleLogger().Write() << preselected_node_list.size() << " passed preselection";
std::vector<NodeID> & packed_shortest_path = packed_forward_path; std::vector<NodeID> & packed_shortest_path = packed_forward_path;
std::reverse(packed_shortest_path.begin(), packed_shortest_path.end()); std::reverse(packed_shortest_path.begin(), packed_shortest_path.end());
packed_shortest_path.push_back(middle_node); packed_shortest_path.push_back(middle_node);
packed_shortest_path.insert(packed_shortest_path.end(),packed_reverse_path.begin(), packed_reverse_path.end()); packed_shortest_path.insert(
std::vector<RankedCandidateNode > rankedCandidates; packed_shortest_path.end(),
packed_reverse_path.begin(),
packed_reverse_path.end()
);
std::vector<RankedCandidateNode> ranked_candidates_list;
//prioritizing via nodes for deep inspection //prioritizing via nodes for deep inspection
BOOST_FOREACH(const NodeID node, nodes_that_passed_preselection) { BOOST_FOREACH(const NodeID node, preselected_node_list) {
int lengthOfViaPath = 0, sharingOfViaPath = 0; int length_of_via_path = 0, sharing_of_via_path = 0;
computeLengthAndSharingOfViaPath(node, &lengthOfViaPath, &sharingOfViaPath, forward_offset+reverse_offset, packed_shortest_path); ComputeLengthAndSharingOfViaPath(node, &length_of_via_path, &sharing_of_via_path, forward_offset+reverse_offset, packed_shortest_path);
if(sharingOfViaPath <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA) { const int maximum_allowed_sharing = upper_bound_to_shortest_path_distance*VIAPATH_GAMMA;
rankedCandidates.push_back(RankedCandidateNode(node, lengthOfViaPath, sharingOfViaPath)); if( sharing_of_via_path <= maximum_allowed_sharing ) {
ranked_candidates_list.push_back(
RankedCandidateNode(
node,
length_of_via_path,
sharing_of_via_path
)
);
} }
} }
std::sort(rankedCandidates.begin(), rankedCandidates.end()); std::sort(
ranked_candidates_list.begin(),
ranked_candidates_list.end()
);
NodeID selectedViaNode = UINT_MAX; NodeID selected_via_node = SPECIAL_NODEID;
int lengthOfViaPath = INT_MAX; int length_of_via_path = INVALID_EDGE_WEIGHT;
NodeID s_v_middle = UINT_MAX, v_t_middle = UINT_MAX; NodeID s_v_middle = SPECIAL_NODEID, v_t_middle = SPECIAL_NODEID;
BOOST_FOREACH(const RankedCandidateNode & candidate, rankedCandidates){ BOOST_FOREACH(const RankedCandidateNode & candidate, ranked_candidates_list){
if(viaNodeCandidatePasses_T_Test(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, candidate, forward_offset+reverse_offset, upper_bound_to_shortest_path_distance, &lengthOfViaPath, &s_v_middle, &v_t_middle)) { if(ViaNodeCandidatePassesTTest(forward_heap1, reverse_heap1, forward_heap2, reverse_heap2, candidate, forward_offset+reverse_offset, upper_bound_to_shortest_path_distance, &length_of_via_path, &s_v_middle, &v_t_middle)) {
// select first admissable // select first admissable
selectedViaNode = candidate.node; selected_via_node = candidate.node;
break; break;
} }
} }
//Unpack shortest path and alternative, if they exist //Unpack shortest path and alternative, if they exist
if(INT_MAX != upper_bound_to_shortest_path_distance) { if( INVALID_EDGE_WEIGHT != upper_bound_to_shortest_path_distance ) {
BOOST_ASSERT( !packed_shortest_path.empty() ); BOOST_ASSERT( !packed_shortest_path.empty() );
raw_route_data.unpacked_path_segments.resize(1); raw_route_data.unpacked_path_segments.resize(1);
// SimpleLogger().Write() << "fwd offset1: " << phantom_node_pair.startPhantom.fwd_segment_position; // SimpleLogger().Write() << "fwd offset1: " << phantom_node_pair.startPhantom.fwd_segment_position;
@ -306,48 +337,59 @@ public:
raw_route_data.unpacked_path_segments.front() raw_route_data.unpacked_path_segments.front()
); );
raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance; raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance;
} else { SimpleLogger().Write(logDEBUG) << "upper_bound_to_shortest_path_distance: " << upper_bound_to_shortest_path_distance;
//TODO: kill this branch by initialization
raw_route_data.lengthOfShortestPath = INT_MAX;
} }
if(selectedViaNode != UINT_MAX) { if(SPECIAL_NODEID != selected_via_node ) {
RetrieveAndUnpackAlternatePath( std::vector<NodeID> packed_alternate_path;
// retrieve alternate path
RetrievePackedAlternatePath(
forward_heap1, forward_heap1,
reverse_heap1, reverse_heap1,
forward_heap2, forward_heap2,
reverse_heap2, reverse_heap2,
s_v_middle, s_v_middle,
v_t_middle, v_t_middle,
packed_alternate_path
);
// unpack the alternate path
super::UnpackPath(
packed_alternate_path,
phantom_node_pair.startPhantom.packed_geometry_id,
phantom_node_pair.startPhantom.fwd_segment_position,
(packed_alternate_path.front() != phantom_node_pair.startPhantom.forward_node_id),
phantom_node_pair.targetPhantom.packed_geometry_id,
phantom_node_pair.targetPhantom.fwd_segment_position,
(packed_alternate_path.back() != phantom_node_pair.targetPhantom.forward_node_id),
raw_route_data.unpacked_alternative raw_route_data.unpacked_alternative
); );
raw_route_data.lengthOfAlternativePath = lengthOfViaPath;
} else { raw_route_data.lengthOfAlternativePath = length_of_via_path;
//TODO: kill this branch by initialization SimpleLogger().Write(logDEBUG) << "length_of_via_path: " << length_of_via_path;
raw_route_data.lengthOfAlternativePath = INT_MAX;
} }
} }
private: private:
//unpack <s,..,v,..,t> by exploring search spaces from v //unpack alternate <s,..,v,..,t> by exploring search spaces from v
inline void RetrieveAndUnpackAlternatePath( inline void RetrievePackedAlternatePath(
const QueryHeap & forward_heap1, const QueryHeap & forward_heap1,
const QueryHeap & reverse_heap1, const QueryHeap & reverse_heap1,
const QueryHeap & forward_heap2, const QueryHeap & forward_heap2,
const QueryHeap & reverse_heap2, const QueryHeap & reverse_heap2,
const NodeID s_v_middle, const NodeID s_v_middle,
const NodeID v_t_middle, const NodeID v_t_middle,
std::vector<PathData> & unpacked_path std::vector<NodeID> & packed_path
) const { ) const {
//fetch packed path [s,v) //fetch packed path [s,v)
std::vector<NodeID> packed_s_v_path, packed_v_t_path; std::vector<NodeID> packed_v_t_path;
super::RetrievePackedPathFromHeap( super::RetrievePackedPathFromHeap(
forward_heap1, forward_heap1,
reverse_heap2, reverse_heap2,
s_v_middle, s_v_middle,
packed_s_v_path packed_path
); );
packed_s_v_path.pop_back(); //remove v, other we get it twice packed_path.pop_back(); //remove middle node. It's in both half-paths
//fetch patched path [v,t] //fetch patched path [v,t]
super::RetrievePackedPathFromHeap( super::RetrievePackedPathFromHeap(
@ -357,22 +399,14 @@ private:
packed_v_t_path packed_v_t_path
); );
packed_s_v_path.insert( packed_path.insert(
packed_s_v_path.end(), packed_path.end(),
packed_v_t_path.begin(), packed_v_t_path.begin(),
packed_v_t_path.end() packed_v_t_path.end()
); );
// unpack, supply correct offsets to packed start and end nodes.
super::UnpackPath(
packed_s_v_path,
SPECIAL_EDGEID, 0, false, //TODO: replace with actual data
SPECIAL_EDGEID, 0, false, //TODO: replace with actual data
unpacked_path
);
} }
inline void computeLengthAndSharingOfViaPath(const NodeID via_node, int *real_length_of_via_path, int *sharing_of_via_path, inline void ComputeLengthAndSharingOfViaPath(const NodeID via_node, int *real_length_of_via_path, int *sharing_of_via_path,
const int offset, const std::vector<NodeID> & packed_shortest_path) { const int offset, const std::vector<NodeID> & packed_shortest_path) {
//compute and unpack <s,..,v> and <v,..,t> by exploring search spaces from v and intersecting against queues //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 //only half-searches have to be done at this stage
@ -380,80 +414,114 @@ private:
super::facade->GetNumberOfNodes() super::facade->GetNumberOfNodes()
); );
QueryHeap & existingForwardHeap = *engine_working_data.forwardHeap; QueryHeap & existing_forward_heap = *engine_working_data.forwardHeap;
QueryHeap & existingBackwardHeap = *engine_working_data.backwardHeap; QueryHeap & existing_reverse_heap = *engine_working_data.backwardHeap;
QueryHeap & newForwardHeap = *engine_working_data.forwardHeap2; QueryHeap & new_forward_heap = *engine_working_data.forwardHeap2;
QueryHeap & newBackwardHeap = *engine_working_data.backwardHeap2; QueryHeap & new_reverse_heap = *engine_working_data.backwardHeap2;
std::vector < NodeID > packed_s_v_path; std::vector<NodeID> packed_s_v_path;
std::vector < NodeID > packed_v_t_path; std::vector<NodeID> packed_v_t_path;
std::vector<NodeID> partiallyUnpacked_shortest_path; std::vector<NodeID> partially_unpacked_shortest_path;
std::vector<NodeID> partiallyUnpackedViaPath; std::vector<NodeID> partially_unpacked_via_path;
NodeID s_v_middle = UINT_MAX; NodeID s_v_middle = SPECIAL_NODEID;
int upperBoundFor_s_vPath = INT_MAX;//compute path <s,..,v> by reusing forward search from s int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT;
newBackwardHeap.Insert(via_node, 0, via_node); new_reverse_heap.Insert(via_node, 0, via_node);
while (0 < newBackwardHeap.Size()) { //compute path <s,..,v> by reusing forward search from s
super::RoutingStep(newBackwardHeap, existingForwardHeap, &s_v_middle, &upperBoundFor_s_vPath, 2 * offset, false); while( !new_reverse_heap.Empty() ) {
super::RoutingStep(
new_reverse_heap,
existing_forward_heap,
&s_v_middle,
&upper_bound_s_v_path_length,
2 * offset,
false
);
} }
//compute path <v,..,t> by reusing backward search from node t //compute path <v,..,t> by reusing backward search from node t
NodeID v_t_middle = UINT_MAX; NodeID v_t_middle = SPECIAL_NODEID;
int upperBoundFor_v_tPath = INT_MAX; int upper_bound_of_v_t_path_length = INVALID_EDGE_WEIGHT;
newForwardHeap.Insert(via_node, 0, via_node); new_forward_heap.Insert(via_node, 0, via_node);
while (0 < newForwardHeap.Size() ) { while(!new_forward_heap.Empty() ) {
super::RoutingStep(newForwardHeap, existingBackwardHeap, &v_t_middle, &upperBoundFor_v_tPath, 2 * offset, true); super::RoutingStep(
new_forward_heap,
existing_reverse_heap,
&v_t_middle,
&upper_bound_of_v_t_path_length,
2 * offset,
true
);
} }
*real_length_of_via_path = upperBoundFor_s_vPath + upperBoundFor_v_tPath; *real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length;
if(UINT_MAX == s_v_middle || UINT_MAX == v_t_middle) if( SPECIAL_NODEID == s_v_middle || SPECIAL_NODEID == v_t_middle ) {
return; return;
}
//retrieve packed paths //retrieve packed paths
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, s_v_middle, packed_s_v_path); super::RetrievePackedPathFromHeap(
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, v_t_middle, packed_v_t_path); existing_forward_heap,
new_reverse_heap,
s_v_middle,
packed_s_v_path
);
super::RetrievePackedPathFromHeap(
new_forward_heap,
existing_reverse_heap,
v_t_middle,
packed_v_t_path
);
//partial unpacking, compute sharing //partial unpacking, compute sharing
//First partially unpack s-->v until paths deviate, note length of common path. //First partially unpack s-->v until paths deviate, note length of common path.
for (unsigned i = 0, lengthOfPackedPath = std::min( packed_s_v_path.size(), packed_shortest_path.size()) - 1; (i < lengthOfPackedPath); ++i) { const unsigned s_v_min_path_size = std::min( packed_s_v_path.size(), packed_shortest_path.size()) - 1;
if (packed_s_v_path[i] == packed_shortest_path[i] && packed_s_v_path[i + 1] == packed_shortest_path[i + 1]) { for(
unsigned i = 0;
i < s_v_min_path_size;
++i
) {
if(packed_s_v_path[i] == packed_shortest_path[i] && packed_s_v_path[i + 1] == packed_shortest_path[i + 1]) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]); EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else { } else {
if (packed_s_v_path[i] == packed_shortest_path[i]) { if( packed_s_v_path[i] == packed_shortest_path[i] ) {
super::UnpackEdge(packed_s_v_path[i], packed_s_v_path[i+1], partiallyUnpackedViaPath); super::UnpackEdge(packed_s_v_path[i], packed_s_v_path[i+1], partially_unpacked_via_path);
super::UnpackEdge(packed_shortest_path[i], packed_shortest_path[i+1], partiallyUnpacked_shortest_path); super::UnpackEdge(packed_shortest_path[i], packed_shortest_path[i+1], partially_unpacked_shortest_path);
break; break;
} }
} }
} }
//traverse partially unpacked edge and note common prefix //traverse partially unpacked edge and note common prefix
for (int i = 0, lengthOfPackedPath = std::min( partiallyUnpackedViaPath.size(), partiallyUnpacked_shortest_path.size()) - 1; (i < lengthOfPackedPath) && (partiallyUnpackedViaPath[i] == partiallyUnpacked_shortest_path[i] && partiallyUnpackedViaPath[i+1] == partiallyUnpacked_shortest_path[i+1]); ++i) { for (int i = 0, packed_path_length = std::min( partially_unpacked_via_path.size(), partially_unpacked_shortest_path.size()) - 1; (i < packed_path_length) && (partially_unpacked_via_path[i] == partially_unpacked_shortest_path[i] && partially_unpacked_via_path[i+1] == partially_unpacked_shortest_path[i+1]); ++i) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(partiallyUnpackedViaPath[i], partiallyUnpackedViaPath[i+1]); EdgeID edgeID = facade->FindEdgeInEitherDirection(partially_unpacked_via_path[i], partially_unpacked_via_path[i+1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} }
//Second, partially unpack v-->t in reverse order until paths deviate and note lengths //Second, partially unpack v-->t in reverse order until paths deviate and note lengths
int viaPathIndex = packed_v_t_path.size() - 1; int via_path_index = packed_v_t_path.size() - 1;
int shortestPathIndex = packed_shortest_path.size() - 1; int shortest_path_index = packed_shortest_path.size() - 1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex ) { for (;
if (packed_v_t_path[viaPathIndex - 1] == packed_shortest_path[shortestPathIndex - 1] && packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) { via_path_index > 0 && shortest_path_index > 0;
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[viaPathIndex - 1], packed_v_t_path[viaPathIndex]); --via_path_index,--shortest_path_index
) {
if (packed_v_t_path[via_path_index-1] == packed_shortest_path[shortest_path_index-1] && packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index]) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[via_path_index-1], packed_v_t_path[via_path_index]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else { } else {
if (packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) { if (packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index]) {
super::UnpackEdge(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex], partiallyUnpackedViaPath); super::UnpackEdge(packed_v_t_path[via_path_index-1], packed_v_t_path[via_path_index], partially_unpacked_via_path);
super::UnpackEdge(packed_shortest_path[shortestPathIndex-1] , packed_shortest_path[shortestPathIndex], partiallyUnpacked_shortest_path); super::UnpackEdge(packed_shortest_path[shortest_path_index-1] , packed_shortest_path[shortest_path_index], partially_unpacked_shortest_path);
break; break;
} }
} }
} }
viaPathIndex = partiallyUnpackedViaPath.size() - 1; via_path_index = partially_unpacked_via_path.size()-1;
shortestPathIndex = partiallyUnpacked_shortest_path.size() - 1; shortest_path_index = partially_unpacked_shortest_path.size()-1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex) { for (; via_path_index > 0 && shortest_path_index > 0; --via_path_index,--shortest_path_index) {
if (partiallyUnpackedViaPath[viaPathIndex - 1] == partiallyUnpacked_shortest_path[shortestPathIndex - 1] && partiallyUnpackedViaPath[viaPathIndex] == partiallyUnpacked_shortest_path[shortestPathIndex]) { if (partially_unpacked_via_path[via_path_index-1] == partially_unpacked_shortest_path[shortest_path_index-1] && partially_unpacked_via_path[via_path_index] == partially_unpacked_shortest_path[shortest_path_index]) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( partiallyUnpackedViaPath[viaPathIndex - 1], partiallyUnpackedViaPath[viaPathIndex]); EdgeID edgeID = facade->FindEdgeInEitherDirection( partially_unpacked_via_path[via_path_index-1], partially_unpacked_via_path[via_path_index]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else { } else {
break; break;
@ -462,241 +530,322 @@ private:
//finished partial unpacking spree! Amount of sharing is stored to appropriate pointer variable //finished partial unpacking spree! Amount of sharing is stored to appropriate pointer variable
} }
inline int approximateAmountOfSharing(const NodeID middleNodeIDOfAlternativePath, QueryHeap & _forwardHeap, QueryHeap & _backwardHeap, const std::vector<NodeID> & packed_shortest_path) { // inline int approximateAmountOfSharing(
std::vector<NodeID> packedAlternativePath; // const NodeID alternate_path_middle_node_id,
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath); // QueryHeap & forward_heap,
// QueryHeap & reverse_heap,
// const std::vector<NodeID> & packed_shortest_path
// ) const {
// std::vector<NodeID> packed_alternate_path;
// super::RetrievePackedPathFromHeap(
// forward_heap,
// reverse_heap,
// alternate_path_middle_node_id,
// packed_alternate_path
// );
if(packed_shortest_path.size() < 2 || packedAlternativePath.size() < 2) // if(packed_shortest_path.size() < 2 || packed_alternate_path.size() < 2) {
return 0; // return 0;
// }
int sharing = 0; // int sharing = 0;
int aindex = 0; // int aindex = 0;
//compute forward sharing // //compute forward sharing
while( (packedAlternativePath[aindex] == packed_shortest_path[aindex]) && (packedAlternativePath[aindex+1] == packed_shortest_path[aindex+1]) ) { // while( (packed_alternate_path[aindex] == packed_shortest_path[aindex]) && (packed_alternate_path[aindex+1] == packed_shortest_path[aindex+1]) ) {
// SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")"; // // SimpleLogger().Write() << "retrieving edge (" << packed_alternate_path[aindex] << "," << packed_alternate_path[aindex+1] << ")";
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]); // EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_alternate_path[aindex], packed_alternate_path[aindex+1]);
sharing += facade->GetEdgeData(edgeID).distance; // sharing += facade->GetEdgeData(edgeID).distance;
++aindex; // ++aindex;
} // }
aindex = packedAlternativePath.size()-1; // aindex = packed_alternate_path.size()-1;
int bindex = packed_shortest_path.size()-1; // int bindex = packed_shortest_path.size()-1;
//compute backward sharing // //compute backward sharing
while( aindex > 0 && bindex > 0 && (packedAlternativePath[aindex] == packed_shortest_path[bindex]) && (packedAlternativePath[aindex-1] == packed_shortest_path[bindex-1]) ) { // while( aindex > 0 && bindex > 0 && (packed_alternate_path[aindex] == packed_shortest_path[bindex]) && (packed_alternate_path[aindex-1] == packed_shortest_path[bindex-1]) ) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex-1]); // EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_alternate_path[aindex], packed_alternate_path[aindex-1]);
sharing += facade->GetEdgeData(edgeID).distance; // sharing += facade->GetEdgeData(edgeID).distance;
--aindex; --bindex; // --aindex; --bindex;
} // }
return sharing; // return sharing;
} // }
template<bool forwardDirection> template<bool is_forward_directed>
inline void AlternativeRoutingStep( inline void AlternativeRoutingStep(
QueryHeap & _forward_heap, QueryHeap & forward_heap,
QueryHeap & _reverse_heap, QueryHeap & reverse_heap,
NodeID *middle_node, NodeID * middle_node,
int *upper_bound_to_shortest_path_distance, int * upper_bound_to_shortest_path_distance,
std::vector<NodeID>& searchSpaceIntersection, std::vector<NodeID> & search_space_intersection,
std::vector<SearchSpaceEdge> & search_space, std::vector<SearchSpaceEdge> & search_space,
const int edgeBasedOffset const int edge_expansion_offset
) const { ) const {
const NodeID node = _forward_heap.DeleteMin(); const NodeID node = forward_heap.DeleteMin();
const int distance = _forward_heap.GetKey(node); const int distance = forward_heap.GetKey(node);
int scaledDistance = (distance-edgeBasedOffset)/(1.+VIAPATH_EPSILON); const int scaled_distance = (distance-edge_expansion_offset)/(1.+VIAPATH_EPSILON);
if(scaledDistance > *upper_bound_to_shortest_path_distance){ if( scaled_distance > *upper_bound_to_shortest_path_distance ){
_forward_heap.DeleteAll(); forward_heap.DeleteAll();
return; return;
} }
search_space.push_back(std::make_pair(_forward_heap.GetData( node ).parent, node)); search_space.push_back(
std::make_pair(forward_heap.GetData( node ).parent, node)
);
if(_reverse_heap.WasInserted(node) ){ if( reverse_heap.WasInserted(node) ) {
searchSpaceIntersection.push_back(node); search_space_intersection.push_back(node);
const int newDistance = _reverse_heap.GetKey(node) + distance; const int new_distance = reverse_heap.GetKey(node) + distance;
if(newDistance < *upper_bound_to_shortest_path_distance ){ if( new_distance < *upper_bound_to_shortest_path_distance ){
if(newDistance>=0 ) { if( new_distance >= 0 ) {
*middle_node = node; *middle_node = node;
*upper_bound_to_shortest_path_distance = newDistance; *upper_bound_to_shortest_path_distance = new_distance;
} }
} }
} }
for ( EdgeID edge = facade->BeginEdges( node ); edge < facade->EndEdges(node); edge++ ) { for(
EdgeID edge = facade->BeginEdges(node);
edge < facade->EndEdges(node);
++edge
) {
const EdgeData & data = facade->GetEdgeData(edge); const EdgeData & data = facade->GetEdgeData(edge);
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward ); const bool edge_is_forward_directed = (is_forward_directed ? data.forward : data.backward );
if(forwardDirectionFlag) { if( edge_is_forward_directed ) {
const NodeID to = facade->GetTarget(edge); const NodeID to = facade->GetTarget(edge);
const int edgeWeight = data.distance; const int edge_weight = data.distance;
assert( edgeWeight > 0 ); BOOST_ASSERT( edge_weight > 0 );
const int toDistance = distance + edgeWeight; const int to_distance = distance + edge_weight;
//New Node discovered -> Add to Heap + Node Info Storage //New Node discovered -> Add to Heap + Node Info Storage
if ( !_forward_heap.WasInserted( to ) ) { if ( !forward_heap.WasInserted( to ) ) {
_forward_heap.Insert( to, toDistance, node ); forward_heap.Insert( to, to_distance, node );
} }
//Found a shorter Path -> Update distance //Found a shorter Path -> Update distance
else if ( toDistance < _forward_heap.GetKey( to ) ) { else if ( to_distance < forward_heap.GetKey( to ) ) {
_forward_heap.GetData( to ).parent = node; // new parent
_forward_heap.DecreaseKey( to, toDistance ); forward_heap.GetData( to ).parent = node;
//new parent // decreased distance
forward_heap.DecreaseKey( to, to_distance );
} }
} }
} }
} }
//conduct T-Test //conduct T-Test
inline bool viaNodeCandidatePasses_T_Test( QueryHeap& existingForwardHeap, QueryHeap& existingBackwardHeap, QueryHeap& newForwardHeap, QueryHeap& newBackwardHeap, const RankedCandidateNode& candidate, const int offset, const int lengthOfShortestPath, int * lengthOfViaPath, NodeID * s_v_middle, NodeID * v_t_middle) { inline bool ViaNodeCandidatePassesTTest(
newForwardHeap.Clear(); QueryHeap& existing_forward_heap,
newBackwardHeap.Clear(); QueryHeap& existing_reverse_heap,
std::vector < NodeID > packed_s_v_path; QueryHeap& new_forward_heap,
std::vector < NodeID > packed_v_t_path; QueryHeap& new_reverse_heap,
const RankedCandidateNode& candidate,
const int offset,
const int lengthOfShortestPath,
int * length_of_via_path,
NodeID * s_v_middle,
NodeID * v_t_middle
) const {
new_forward_heap.Clear();
new_reverse_heap.Clear();
std::vector<NodeID> packed_s_v_path;
std::vector<NodeID> packed_v_t_path;
*s_v_middle = UINT_MAX; *s_v_middle = SPECIAL_NODEID;
int upperBoundFor_s_vPath = INT_MAX; int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT;
//compute path <s,..,v> by reusing forward search from s //compute path <s,..,v> by reusing forward search from s
newBackwardHeap.Insert(candidate.node, 0, candidate.node); new_reverse_heap.Insert(candidate.node, 0, candidate.node);
while (newBackwardHeap.Size() > 0) { while (new_reverse_heap.Size() > 0) {
super::RoutingStep(newBackwardHeap, existingForwardHeap, s_v_middle, &upperBoundFor_s_vPath, 2*offset, false); super::RoutingStep(new_reverse_heap, existing_forward_heap, s_v_middle, &upper_bound_s_v_path_length, 2*offset, false);
} }
if(INT_MAX == upperBoundFor_s_vPath) if( INVALID_EDGE_WEIGHT == upper_bound_s_v_path_length ) {
return false; return false;
}
//compute path <v,..,t> by reusing backward search from t //compute path <v,..,t> by reusing backward search from t
*v_t_middle = UINT_MAX; *v_t_middle = SPECIAL_NODEID;
int upperBoundFor_v_tPath = INT_MAX; int upper_bound_of_v_t_path_length = INVALID_EDGE_WEIGHT;
newForwardHeap.Insert(candidate.node, 0, candidate.node); new_forward_heap.Insert(candidate.node, 0, candidate.node);
while (newForwardHeap.Size() > 0) { while (new_forward_heap.Size() > 0) {
super::RoutingStep(newForwardHeap, existingBackwardHeap, v_t_middle, &upperBoundFor_v_tPath, 2*offset, true); super::RoutingStep(new_forward_heap, existing_reverse_heap, v_t_middle, &upper_bound_of_v_t_path_length, 2*offset, true);
} }
if(INT_MAX == upperBoundFor_v_tPath) if( INVALID_EDGE_WEIGHT == upper_bound_of_v_t_path_length ){
return false; return false;
}
*lengthOfViaPath = upperBoundFor_s_vPath + upperBoundFor_v_tPath; *length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length;
//retrieve packed paths //retrieve packed paths
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, *s_v_middle, packed_s_v_path); super::RetrievePackedPathFromHeap(
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, *v_t_middle, packed_v_t_path); existing_forward_heap,
new_reverse_heap,
*s_v_middle,
packed_s_v_path
);
super::RetrievePackedPathFromHeap(
new_forward_heap,
existing_reverse_heap,
*v_t_middle,
packed_v_t_path
);
NodeID s_P = *s_v_middle, t_P = *v_t_middle; NodeID s_P = *s_v_middle, t_P = *v_t_middle;
if(UINT_MAX == s_P) { if( SPECIAL_NODEID == s_P ) {
return false; return false;
} }
if(UINT_MAX == t_P) { if( SPECIAL_NODEID == t_P ) {
return false; return false;
} }
const int T_threshold = VIAPATH_EPSILON * lengthOfShortestPath; const int T_threshold = VIAPATH_EPSILON * lengthOfShortestPath;
int unpackedUntilDistance = 0; int unpacked_until_distance = 0;
std::stack<SearchSpaceEdge> unpackStack; std::stack<SearchSpaceEdge> unpack_stack;
//Traverse path s-->v //Traverse path s-->v
for (unsigned i = packed_s_v_path.size() - 1; (i > 0) && unpackStack.empty(); --i) { for(
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_s_v_path[i - 1], packed_s_v_path[i]); unsigned i = packed_s_v_path.size() - 1;
int lengthOfCurrentEdge = facade->GetEdgeData(edgeID).distance; (i > 0) && unpack_stack.empty();
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) { --i
unpackStack.push(std::make_pair(packed_s_v_path[i - 1], packed_s_v_path[i])); ) {
const EdgeID current_edge_id = facade->FindEdgeInEitherDirection( packed_s_v_path[i - 1], packed_s_v_path[i]);
const int length_of_current_edge = facade->GetEdgeData(current_edge_id).distance;
if( (length_of_current_edge + unpacked_until_distance) >= T_threshold ) {
unpack_stack.push(
std::make_pair(packed_s_v_path[i - 1], packed_s_v_path[i])
);
} else { } else {
unpackedUntilDistance += lengthOfCurrentEdge; unpacked_until_distance += length_of_current_edge;
s_P = packed_s_v_path[i - 1]; s_P = packed_s_v_path[i - 1];
} }
} }
while (!unpackStack.empty()) { while( !unpack_stack.empty() ) {
const SearchSpaceEdge viaPathEdge = unpackStack.top(); const SearchSpaceEdge via_path_edge = unpack_stack.top();
unpackStack.pop(); unpack_stack.pop();
EdgeID edgeIDInViaPath = facade->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second); EdgeID edge_in_via_path_id = facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
if(UINT_MAX == edgeIDInViaPath) if( SPECIAL_EDGEID == edge_in_via_path_id ) {
return false; return false;
EdgeData currentEdgeData = facade->GetEdgeData(edgeIDInViaPath); }
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if (IsViaEdgeShortCut) { const EdgeData & current_edge_data = facade->GetEdgeData(edge_in_via_path_id);
const NodeID middleOfViaPath = currentEdgeData.id; const bool current_edge_is_shortcut = current_edge_data.shortcut;
EdgeID edgeIDOfSecondSegment = facade->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second); if( current_edge_is_shortcut ) {
int lengthOfSecondSegment = facade->GetEdgeData(edgeIDOfSecondSegment).distance; const NodeID via_path_middle_node_id = current_edge_data.id;
const EdgeID second_segment_edge_id = facade->FindEdgeInEitherDirection(via_path_middle_node_id, via_path_edge.second);
const int second_segment_length = facade->GetEdgeData(second_segment_edge_id).distance;
//attention: !unpacking in reverse! //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. //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) { if (unpacked_until_distance + second_segment_length >= T_threshold) {
unpackStack.push(std::make_pair(middleOfViaPath, viaPathEdge.second)); unpack_stack.push(
std::make_pair(
via_path_middle_node_id,
via_path_edge.second
)
);
} else { } else {
unpackedUntilDistance += lengthOfSecondSegment; unpacked_until_distance += second_segment_length;
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath)); unpack_stack.push(
std::make_pair(
via_path_edge.first,
via_path_middle_node_id
)
);
} }
} else { } else {
// edge is not a shortcut, set the start node for T-Test to end of edge. // edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance; unpacked_until_distance += current_edge_data.distance;
s_P = viaPathEdge.first; s_P = via_path_edge.first;
} }
} }
int lengthOfPathT_TestPath = unpackedUntilDistance; int t_test_path_length = unpacked_until_distance;
unpackedUntilDistance = 0; unpacked_until_distance = 0;
//Traverse path s-->v //Traverse path s-->v
for (unsigned i = 0, lengthOfPackedPath = packed_v_t_path.size() - 1; (i < lengthOfPackedPath) && unpackStack.empty(); ++i) { for(
unsigned i = 0, packed_path_length = packed_v_t_path.size() - 1;
(i < packed_path_length) && unpack_stack.empty();
++i
) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[i], packed_v_t_path[i + 1]); EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[i], packed_v_t_path[i + 1]);
int lengthOfCurrentEdge = facade->GetEdgeData(edgeID).distance; int length_of_current_edge = facade->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) { if (length_of_current_edge + unpacked_until_distance >= T_threshold) {
unpackStack.push( std::make_pair(packed_v_t_path[i], packed_v_t_path[i + 1])); unpack_stack.push( std::make_pair(packed_v_t_path[i], packed_v_t_path[i + 1]));
} else { } else {
unpackedUntilDistance += lengthOfCurrentEdge; unpacked_until_distance += length_of_current_edge;
t_P = packed_v_t_path[i + 1]; t_P = packed_v_t_path[i + 1];
} }
} }
while (!unpackStack.empty()) { while (!unpack_stack.empty()) {
const SearchSpaceEdge viaPathEdge = unpackStack.top(); const SearchSpaceEdge via_path_edge = unpack_stack.top();
unpackStack.pop(); unpack_stack.pop();
EdgeID edgeIDInViaPath = facade->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second); EdgeID edge_in_via_path_id = facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
if(UINT_MAX == edgeIDInViaPath) if(SPECIAL_EDGEID == edge_in_via_path_id) {
return false; return false;
EdgeData currentEdgeData = facade->GetEdgeData(edgeIDInViaPath); }
const bool IsViaEdgeShortCut = currentEdgeData.shortcut;
const EdgeData & current_edge_data = facade->GetEdgeData(edge_in_via_path_id);
const bool IsViaEdgeShortCut = current_edge_data.shortcut;
if (IsViaEdgeShortCut) { if (IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id; const NodeID middleOfViaPath = current_edge_data.id;
EdgeID edgeIDOfFirstSegment = facade->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath); EdgeID edgeIDOfFirstSegment = facade->FindEdgeInEitherDirection(via_path_edge.first, middleOfViaPath);
int lengthOfFirstSegment = facade->GetEdgeData( edgeIDOfFirstSegment).distance; int lengthOfFirstSegment = facade->GetEdgeData( edgeIDOfFirstSegment).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. //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) { if (unpacked_until_distance + lengthOfFirstSegment >= T_threshold) {
unpackStack.push( std::make_pair(viaPathEdge.first, middleOfViaPath)); unpack_stack.push( std::make_pair(via_path_edge.first, middleOfViaPath));
} else { } else {
unpackedUntilDistance += lengthOfFirstSegment; unpacked_until_distance += lengthOfFirstSegment;
unpackStack.push( std::make_pair(middleOfViaPath, viaPathEdge.second)); unpack_stack.push( std::make_pair(middleOfViaPath, via_path_edge.second));
} }
} else { } else {
// edge is not a shortcut, set the start node for T-Test to end of edge. // edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance; unpacked_until_distance += current_edge_data.distance;
t_P = viaPathEdge.second; t_P = via_path_edge.second;
} }
} }
lengthOfPathT_TestPath += unpackedUntilDistance; t_test_path_length += unpacked_until_distance;
//Run actual T-Test query and compare if distances equal. //Run actual T-Test query and compare if distances equal.
engine_working_data.InitializeOrClearThirdThreadLocalStorage( engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes() super::facade->GetNumberOfNodes()
); );
QueryHeap& forward_heap3 = *engine_working_data.forwardHeap3; QueryHeap & forward_heap3 = *engine_working_data.forwardHeap3;
QueryHeap& backward_heap3 = *engine_working_data.backwardHeap3; QueryHeap & reverse_heap3 = *engine_working_data.backwardHeap3;
int _upperBound = INT_MAX; int upper_bound = INVALID_EDGE_WEIGHT;
NodeID middle = UINT_MAX; NodeID middle = SPECIAL_NODEID;
forward_heap3.Insert(s_P, 0, s_P); forward_heap3.Insert(s_P, 0, s_P);
backward_heap3.Insert(t_P, 0, t_P); reverse_heap3.Insert(t_P, 0, t_P);
//exploration from s and t until deletemin/(1+epsilon) > _lengthOfShortestPath //exploration from s and t until deletemin/(1+epsilon) > _lengthOfShortestPath
while (forward_heap3.Size() + backward_heap3.Size() > 0) { while( (forward_heap3.Size() + reverse_heap3.Size() ) > 0) {
if (forward_heap3.Size() > 0) { if( !forward_heap3.Empty() ) {
super::RoutingStep(forward_heap3, backward_heap3, &middle, &_upperBound, offset, true); super::RoutingStep(
forward_heap3,
reverse_heap3,
&middle,
&upper_bound,
offset,
true
);
} }
if (backward_heap3.Size() > 0) { if( !reverse_heap3.Empty() ) {
super::RoutingStep(backward_heap3, forward_heap3, &middle, &_upperBound, offset, false); super::RoutingStep(
reverse_heap3,
forward_heap3,
&middle,
&upper_bound,
offset,
false
);
} }
} }
return (_upperBound <= lengthOfPathT_TestPath); return (upper_bound <= t_test_path_length);
} }
}; };
#endif /* ALTERNATIVEROUTES_H_ */ #endif /* ALTERNATIVE_PATH_ROUTING_H */

View File

@ -200,10 +200,10 @@ public:
} }
} }
} }
BOOST_ASSERT_MSG(edge_weight != INT_MAX, "edge id invalid"); BOOST_ASSERT_MSG(edge_weight != SPECIAL_EDGEID, "edge id invalid");
BOOST_ASSERT( facade->EndEdges(edge.first) != smaller_edge_id ); // BOOST_ASSERT( facade->EndEdges(edge.first) != smaller_edge_id );
const EdgeData& ed = facade->GetEdgeData(smaller_edge_id); const EdgeData& ed = facade->GetEdgeData(smaller_edge_id);
if( ed.shortcut ) {//unpack if( ed.shortcut ) {//unpack
@ -368,7 +368,7 @@ public:
current_node_id = forward_heap.GetData(current_node_id).parent; current_node_id = forward_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id); packed_path.push_back(current_node_id);
} }
SimpleLogger().Write() << "parent of last node. " << forward_heap.GetData(current_node_id).parent; // SimpleLogger().Write() << "parent of last node. " << forward_heap.GetData(current_node_id).parent;
std::reverse(packed_path.begin(), packed_path.end()); std::reverse(packed_path.begin(), packed_path.end());
packed_path.push_back(middle_node_id); packed_path.push_back(middle_node_id);
current_node_id = middle_node_id; current_node_id = middle_node_id;
@ -376,11 +376,6 @@ public:
current_node_id = reverse_heap.GetData(current_node_id).parent; current_node_id = reverse_heap.GetData(current_node_id).parent;
packed_path.push_back(current_node_id); packed_path.push_back(current_node_id);
} }
SimpleLogger().Write(logDEBUG) << "packed path";
BOOST_FOREACH(NodeID node, packed_path) {
SimpleLogger().Write(logDEBUG) << "node: " << node;
}
} }
//TODO: reorder parameters //TODO: reorder parameters

View File

@ -60,9 +60,9 @@ public:
const PhantomNodes & phantom_node_pair, const PhantomNodes & phantom_node_pair,
phantom_nodes_vector phantom_nodes_vector
){ ){
if(!phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX()) { if( phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX() ) {
raw_route_data.lengthOfShortestPath = INT_MAX; // raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX; // raw_route_data.lengthOfAlternativePath = INT_MAX;
return; return;
} }
} }
@ -104,9 +104,10 @@ public:
middle2 = UINT_MAX; middle2 = UINT_MAX;
//insert new starting nodes into forward heap, adjusted by previous distances. //insert new starting nodes into forward heap, adjusted by previous distances.
if(search_from_1st_node) { if(
BOOST_ASSERT(phantom_node_pair.startPhantom.forward_node_id != UINT_MAX); search_from_1st_node &&
phantom_node_pair.startPhantom.forward_node_id != SPECIAL_NODEID
) {
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.forward_node_id, phantom_node_pair.startPhantom.forward_node_id,
distance1-phantom_node_pair.startPhantom.GetForwardWeightPlusOffset(), distance1-phantom_node_pair.startPhantom.GetForwardWeightPlusOffset(),
@ -118,8 +119,10 @@ public:
phantom_node_pair.startPhantom.forward_node_id phantom_node_pair.startPhantom.forward_node_id
); );
} }
if(phantom_node_pair.startPhantom.isBidirected() && search_from_2nd_node) { if(
BOOST_ASSERT(phantom_node_pair.startPhantom.reverse_node_id != UINT_MAX); search_from_2nd_node &&
phantom_node_pair.startPhantom.reverse_node_id != SPECIAL_NODEID
) {
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.startPhantom.reverse_node_id, phantom_node_pair.startPhantom.reverse_node_id,
distance2-phantom_node_pair.startPhantom.GetReverseWeightPlusOffset(), distance2-phantom_node_pair.startPhantom.GetReverseWeightPlusOffset(),
@ -133,15 +136,15 @@ public:
} }
//insert new backward nodes into backward heap, unadjusted. //insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert( if( phantom_node_pair.targetPhantom.forward_node_id != SPECIAL_NODEID ) {
phantom_node_pair.targetPhantom.forward_node_id, reverse_heap1.Insert(
phantom_node_pair.targetPhantom.GetForwardWeightPlusOffset(), phantom_node_pair.targetPhantom.forward_node_id,
phantom_node_pair.targetPhantom.forward_node_id phantom_node_pair.targetPhantom.GetForwardWeightPlusOffset(),
); phantom_node_pair.targetPhantom.forward_node_id
BOOST_ASSERT(phantom_node_pair.targetPhantom.forward_node_id != UINT_MAX); );
}
if(phantom_node_pair.targetPhantom.isBidirected() ) { if( phantom_node_pair.targetPhantom.reverse_node_id != SPECIAL_NODEID ) {
BOOST_ASSERT(phantom_node_pair.startPhantom.forward_node_id != UINT_MAX);
reverse_heap2.Insert( reverse_heap2.Insert(
phantom_node_pair.targetPhantom.reverse_node_id, phantom_node_pair.targetPhantom.reverse_node_id,
phantom_node_pair.targetPhantom.GetReverseWeightPlusOffset(), phantom_node_pair.targetPhantom.GetReverseWeightPlusOffset(),
@ -207,17 +210,17 @@ public:
//No path found for both target nodes? //No path found for both target nodes?
if( if(
(INT_MAX == local_upper_bound1) && (INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INT_MAX == local_upper_bound2) (INVALID_EDGE_WEIGHT == local_upper_bound2)
) { ) {
raw_route_data.lengthOfShortestPath = INT_MAX; raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
raw_route_data.lengthOfAlternativePath = INT_MAX; raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
return; return;
} }
if(UINT_MAX == middle1) { if( SPECIAL_NODEID == middle1 ) {
search_from_1st_node = false; search_from_1st_node = false;
} }
if(UINT_MAX == middle2) { if( SPECIAL_NODEID == middle2 ) {
search_from_2nd_node = false; search_from_2nd_node = false;
} }
@ -234,7 +237,7 @@ public:
BOOST_ASSERT( (unsigned)current_leg < packed_legs1.size() ); BOOST_ASSERT( (unsigned)current_leg < packed_legs1.size() );
BOOST_ASSERT( (unsigned)current_leg < packed_legs2.size() ); BOOST_ASSERT( (unsigned)current_leg < packed_legs2.size() );
if(INT_MAX != local_upper_bound1) { if( INVALID_EDGE_WEIGHT != local_upper_bound1 ) {
super::RetrievePackedPathFromHeap( super::RetrievePackedPathFromHeap(
forward_heap1, forward_heap1,
reverse_heap1, reverse_heap1,
@ -243,7 +246,7 @@ public:
); );
} }
if(INT_MAX != local_upper_bound2) { if( INVALID_EDGE_WEIGHT != local_upper_bound2 ) {
super::RetrievePackedPathFromHeap( super::RetrievePackedPathFromHeap(
forward_heap2, forward_heap2,
reverse_heap2, reverse_heap2,
@ -360,14 +363,34 @@ public:
for(unsigned i = 0; i < packed_legs1.size(); ++i){ for(unsigned i = 0; i < packed_legs1.size(); ++i){
BOOST_ASSERT( !phantom_nodes_vector.empty() ); BOOST_ASSERT( !phantom_nodes_vector.empty() );
bool at_beginning = (0 == i); const bool at_beginning = (0 == i);
const bool at_end = (packed_legs1.size() == i+1);
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size() ); BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size() );
super::UnpackPath( super::UnpackPath(
// -- packed input
packed_legs1[i], packed_legs1[i],
SPECIAL_EDGEID, ( at_beginning ? start_offset : 0), false, // -- start of route
SPECIAL_EDGEID, 0, false, ( !at_beginning ? SPECIAL_EDGEID : phantom_nodes_vector.front().startPhantom.packed_geometry_id ),
( !at_beginning ? 0 : phantom_nodes_vector.front().startPhantom.fwd_segment_position ),
( !at_beginning ? false : (packed_legs1.front().front() != phantom_nodes_vector.front().startPhantom.forward_node_id) ),
// -- end of route
( !at_end ? SPECIAL_EDGEID : phantom_nodes_vector.back().targetPhantom.packed_geometry_id ),
( !at_end ? 0 : phantom_nodes_vector.back().targetPhantom.fwd_segment_position ),
( !at_end ? false : (packed_legs1.back().back() != phantom_nodes_vector.back().targetPhantom.forward_node_id) ),
// -- unpacked output
raw_route_data.unpacked_path_segments[i] raw_route_data.unpacked_path_segments[i]
); );
// // TODO: properly unpack first and last segments
// super::UnpackPath(
// packed_legs1[i],
// SPECIAL_EDGEID, ( at_beginning ? start_offset : 0), false,
// SPECIAL_EDGEID, 0, false,
// raw_route_data.unpacked_path_segments[i]
// );
} }
raw_route_data.lengthOfShortestPath = std::min(distance1, distance2); raw_route_data.lengthOfShortestPath = std::min(distance1, distance2);
} }