unpacking start and target edge fixes plus some refactoring
This commit is contained in:
parent
985270bb02
commit
3b29eeb6b6
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user