use 64bit int types to not lose precision in for loop counting variables

This commit is contained in:
Dennis Luxen 2014-07-21 13:14:05 +02:00
parent fc90162f69
commit 507167d5c1

View File

@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../DataStructures/SearchEngineData.h" #include "../DataStructures/SearchEngineData.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/range/irange.hpp>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
@ -98,8 +99,10 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT; int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT;
NodeID middle_node = SPECIAL_NODEID; NodeID middle_node = SPECIAL_NODEID;
EdgeWeight min_edge_offset = std::min(0, -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); EdgeWeight min_edge_offset =
min_edge_offset = std::min(min_edge_offset, -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); std::min(0, -phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
min_edge_offset = std::min(min_edge_offset,
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
if (phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID) if (phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
{ {
@ -112,8 +115,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
} }
if (phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID) if (phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
{ {
// SimpleLogger().Write(logDEBUG) << "fwd-b insert: " << // SimpleLogger().Write(logDEBUG) << "fwd-b insert: " <<
// phantom_node_pair.source_phantom.reverse_node_id << ", w: " << // phantom_node_pair.source_phantom.reverse_node_id << ", w: " <<
// -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); // -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_node_id, forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_node_id,
-phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
@ -178,7 +181,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
super::RetrievePackedPathFromSingleHeap(reverse_heap1, middle_node, packed_reverse_path); super::RetrievePackedPathFromSingleHeap(reverse_heap1, middle_node, packed_reverse_path);
// this set is is used as an indicator if a node is on the shortest path // this set is is used as an indicator if a node is on the shortest path
std::unordered_set<NodeID> nodes_in_path(packed_forward_path.size() + packed_reverse_path.size()); std::unordered_set<NodeID> nodes_in_path(packed_forward_path.size() +
packed_reverse_path.size());
nodes_in_path.insert(packed_forward_path.begin(), packed_forward_path.end()); nodes_in_path.insert(packed_forward_path.begin(), packed_forward_path.end());
nodes_in_path.insert(middle_node); nodes_in_path.insert(middle_node);
nodes_in_path.insert(packed_reverse_path.begin(), packed_reverse_path.end()); nodes_in_path.insert(packed_reverse_path.begin(), packed_reverse_path.end());
@ -199,9 +203,10 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
} }
else else
{ {
// current edge is not on shortest path. Check if we know a value for the other endpoint // current edge is not on shortest path. Check if we know a value for the other
// endpoint
const auto sharing_of_u_iterator = approximated_forward_sharing.find(u); const auto sharing_of_u_iterator = approximated_forward_sharing.find(u);
if(sharing_of_u_iterator != approximated_forward_sharing.end()) if (sharing_of_u_iterator != approximated_forward_sharing.end())
{ {
approximated_forward_sharing.emplace(v, sharing_of_u_iterator->second); approximated_forward_sharing.emplace(v, sharing_of_u_iterator->second);
} }
@ -220,9 +225,10 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
} }
else else
{ {
// current edge is not on shortest path. Check if we know a value for the other endpoint // current edge is not on shortest path. Check if we know a value for the other
// endpoint
const auto sharing_of_u_iterator = approximated_reverse_sharing.find(u); const auto sharing_of_u_iterator = approximated_reverse_sharing.find(u);
if(sharing_of_u_iterator != approximated_reverse_sharing.end()) if (sharing_of_u_iterator != approximated_reverse_sharing.end())
{ {
approximated_reverse_sharing.emplace(v, sharing_of_u_iterator->second); approximated_reverse_sharing.emplace(v, sharing_of_u_iterator->second);
} }
@ -275,10 +281,13 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
for (const NodeID node : preselected_node_list) for (const NodeID node : preselected_node_list)
{ {
int length_of_via_path = 0, sharing_of_via_path = 0; int length_of_via_path = 0, sharing_of_via_path = 0;
ComputeLengthAndSharingOfViaPath( ComputeLengthAndSharingOfViaPath(node,
node, &length_of_via_path, &sharing_of_via_path, packed_shortest_path, min_edge_offset); &length_of_via_path,
const int maximum_allowed_sharing = static_cast<int>( &sharing_of_via_path,
upper_bound_to_shortest_path_distance * VIAPATH_GAMMA); packed_shortest_path,
min_edge_offset);
const int maximum_allowed_sharing =
static_cast<int>(upper_bound_to_shortest_path_distance * VIAPATH_GAMMA);
if (sharing_of_via_path <= maximum_allowed_sharing && if (sharing_of_via_path <= maximum_allowed_sharing &&
length_of_via_path <= upper_bound_to_shortest_path_distance * (1 + VIAPATH_EPSILON)) length_of_via_path <= upper_bound_to_shortest_path_distance * (1 + VIAPATH_EPSILON))
{ {
@ -341,8 +350,8 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
v_t_middle, v_t_middle,
packed_alternate_path); packed_alternate_path);
raw_route_data.alt_source_traversed_in_reverse.push_back( raw_route_data.alt_source_traversed_in_reverse.push_back((
(packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id)); packed_alternate_path.front() != phantom_node_pair.source_phantom.forward_node_id));
raw_route_data.alt_target_traversed_in_reverse.push_back( raw_route_data.alt_target_traversed_in_reverse.push_back(
(packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id)); (packed_alternate_path.back() != phantom_node_pair.target_phantom.forward_node_id));
@ -351,7 +360,9 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
packed_alternate_path, phantom_node_pair, raw_route_data.unpacked_alternative); packed_alternate_path, phantom_node_pair, raw_route_data.unpacked_alternative);
raw_route_data.alternative_path_length = length_of_via_path; raw_route_data.alternative_path_length = length_of_via_path;
} else { }
else
{
BOOST_ASSERT(raw_route_data.alternative_path_length == INVALID_EDGE_WEIGHT); BOOST_ASSERT(raw_route_data.alternative_path_length == INVALID_EDGE_WEIGHT);
} }
} }
@ -443,48 +454,52 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
// partial unpacking, compute sharing // partial unpacking, compute sharing
// First partially unpack s-->v until paths deviate, note length of common path. // First partially unpack s-->v until paths deviate, note length of common path.
const unsigned s_v_min_path_size = const int64_t s_v_min_path_size =
std::min(packed_s_v_path.size(), packed_shortest_path.size()) - 1; std::min(packed_s_v_path.size(), packed_shortest_path.size()) - 1;
for (unsigned i = 0; i < s_v_min_path_size; ++i) for (const int64_t current_node : boost::irange((int64_t)0, s_v_min_path_size))
{ {
if (packed_s_v_path[i] == packed_shortest_path[i] && if (packed_s_v_path[current_node] == packed_shortest_path[current_node] &&
packed_s_v_path[i + 1] == packed_shortest_path[i + 1]) packed_s_v_path[current_node + 1] == packed_shortest_path[current_node + 1])
{ {
EdgeID edgeID = EdgeID edgeID = facade->FindEdgeInEitherDirection(
facade->FindEdgeInEitherDirection(packed_s_v_path[i], packed_s_v_path[i + 1]); packed_s_v_path[current_node], packed_s_v_path[current_node + 1]);
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; *sharing_of_via_path += facade->GetEdgeData(edgeID).distance;
} }
else else
{ {
if (packed_s_v_path[i] == packed_shortest_path[i]) if (packed_s_v_path[current_node] == packed_shortest_path[current_node])
{ {
super::UnpackEdge( super::UnpackEdge(packed_s_v_path[current_node],
packed_s_v_path[i], packed_s_v_path[i + 1], partially_unpacked_via_path); packed_s_v_path[current_node + 1],
super::UnpackEdge(packed_shortest_path[i], partially_unpacked_via_path);
packed_shortest_path[i + 1], super::UnpackEdge(packed_shortest_path[current_node],
packed_shortest_path[current_node + 1],
partially_unpacked_shortest_path); partially_unpacked_shortest_path);
break; break;
} }
} }
} }
// traverse partially unpacked edge and note common prefix // traverse partially unpacked edge and note common prefix
for (int i = 0, const int64_t packed_path_length =
packed_path_length = std::min(partially_unpacked_via_path.size(), std::min(partially_unpacked_via_path.size(), partially_unpacked_shortest_path.size()) -
partially_unpacked_shortest_path.size()) - 1;
1; for (int64_t current_node = 0;
(i < packed_path_length) && (current_node < packed_path_length) &&
(partially_unpacked_via_path[i] == partially_unpacked_shortest_path[i] && (partially_unpacked_via_path[current_node] ==
partially_unpacked_via_path[i + 1] == partially_unpacked_shortest_path[i + 1]); partially_unpacked_shortest_path[current_node] &&
++i) partially_unpacked_via_path[current_node + 1] ==
partially_unpacked_shortest_path[current_node + 1]);
++current_node)
{ {
EdgeID edgeID = facade->FindEdgeInEitherDirection(partially_unpacked_via_path[i], EdgeID selected_edge =
partially_unpacked_via_path[i + 1]); facade->FindEdgeInEitherDirection(partially_unpacked_via_path[current_node],
*sharing_of_via_path += facade->GetEdgeData(edgeID).distance; partially_unpacked_via_path[current_node + 1]);
*sharing_of_via_path += facade->GetEdgeData(selected_edge).distance;
} }
// Second, partially unpack v-->t in reverse order until paths deviate and note lengths // Second, partially unpack v-->t in reverse order until paths deviate and note lengths
int via_path_index = packed_v_t_path.size() - 1; int64_t via_path_index = packed_v_t_path.size() - 1;
int shortest_path_index = packed_shortest_path.size() - 1; int64_t shortest_path_index = packed_shortest_path.size() - 1;
for (; via_path_index > 0 && shortest_path_index > 0; for (; via_path_index > 0 && shortest_path_index > 0;
--via_path_index, --shortest_path_index) --via_path_index, --shortest_path_index)
{ {
@ -593,9 +608,11 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
const NodeID node = forward_heap.DeleteMin(); const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node); const int distance = forward_heap.GetKey(node);
// const NodeID parentnode = forward_heap.GetData(node).parent; // const NodeID parentnode = forward_heap.GetData(node).parent;
// SimpleLogger().Write() << (is_forward_directed ? "[fwd] " : "[rev] ") << "settled edge (" << parentnode << "," << node << "), dist: " << distance; // SimpleLogger().Write() << (is_forward_directed ? "[fwd] " : "[rev] ") << "settled edge ("
// << parentnode << "," << node << "), dist: " << distance;
const int scaled_distance = static_cast<int>((distance + min_edge_offset) / (1. + VIAPATH_EPSILON)); const int scaled_distance =
static_cast<int>((distance + min_edge_offset) / (1. + VIAPATH_EPSILON));
if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_distance) && if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_distance) &&
(scaled_distance > *upper_bound_to_shortest_path_distance)) (scaled_distance > *upper_bound_to_shortest_path_distance))
{ {
@ -615,9 +632,11 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{ {
*middle_node = node; *middle_node = node;
*upper_bound_to_shortest_path_distance = new_distance; *upper_bound_to_shortest_path_distance = new_distance;
// SimpleLogger().Write() << "accepted middle_node " << *middle_node << " at distance " << new_distance; // SimpleLogger().Write() << "accepted middle_node " << *middle_node << " at
// } else { // distance " << new_distance;
// SimpleLogger().Write() << "discarded middle_node " << *middle_node << " at distance " << new_distance; // } else {
// SimpleLogger().Write() << "discarded middle_node " << *middle_node << "
// at distance " << new_distance;
} }
} }
} }
@ -868,11 +887,13 @@ template <class DataFacadeT> class AlternativeRouting : private BasicRoutingInte
{ {
if (!forward_heap3.Empty()) if (!forward_heap3.Empty())
{ {
super::RoutingStep(forward_heap3, reverse_heap3, &middle, &upper_bound, min_edge_offset, true); super::RoutingStep(
forward_heap3, reverse_heap3, &middle, &upper_bound, min_edge_offset, true);
} }
if (!reverse_heap3.Empty()) if (!reverse_heap3.Empty())
{ {
super::RoutingStep(reverse_heap3, forward_heap3, &middle, &upper_bound, min_edge_offset, false); super::RoutingStep(
reverse_heap3, forward_heap3, &middle, &upper_bound, min_edge_offset, false);
} }
} }
return (upper_bound <= t_test_path_length); return (upper_bound <= t_test_path_length);