From c324fbace4876b0570ff587cfd899e7c3aa0ee45 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 10 Jul 2014 13:56:36 +0200 Subject: [PATCH] path searches were pruned too early, fixes #1117 --- RoutingAlgorithms/AlternativePathRouting.h | 44 +++++++++++++++------- RoutingAlgorithms/BasicRoutingInterface.h | 11 +++++- RoutingAlgorithms/ShortestPathRouting.h | 27 ++++++++++--- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/RoutingAlgorithms/AlternativePathRouting.h b/RoutingAlgorithms/AlternativePathRouting.h index 2a67313fa..214a8eb3b 100644 --- a/RoutingAlgorithms/AlternativePathRouting.h +++ b/RoutingAlgorithms/AlternativePathRouting.h @@ -98,6 +98,9 @@ template class AlternativeRouting : private BasicRoutingInte int upper_bound_to_shortest_path_distance = INVALID_EDGE_WEIGHT; NodeID middle_node = SPECIAL_NODEID; + EdgeWeight min_edge_offset = std::min(min_edge_offset, -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) { // SimpleLogger().Write(logDEBUG) << "fwd-a insert: " << @@ -109,8 +112,8 @@ template class AlternativeRouting : private BasicRoutingInte } if (phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID) { - // SimpleLogger().Write(logDEBUG) << "fwd-b insert: " << - // phantom_node_pair.source_phantom.reverse_node_id << ", w: " << + // SimpleLogger().Write(logDEBUG) << "fwd-b insert: " << + // phantom_node_pair.source_phantom.reverse_node_id << ", w: " << // -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); forward_heap1.Insert(phantom_node_pair.source_phantom.reverse_node_id, -phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), @@ -146,7 +149,8 @@ template class AlternativeRouting : private BasicRoutingInte &middle_node, &upper_bound_to_shortest_path_distance, via_node_candidate_list, - forward_search_space); + forward_search_space, + min_edge_offset); } if (0 < reverse_heap1.Size()) { @@ -155,7 +159,8 @@ template class AlternativeRouting : private BasicRoutingInte &middle_node, &upper_bound_to_shortest_path_distance, via_node_candidate_list, - reverse_search_space); + reverse_search_space, + min_edge_offset); } } @@ -271,7 +276,7 @@ template class AlternativeRouting : private BasicRoutingInte { int length_of_via_path = 0, sharing_of_via_path = 0; ComputeLengthAndSharingOfViaPath( - node, &length_of_via_path, &sharing_of_via_path, packed_shortest_path); + node, &length_of_via_path, &sharing_of_via_path, packed_shortest_path, min_edge_offset); const int maximum_allowed_sharing = static_cast( upper_bound_to_shortest_path_distance * VIAPATH_GAMMA); if (sharing_of_via_path <= maximum_allowed_sharing && @@ -295,7 +300,8 @@ template class AlternativeRouting : private BasicRoutingInte upper_bound_to_shortest_path_distance, &length_of_via_path, &s_v_middle, - &v_t_middle)) + &v_t_middle, + min_edge_offset)) { // select first admissable selected_via_node = candidate.node; @@ -379,7 +385,8 @@ template class AlternativeRouting : private BasicRoutingInte inline void ComputeLengthAndSharingOfViaPath(const NodeID via_node, int *real_length_of_via_path, int *sharing_of_via_path, - const std::vector &packed_shortest_path) + const std::vector &packed_shortest_path, + const EdgeWeight min_edge_offset) { engine_working_data.InitializeOrClearSecondThreadLocalStorage( super::facade->GetNumberOfNodes()); @@ -405,6 +412,7 @@ template class AlternativeRouting : private BasicRoutingInte existing_forward_heap, &s_v_middle, &upper_bound_s_v_path_length, + min_edge_offset, false); } // compute path by reusing backward search from node t @@ -417,6 +425,7 @@ template class AlternativeRouting : private BasicRoutingInte existing_reverse_heap, &v_t_middle, &upper_bound_of_v_t_path_length, + min_edge_offset, true); } *real_length_of_via_path = upper_bound_s_v_path_length + upper_bound_of_v_t_path_length; @@ -578,11 +587,15 @@ template class AlternativeRouting : private BasicRoutingInte NodeID *middle_node, int *upper_bound_to_shortest_path_distance, std::vector &search_space_intersection, - std::vector &search_space) const + std::vector &search_space, + const EdgeWeight min_edge_offset) const { const NodeID node = forward_heap.DeleteMin(); const int distance = forward_heap.GetKey(node); - const int scaled_distance = static_cast(distance / (1. + VIAPATH_EPSILON)); + // const NodeID parentnode = forward_heap.GetData(node).parent; + // SimpleLogger().Write() << (is_forward_directed ? "[fwd] " : "[rev] ") << "settled edge (" << parentnode << "," << node << "), dist: " << distance; + + const int scaled_distance = static_cast((distance + min_edge_offset) / (1. + VIAPATH_EPSILON)); if ((INVALID_EDGE_WEIGHT != *upper_bound_to_shortest_path_distance) && (scaled_distance > *upper_bound_to_shortest_path_distance)) { @@ -595,7 +608,6 @@ template class AlternativeRouting : private BasicRoutingInte if (reverse_heap.WasInserted(node)) { search_space_intersection.emplace_back(node); - const int new_distance = reverse_heap.GetKey(node) + distance; if (new_distance < *upper_bound_to_shortest_path_distance) { @@ -603,6 +615,9 @@ template class AlternativeRouting : private BasicRoutingInte { *middle_node = node; *upper_bound_to_shortest_path_distance = new_distance; + // SimpleLogger().Write() << "accepted middle_node " << *middle_node << " at distance " << new_distance; + // } else { + // SimpleLogger().Write() << "discarded middle_node " << *middle_node << " at distance " << new_distance; } } } @@ -647,7 +662,8 @@ template class AlternativeRouting : private BasicRoutingInte const int length_of_shortest_path, int *length_of_via_path, NodeID *s_v_middle, - NodeID *v_t_middle) const + NodeID *v_t_middle, + const EdgeWeight min_edge_offset) const { new_forward_heap.Clear(); new_reverse_heap.Clear(); @@ -664,6 +680,7 @@ template class AlternativeRouting : private BasicRoutingInte existing_forward_heap, s_v_middle, &upper_bound_s_v_path_length, + min_edge_offset, false); } @@ -682,6 +699,7 @@ template class AlternativeRouting : private BasicRoutingInte existing_reverse_heap, v_t_middle, &upper_bound_of_v_t_path_length, + min_edge_offset, true); } @@ -850,11 +868,11 @@ template class AlternativeRouting : private BasicRoutingInte { if (!forward_heap3.Empty()) { - super::RoutingStep(forward_heap3, reverse_heap3, &middle, &upper_bound, true); + super::RoutingStep(forward_heap3, reverse_heap3, &middle, &upper_bound, min_edge_offset, true); } if (!reverse_heap3.Empty()) { - super::RoutingStep(reverse_heap3, forward_heap3, &middle, &upper_bound, false); + super::RoutingStep(reverse_heap3, forward_heap3, &middle, &upper_bound, min_edge_offset, false); } } return (upper_bound <= t_test_path_length); diff --git a/RoutingAlgorithms/BasicRoutingInterface.h b/RoutingAlgorithms/BasicRoutingInterface.h index 16e5653fc..b430b2d29 100644 --- a/RoutingAlgorithms/BasicRoutingInterface.h +++ b/RoutingAlgorithms/BasicRoutingInterface.h @@ -63,10 +63,15 @@ template class BasicRoutingInterface SearchEngineData::QueryHeap &reverse_heap, NodeID *middle_node_id, int *upper_bound, + const int min_edge_offset, const bool forward_direction) const { const NodeID node = forward_heap.DeleteMin(); const int distance = forward_heap.GetKey(node); + + // const NodeID parentnode = forward_heap.GetData(node).parent; + // SimpleLogger().Write() << (forward_direction ? "[fwd] " : "[rev] ") << "settled edge (" << parentnode << "," << node << "), dist: " << distance; + if (reverse_heap.WasInserted(node)) { const int new_distance = reverse_heap.GetKey(node) + distance; @@ -76,12 +81,16 @@ template class BasicRoutingInterface { *middle_node_id = node; *upper_bound = new_distance; + // SimpleLogger().Write() << "accepted middle node " << node << " at distance " << new_distance; + // } else { + // SimpleLogger().Write() << "discared middle node " << node << " at distance " << new_distance; } } } - if (distance > *upper_bound) + if (distance + min_edge_offset > *upper_bound) { + // SimpleLogger().Write() << "min_edge_offset: " << min_edge_offset; forward_heap.DeleteAll(); return; } diff --git a/RoutingAlgorithms/ShortestPathRouting.h b/RoutingAlgorithms/ShortestPathRouting.h index cc5afe5da..3c3d6ef7c 100644 --- a/RoutingAlgorithms/ShortestPathRouting.h +++ b/RoutingAlgorithms/ShortestPathRouting.h @@ -86,6 +86,8 @@ template class ShortestPathRouting : public BasicRoutingInte middle1 = UINT_MAX; middle2 = UINT_MAX; + int min_edge_offset = 0; + // insert new starting nodes into forward heap, adjusted by previous distances. if (search_from_1st_node && phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID) @@ -94,10 +96,15 @@ template class ShortestPathRouting : public BasicRoutingInte phantom_node_pair.source_phantom.forward_node_id, distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.source_phantom.forward_node_id); + min_edge_offset = std::min(min_edge_offset, distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); + // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); forward_heap2.Insert( phantom_node_pair.source_phantom.forward_node_id, distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.source_phantom.forward_node_id); + min_edge_offset = std::min(min_edge_offset, distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); + // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); + } if (search_from_2nd_node && phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID) @@ -106,10 +113,16 @@ template class ShortestPathRouting : public BasicRoutingInte phantom_node_pair.source_phantom.reverse_node_id, distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.source_phantom.reverse_node_id); + min_edge_offset = std::min(min_edge_offset, distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); + // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.reverse_node_id << + // ", w: " << distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); forward_heap2.Insert( phantom_node_pair.source_phantom.reverse_node_id, distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.source_phantom.reverse_node_id); + min_edge_offset = std::min(min_edge_offset, distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); + // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.reverse_node_id << + // ", w: " << distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); } // insert new backward nodes into backward heap, unadjusted. @@ -118,13 +131,17 @@ template class ShortestPathRouting : public BasicRoutingInte reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id, phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(), phantom_node_pair.target_phantom.forward_node_id); - } + // SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.forward_node_id << + // ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(); + } if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID) { reverse_heap2.Insert(phantom_node_pair.target_phantom.reverse_node_id, phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(), phantom_node_pair.target_phantom.reverse_node_id); + // SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.reverse_node_id << + // ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(); } // run two-Target Dijkstra routing step. @@ -133,12 +150,12 @@ template class ShortestPathRouting : public BasicRoutingInte if (0 < forward_heap1.Size()) { super::RoutingStep( - forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, true); + forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true); } if (0 < reverse_heap1.Size()) { super::RoutingStep( - reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, false); + reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, min_edge_offset, false); } } @@ -149,12 +166,12 @@ template class ShortestPathRouting : public BasicRoutingInte if (0 < forward_heap2.Size()) { super::RoutingStep( - forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, true); + forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true); } if (0 < reverse_heap2.Size()) { super::RoutingStep( - reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, false); + reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, min_edge_offset, false); } } }