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_
#define ALTERNATIVEROUTES_H_
#ifndef ALTERNATIVE_PATH_ROUTING_H
#define ALTERNATIVE_PATH_ROUTING_H
#include "BasicRoutingInterface.h"
#include "../DataStructures/SearchEngineData.h"
#include "../Util/TimingUtil.h"
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include <cmath>
#include <vector>
const double VIAPATH_ALPHA = 0.15;
@ -74,7 +76,7 @@ public:
engine_working_data(engine_working_data)
{ }
~AlternativeRouting() {}
virtual ~AlternativeRouting() {}
void operator() (
const PhantomNodes & phantom_node_pair,
@ -83,8 +85,8 @@ public:
if( //phantom_node_pair.AtLeastOnePhantomNodeIsUINTMAX() ||
phantom_node_pair.PhantomNodesHaveEqualLocation()
) {
raw_route_data.lengthOfShortestPath = INT_MAX;
raw_route_data.lengthOfAlternativePath = INT_MAX;
// raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
// raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
SimpleLogger().Write(logDEBUG) << "not executing path search";
return;
}
@ -94,6 +96,7 @@ public:
std::vector<SearchSpaceEdge> forward_search_space;
std::vector<SearchSpaceEdge> reverse_search_space;
//Init queues, semi-expensive because access to TSS invokes a sys-call
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes()
@ -153,6 +156,8 @@ public:
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
while(0 < (forward_heap1.Size() + reverse_heap1.Size())){
if(0 < forward_heap1.Size()){
@ -179,6 +184,7 @@ public:
}
}
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_reverse_path;
@ -202,7 +208,10 @@ public:
BOOST_FOREACH(const SearchSpaceEdge & current_edge, forward_search_space) {
const NodeID u = current_edge.first;
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);
++index_into_forward_path;
approximated_forward_sharing[v] = forward_heap1.GetKey(u);
@ -217,65 +226,87 @@ public:
BOOST_FOREACH(const SearchSpaceEdge & current_edge, reverse_search_space) {
const NodeID u = current_edge.first;
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);
++index_into_reverse_path;
approximated_reverse_sharing[v] = reverse_heap1.GetKey(u);
} else {
//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;
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::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;
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;
int approximated_sharing = fwd_sharing + rev_sharing;
int approximated_length = forward_heap1.GetKey(node)+reverse_heap1.GetKey(node);
bool lengthPassed = (approximated_length < upper_bound_to_shortest_path_distance*(1+VIAPATH_EPSILON));
bool sharingPassed = (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 int approximated_sharing = fwd_sharing + rev_sharing;
const int approximated_length = forward_heap1.GetKey(node) + reverse_heap1.GetKey(node);
const bool length_passes = (approximated_length < upper_bound_to_shortest_path_distance*(1+VIAPATH_EPSILON));
const bool sharing_passes = (approximated_sharing <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA);
const bool stretch_passes = (approximated_length - approximated_sharing) < ((1.+VIAPATH_EPSILON)*(upper_bound_to_shortest_path_distance-approximated_sharing));
if(lengthPassed && sharingPassed && stretchPassed) {
nodes_that_passed_preselection.push_back(node);
if( length_passes && sharing_passes && stretch_passes ) {
preselected_node_list.push_back(node);
}
}
SimpleLogger().Write() << preselected_node_list.size() << " passed preselection";
std::vector<NodeID> & packed_shortest_path = packed_forward_path;
std::reverse(packed_shortest_path.begin(), packed_shortest_path.end());
packed_shortest_path.push_back(middle_node);
packed_shortest_path.insert(packed_shortest_path.end(),packed_reverse_path.begin(), packed_reverse_path.end());
std::vector<RankedCandidateNode > rankedCandidates;
packed_shortest_path.insert(
packed_shortest_path.end(),
packed_reverse_path.begin(),
packed_reverse_path.end()
);
std::vector<RankedCandidateNode> ranked_candidates_list;
//prioritizing via nodes for deep inspection
BOOST_FOREACH(const NodeID node, nodes_that_passed_preselection) {
int lengthOfViaPath = 0, sharingOfViaPath = 0;
computeLengthAndSharingOfViaPath(node, &lengthOfViaPath, &sharingOfViaPath, forward_offset+reverse_offset, packed_shortest_path);
if(sharingOfViaPath <= upper_bound_to_shortest_path_distance*VIAPATH_GAMMA) {
rankedCandidates.push_back(RankedCandidateNode(node, lengthOfViaPath, sharingOfViaPath));
BOOST_FOREACH(const NodeID node, preselected_node_list) {
int length_of_via_path = 0, sharing_of_via_path = 0;
ComputeLengthAndSharingOfViaPath(node, &length_of_via_path, &sharing_of_via_path, forward_offset+reverse_offset, packed_shortest_path);
const int maximum_allowed_sharing = upper_bound_to_shortest_path_distance*VIAPATH_GAMMA;
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;
int lengthOfViaPath = INT_MAX;
NodeID s_v_middle = UINT_MAX, v_t_middle = UINT_MAX;
BOOST_FOREACH(const RankedCandidateNode & candidate, rankedCandidates){
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)) {
NodeID selected_via_node = SPECIAL_NODEID;
int length_of_via_path = INVALID_EDGE_WEIGHT;
NodeID s_v_middle = SPECIAL_NODEID, v_t_middle = SPECIAL_NODEID;
BOOST_FOREACH(const RankedCandidateNode & candidate, ranked_candidates_list){
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
selectedViaNode = candidate.node;
selected_via_node = candidate.node;
break;
}
}
//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() );
raw_route_data.unpacked_path_segments.resize(1);
// 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.lengthOfShortestPath = upper_bound_to_shortest_path_distance;
} else {
//TODO: kill this branch by initialization
raw_route_data.lengthOfShortestPath = INT_MAX;
SimpleLogger().Write(logDEBUG) << "upper_bound_to_shortest_path_distance: " << upper_bound_to_shortest_path_distance;
}
if(selectedViaNode != UINT_MAX) {
RetrieveAndUnpackAlternatePath(
if(SPECIAL_NODEID != selected_via_node ) {
std::vector<NodeID> packed_alternate_path;
// retrieve alternate path
RetrievePackedAlternatePath(
forward_heap1,
reverse_heap1,
forward_heap2,
reverse_heap2,
s_v_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.lengthOfAlternativePath = lengthOfViaPath;
} else {
//TODO: kill this branch by initialization
raw_route_data.lengthOfAlternativePath = INT_MAX;
raw_route_data.lengthOfAlternativePath = length_of_via_path;
SimpleLogger().Write(logDEBUG) << "length_of_via_path: " << length_of_via_path;
}
}
private:
//unpack <s,..,v,..,t> by exploring search spaces from v
inline void RetrieveAndUnpackAlternatePath(
//unpack alternate <s,..,v,..,t> by exploring search spaces from v
inline void RetrievePackedAlternatePath(
const QueryHeap & forward_heap1,
const QueryHeap & reverse_heap1,
const QueryHeap & forward_heap2,
const QueryHeap & reverse_heap2,
const NodeID s_v_middle,
const NodeID v_t_middle,
std::vector<PathData> & unpacked_path
std::vector<NodeID> & packed_path
) const {
//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(
forward_heap1,
reverse_heap2,
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]
super::RetrievePackedPathFromHeap(
@ -357,22 +399,14 @@ private:
packed_v_t_path
);
packed_s_v_path.insert(
packed_s_v_path.end(),
packed_path.insert(
packed_path.end(),
packed_v_t_path.begin(),
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) {
//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
@ -380,80 +414,114 @@ private:
super::facade->GetNumberOfNodes()
);
QueryHeap & existingForwardHeap = *engine_working_data.forwardHeap;
QueryHeap & existingBackwardHeap = *engine_working_data.backwardHeap;
QueryHeap & newForwardHeap = *engine_working_data.forwardHeap2;
QueryHeap & newBackwardHeap = *engine_working_data.backwardHeap2;
QueryHeap & existing_forward_heap = *engine_working_data.forwardHeap;
QueryHeap & existing_reverse_heap = *engine_working_data.backwardHeap;
QueryHeap & new_forward_heap = *engine_working_data.forwardHeap2;
QueryHeap & new_reverse_heap = *engine_working_data.backwardHeap2;
std::vector < NodeID > packed_s_v_path;
std::vector < NodeID > packed_v_t_path;
std::vector<NodeID> packed_s_v_path;
std::vector<NodeID> packed_v_t_path;
std::vector<NodeID> partiallyUnpacked_shortest_path;
std::vector<NodeID> partiallyUnpackedViaPath;
std::vector<NodeID> partially_unpacked_shortest_path;
std::vector<NodeID> partially_unpacked_via_path;
NodeID s_v_middle = UINT_MAX;
int upperBoundFor_s_vPath = INT_MAX;//compute path <s,..,v> by reusing forward search from s
newBackwardHeap.Insert(via_node, 0, via_node);
while (0 < newBackwardHeap.Size()) {
super::RoutingStep(newBackwardHeap, existingForwardHeap, &s_v_middle, &upperBoundFor_s_vPath, 2 * offset, false);
NodeID s_v_middle = SPECIAL_NODEID;
int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT;
new_reverse_heap.Insert(via_node, 0, via_node);
//compute path <s,..,v> by reusing forward search from s
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
NodeID v_t_middle = UINT_MAX;
int upperBoundFor_v_tPath = INT_MAX;
newForwardHeap.Insert(via_node, 0, via_node);
while (0 < newForwardHeap.Size() ) {
super::RoutingStep(newForwardHeap, existingBackwardHeap, &v_t_middle, &upperBoundFor_v_tPath, 2 * offset, true);
NodeID v_t_middle = SPECIAL_NODEID;
int upper_bound_of_v_t_path_length = INVALID_EDGE_WEIGHT;
new_forward_heap.Insert(via_node, 0, via_node);
while(!new_forward_heap.Empty() ) {
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;
}
//retrieve packed paths
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, s_v_middle, packed_s_v_path);
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, v_t_middle, packed_v_t_path);
super::RetrievePackedPathFromHeap(
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
//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) {
if (packed_s_v_path[i] == packed_shortest_path[i] && packed_s_v_path[i + 1] == packed_shortest_path[i + 1]) {
const unsigned s_v_min_path_size = std::min( packed_s_v_path.size(), packed_shortest_path.size()) - 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]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else {
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_shortest_path[i], packed_shortest_path[i+1], partiallyUnpacked_shortest_path);
if( packed_s_v_path[i] == packed_shortest_path[i] ) {
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], partially_unpacked_shortest_path);
break;
}
}
}
//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) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(partiallyUnpackedViaPath[i], partiallyUnpackedViaPath[i+1]);
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(partially_unpacked_via_path[i], partially_unpacked_via_path[i+1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
}
//Second, partially unpack v-->t in reverse order until paths deviate and note lengths
int viaPathIndex = packed_v_t_path.size() - 1;
int shortestPathIndex = packed_shortest_path.size() - 1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex ) {
if (packed_v_t_path[viaPathIndex - 1] == packed_shortest_path[shortestPathIndex - 1] && packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_v_t_path[viaPathIndex - 1], packed_v_t_path[viaPathIndex]);
int via_path_index = packed_v_t_path.size() - 1;
int shortest_path_index = packed_shortest_path.size() - 1;
for (;
via_path_index > 0 && shortest_path_index > 0;
--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;
} else {
if (packed_v_t_path[viaPathIndex] == packed_shortest_path[shortestPathIndex]) {
super::UnpackEdge(packed_v_t_path[viaPathIndex-1], packed_v_t_path[viaPathIndex], partiallyUnpackedViaPath);
super::UnpackEdge(packed_shortest_path[shortestPathIndex-1] , packed_shortest_path[shortestPathIndex], partiallyUnpacked_shortest_path);
if (packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index]) {
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[shortest_path_index-1] , packed_shortest_path[shortest_path_index], partially_unpacked_shortest_path);
break;
}
}
}
viaPathIndex = partiallyUnpackedViaPath.size() - 1;
shortestPathIndex = partiallyUnpacked_shortest_path.size() - 1;
for (; viaPathIndex > 0 && shortestPathIndex > 0; --viaPathIndex,--shortestPathIndex) {
if (partiallyUnpackedViaPath[viaPathIndex - 1] == partiallyUnpacked_shortest_path[shortestPathIndex - 1] && partiallyUnpackedViaPath[viaPathIndex] == partiallyUnpacked_shortest_path[shortestPathIndex]) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( partiallyUnpackedViaPath[viaPathIndex - 1], partiallyUnpackedViaPath[viaPathIndex]);
via_path_index = partially_unpacked_via_path.size()-1;
shortest_path_index = partially_unpacked_shortest_path.size()-1;
for (; via_path_index > 0 && shortest_path_index > 0; --via_path_index,--shortest_path_index) {
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( partially_unpacked_via_path[via_path_index-1], partially_unpacked_via_path[via_path_index]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} else {
break;
@ -462,241 +530,322 @@ private:
//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) {
std::vector<NodeID> packedAlternativePath;
super::RetrievePackedPathFromHeap(_forwardHeap, _backwardHeap, middleNodeIDOfAlternativePath, packedAlternativePath);
// inline int approximateAmountOfSharing(
// const NodeID alternate_path_middle_node_id,
// 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)
return 0;
// if(packed_shortest_path.size() < 2 || packed_alternate_path.size() < 2) {
// return 0;
// }
int sharing = 0;
int aindex = 0;
//compute forward sharing
while( (packedAlternativePath[aindex] == packed_shortest_path[aindex]) && (packedAlternativePath[aindex+1] == packed_shortest_path[aindex+1]) ) {
// SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")";
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]);
sharing += facade->GetEdgeData(edgeID).distance;
++aindex;
}
// int sharing = 0;
// int aindex = 0;
// //compute forward sharing
// while( (packed_alternate_path[aindex] == packed_shortest_path[aindex]) && (packed_alternate_path[aindex+1] == packed_shortest_path[aindex+1]) ) {
// // SimpleLogger().Write() << "retrieving edge (" << packed_alternate_path[aindex] << "," << packed_alternate_path[aindex+1] << ")";
// EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_alternate_path[aindex], packed_alternate_path[aindex+1]);
// sharing += facade->GetEdgeData(edgeID).distance;
// ++aindex;
// }
aindex = packedAlternativePath.size()-1;
int bindex = packed_shortest_path.size()-1;
//compute backward sharing
while( aindex > 0 && bindex > 0 && (packedAlternativePath[aindex] == packed_shortest_path[bindex]) && (packedAlternativePath[aindex-1] == packed_shortest_path[bindex-1]) ) {
EdgeID edgeID = facade->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex-1]);
sharing += facade->GetEdgeData(edgeID).distance;
--aindex; --bindex;
}
return sharing;
}
// aindex = packed_alternate_path.size()-1;
// int bindex = packed_shortest_path.size()-1;
// //compute backward sharing
// 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(packed_alternate_path[aindex], packed_alternate_path[aindex-1]);
// sharing += facade->GetEdgeData(edgeID).distance;
// --aindex; --bindex;
// }
// return sharing;
// }
template<bool forwardDirection>
template<bool is_forward_directed>
inline void AlternativeRoutingStep(
QueryHeap & _forward_heap,
QueryHeap & _reverse_heap,
NodeID *middle_node,
int *upper_bound_to_shortest_path_distance,
std::vector<NodeID>& searchSpaceIntersection,
QueryHeap & forward_heap,
QueryHeap & reverse_heap,
NodeID * middle_node,
int * upper_bound_to_shortest_path_distance,
std::vector<NodeID> & search_space_intersection,
std::vector<SearchSpaceEdge> & search_space,
const int edgeBasedOffset
) const {
const NodeID node = _forward_heap.DeleteMin();
const int distance = _forward_heap.GetKey(node);
int scaledDistance = (distance-edgeBasedOffset)/(1.+VIAPATH_EPSILON);
if(scaledDistance > *upper_bound_to_shortest_path_distance){
_forward_heap.DeleteAll();
const int edge_expansion_offset
) const {
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
const int scaled_distance = (distance-edge_expansion_offset)/(1.+VIAPATH_EPSILON);
if( scaled_distance > *upper_bound_to_shortest_path_distance ){
forward_heap.DeleteAll();
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) ){
searchSpaceIntersection.push_back(node);
if( reverse_heap.WasInserted(node) ) {
search_space_intersection.push_back(node);
const int newDistance = _reverse_heap.GetKey(node) + distance;
if(newDistance < *upper_bound_to_shortest_path_distance ){
if(newDistance>=0 ) {
const int new_distance = reverse_heap.GetKey(node) + distance;
if( new_distance < *upper_bound_to_shortest_path_distance ){
if( new_distance >= 0 ) {
*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);
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward );
if(forwardDirectionFlag) {
const bool edge_is_forward_directed = (is_forward_directed ? data.forward : data.backward );
if( edge_is_forward_directed ) {
const NodeID to = facade->GetTarget(edge);
const int edgeWeight = data.distance;
const int edge_weight = data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
BOOST_ASSERT( edge_weight > 0 );
const int to_distance = distance + edge_weight;
//New Node discovered -> Add to Heap + Node Info Storage
if ( !_forward_heap.WasInserted( to ) ) {
_forward_heap.Insert( to, toDistance, node );
if ( !forward_heap.WasInserted( to ) ) {
forward_heap.Insert( to, to_distance, node );
}
//Found a shorter Path -> Update distance
else if ( toDistance < _forward_heap.GetKey( to ) ) {
_forward_heap.GetData( to ).parent = node;
_forward_heap.DecreaseKey( to, toDistance );
//new parent
else if ( to_distance < forward_heap.GetKey( to ) ) {
// new parent
forward_heap.GetData( to ).parent = node;
// decreased distance
forward_heap.DecreaseKey( to, to_distance );
}
}
}
}
//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) {
newForwardHeap.Clear();
newBackwardHeap.Clear();
std::vector < NodeID > packed_s_v_path;
std::vector < NodeID > packed_v_t_path;
inline bool ViaNodeCandidatePassesTTest(
QueryHeap& existing_forward_heap,
QueryHeap& existing_reverse_heap,
QueryHeap& new_forward_heap,
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;
int upperBoundFor_s_vPath = INT_MAX;
*s_v_middle = SPECIAL_NODEID;
int upper_bound_s_v_path_length = INVALID_EDGE_WEIGHT;
//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_vPath, 2*offset, false);
new_reverse_heap.Insert(candidate.node, 0, candidate.node);
while (new_reverse_heap.Size() > 0) {
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;
}
//compute path <v,..,t> by reusing backward search from t
*v_t_middle = UINT_MAX;
int upperBoundFor_v_tPath = INT_MAX;
newForwardHeap.Insert(candidate.node, 0, candidate.node);
while (newForwardHeap.Size() > 0) {
super::RoutingStep(newForwardHeap, existingBackwardHeap, v_t_middle, &upperBoundFor_v_tPath, 2*offset, true);
*v_t_middle = SPECIAL_NODEID;
int upper_bound_of_v_t_path_length = INVALID_EDGE_WEIGHT;
new_forward_heap.Insert(candidate.node, 0, candidate.node);
while (new_forward_heap.Size() > 0) {
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;
}
*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
super::RetrievePackedPathFromHeap(existingForwardHeap, newBackwardHeap, *s_v_middle, packed_s_v_path);
super::RetrievePackedPathFromHeap(newForwardHeap, existingBackwardHeap, *v_t_middle, packed_v_t_path);
super::RetrievePackedPathFromHeap(
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;
if(UINT_MAX == s_P) {
if( SPECIAL_NODEID == s_P ) {
return false;
}
if(UINT_MAX == t_P) {
if( SPECIAL_NODEID == t_P ) {
return false;
}
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
for (unsigned i = packed_s_v_path.size() - 1; (i > 0) && unpackStack.empty(); --i) {
EdgeID edgeID = facade->FindEdgeInEitherDirection( packed_s_v_path[i - 1], packed_s_v_path[i]);
int lengthOfCurrentEdge = facade->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) {
unpackStack.push(std::make_pair(packed_s_v_path[i - 1], packed_s_v_path[i]));
for(
unsigned i = packed_s_v_path.size() - 1;
(i > 0) && unpack_stack.empty();
--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 {
unpackedUntilDistance += lengthOfCurrentEdge;
unpacked_until_distance += length_of_current_edge;
s_P = packed_s_v_path[i - 1];
}
}
while (!unpackStack.empty()) {
const SearchSpaceEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
EdgeID edgeIDInViaPath = facade->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
if(UINT_MAX == edgeIDInViaPath)
while( !unpack_stack.empty() ) {
const SearchSpaceEdge via_path_edge = unpack_stack.top();
unpack_stack.pop();
EdgeID edge_in_via_path_id = facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
if( SPECIAL_EDGEID == edge_in_via_path_id ) {
return false;
EdgeData currentEdgeData = facade->GetEdgeData(edgeIDInViaPath);
bool IsViaEdgeShortCut = currentEdgeData.shortcut;
if (IsViaEdgeShortCut) {
const NodeID middleOfViaPath = currentEdgeData.id;
EdgeID edgeIDOfSecondSegment = facade->FindEdgeInEitherDirection(middleOfViaPath, viaPathEdge.second);
int lengthOfSecondSegment = facade->GetEdgeData(edgeIDOfSecondSegment).distance;
}
const EdgeData & current_edge_data = facade->GetEdgeData(edge_in_via_path_id);
const bool current_edge_is_shortcut = current_edge_data.shortcut;
if( current_edge_is_shortcut ) {
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!
//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));
if (unpacked_until_distance + second_segment_length >= T_threshold) {
unpack_stack.push(
std::make_pair(
via_path_middle_node_id,
via_path_edge.second
)
);
} else {
unpackedUntilDistance += lengthOfSecondSegment;
unpackStack.push(std::make_pair(viaPathEdge.first, middleOfViaPath));
unpacked_until_distance += second_segment_length;
unpack_stack.push(
std::make_pair(
via_path_edge.first,
via_path_middle_node_id
)
);
}
} else {
// edge is not a shortcut, set the start node for T-Test to end of edge.
unpackedUntilDistance += currentEdgeData.distance;
s_P = viaPathEdge.first;
unpacked_until_distance += current_edge_data.distance;
s_P = via_path_edge.first;
}
}
int lengthOfPathT_TestPath = unpackedUntilDistance;
unpackedUntilDistance = 0;
int t_test_path_length = unpacked_until_distance;
unpacked_until_distance = 0;
//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]);
int lengthOfCurrentEdge = facade->GetEdgeData(edgeID).distance;
if (lengthOfCurrentEdge + unpackedUntilDistance >= T_threshold) {
unpackStack.push( std::make_pair(packed_v_t_path[i], packed_v_t_path[i + 1]));
int length_of_current_edge = facade->GetEdgeData(edgeID).distance;
if (length_of_current_edge + unpacked_until_distance >= T_threshold) {
unpack_stack.push( std::make_pair(packed_v_t_path[i], packed_v_t_path[i + 1]));
} else {
unpackedUntilDistance += lengthOfCurrentEdge;
unpacked_until_distance += length_of_current_edge;
t_P = packed_v_t_path[i + 1];
}
}
while (!unpackStack.empty()) {
const SearchSpaceEdge viaPathEdge = unpackStack.top();
unpackStack.pop();
EdgeID edgeIDInViaPath = facade->FindEdgeInEitherDirection(viaPathEdge.first, viaPathEdge.second);
if(UINT_MAX == edgeIDInViaPath)
while (!unpack_stack.empty()) {
const SearchSpaceEdge via_path_edge = unpack_stack.top();
unpack_stack.pop();
EdgeID edge_in_via_path_id = facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
if(SPECIAL_EDGEID == edge_in_via_path_id) {
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) {
const NodeID middleOfViaPath = currentEdgeData.id;
EdgeID edgeIDOfFirstSegment = facade->FindEdgeInEitherDirection(viaPathEdge.first, middleOfViaPath);
const NodeID middleOfViaPath = current_edge_data.id;
EdgeID edgeIDOfFirstSegment = facade->FindEdgeInEitherDirection(via_path_edge.first, middleOfViaPath);
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.
if (unpackedUntilDistance + lengthOfFirstSegment >= T_threshold) {
unpackStack.push( std::make_pair(viaPathEdge.first, middleOfViaPath));
if (unpacked_until_distance + lengthOfFirstSegment >= T_threshold) {
unpack_stack.push( std::make_pair(via_path_edge.first, middleOfViaPath));
} else {
unpackedUntilDistance += lengthOfFirstSegment;
unpackStack.push( std::make_pair(middleOfViaPath, viaPathEdge.second));
unpacked_until_distance += lengthOfFirstSegment;
unpack_stack.push( std::make_pair(middleOfViaPath, via_path_edge.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;
unpacked_until_distance += current_edge_data.distance;
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.
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes()
);
QueryHeap& forward_heap3 = *engine_working_data.forwardHeap3;
QueryHeap& backward_heap3 = *engine_working_data.backwardHeap3;
int _upperBound = INT_MAX;
NodeID middle = UINT_MAX;
QueryHeap & forward_heap3 = *engine_working_data.forwardHeap3;
QueryHeap & reverse_heap3 = *engine_working_data.backwardHeap3;
int upper_bound = INVALID_EDGE_WEIGHT;
NodeID middle = SPECIAL_NODEID;
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
while (forward_heap3.Size() + backward_heap3.Size() > 0) {
if (forward_heap3.Size() > 0) {
super::RoutingStep(forward_heap3, backward_heap3, &middle, &_upperBound, offset, true);
while( (forward_heap3.Size() + reverse_heap3.Size() ) > 0) {
if( !forward_heap3.Empty() ) {
super::RoutingStep(
forward_heap3,
reverse_heap3,
&middle,
&upper_bound,
offset,
true
);
}
if (backward_heap3.Size() > 0) {
super::RoutingStep(backward_heap3, forward_heap3, &middle, &_upperBound, offset, false);
if( !reverse_heap3.Empty() ) {
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);
if( ed.shortcut ) {//unpack
@ -368,7 +368,7 @@ public:
current_node_id = forward_heap.GetData(current_node_id).parent;
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());
packed_path.push_back(middle_node_id);
current_node_id = middle_node_id;
@ -376,11 +376,6 @@ public:
current_node_id = reverse_heap.GetData(current_node_id).parent;
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

View File

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