diff --git a/features/testbot/distance_matrix.feature b/features/testbot/distance_matrix.feature index 1be45b1df..fad753947 100644 --- a/features/testbot/distance_matrix.feature +++ b/features/testbot/distance_matrix.feature @@ -326,3 +326,52 @@ Feature: Basic Distance Matrix | 6 | 7 | 6 | 10 | 9 | 1 | 0 | 3.9 | 2.9 | | 7 | 3.1 | 2.1 | 6.1 | 5.1 | 9.1 | 8.1 | 0 | 11 | | 8 | 4.1 | 3.1 | 7.1 | 6.1 | 10.1 | 9.1 | 1 | 0 | + + + Scenario: Testbot - Travel time matrix with ties + Given the profile file + """ + local functions = require('testbot') + functions.process_segment = function(profile, segment) + segment.weight = 1 + segment.duration = 1 + end + functions.process_turn = function(profile, turn) + if turn.angle >= 0 then + turn.duration = 16 + else + turn.duration = 4 + end + turn.weight = 0 + end + return functions + """ + And the node map + """ + a b + + c d + """ + + And the ways + | nodes | + | ab | + | ac | + | bd | + | dc | + + + When I route I should get + | from | to | route | distance | time | weight | + | a | c | ac,ac | 200m | 5s | 5 | + + When I request a travel time matrix I should get + | | a | b | c | d | + | a | 0 | 1 | 5 | 10 | + + When I request a travel time matrix I should get + | | a | + | a | 0 | + | b | 1 | + | c | 15 | + | d | 10 | diff --git a/include/customizer/cell_customizer.hpp b/include/customizer/cell_customizer.hpp index 0b9a7c020..57c020c21 100644 --- a/include/customizer/cell_customizer.hpp +++ b/include/customizer/cell_customizer.hpp @@ -159,14 +159,16 @@ class CellCustomizer } const EdgeWeight to_weight = weight + subcell_weight; + const EdgeDuration to_duration = duration + *subcell_duration; if (!heap.WasInserted(to)) { - heap.Insert(to, to_weight, {true, duration + *subcell_duration}); + heap.Insert(to, to_weight, {true, to_duration}); } - else if (to_weight < heap.GetKey(to)) + else if (std::tie(to_weight, to_duration) < + std::tie(heap.GetKey(to), heap.GetData(to).duration)) { heap.DecreaseKey(to, to_weight); - heap.GetData(to) = {true, duration + *subcell_duration}; + heap.GetData(to) = {true, to_duration}; } } @@ -191,14 +193,16 @@ class CellCustomizer partition.GetCell(level - 1, node) != partition.GetCell(level - 1, to))) { const EdgeWeight to_weight = weight + data.weight; + const EdgeDuration to_duration = duration + data.duration; if (!heap.WasInserted(to)) { heap.Insert(to, to_weight, {false, duration + data.duration}); } - else if (to_weight < heap.GetKey(to)) + else if (std::tie(to_weight, to_duration) < + std::tie(heap.GetKey(to), heap.GetData(to).duration)) { heap.DecreaseKey(to, to_weight); - heap.GetData(to) = {false, duration + data.duration}; + heap.GetData(to) = {false, to_duration}; } } } diff --git a/src/engine/routing_algorithms/many_to_many.cpp b/src/engine/routing_algorithms/many_to_many.cpp index adc162fe4..82a228151 100644 --- a/src/engine/routing_algorithms/many_to_many.cpp +++ b/src/engine/routing_algorithms/many_to_many.cpp @@ -104,7 +104,8 @@ void relaxOutgoingEdges(const DataFacade &facade, query_heap.Insert(to, to_weight, {node, to_duration}); } // Found a shorter Path -> Update weight - else if (to_weight < query_heap.GetKey(to)) + else if (std::tie(to_weight, to_duration) < + std::tie(query_heap.GetKey(to), query_heap.GetData(to).duration)) { // new parent query_heap.GetData(to) = {node, to_duration}; @@ -203,7 +204,8 @@ void relaxOutgoingEdges(const DataFacade &facade, { query_heap.Insert(to, to_weight, {node, true, to_duration}); } - else if (to_weight < query_heap.GetKey(to)) + else if (std::tie(to_weight, to_duration) < + std::tie(query_heap.GetKey(to), query_heap.GetData(to).duration)) { query_heap.GetData(to) = {node, true, to_duration}; query_heap.DecreaseKey(to, to_weight); @@ -232,7 +234,8 @@ void relaxOutgoingEdges(const DataFacade &facade, { query_heap.Insert(to, to_weight, {node, true, to_duration}); } - else if (to_weight < query_heap.GetKey(to)) + else if (std::tie(to_weight, to_duration) < + std::tie(query_heap.GetKey(to), query_heap.GetData(to).duration)) { query_heap.GetData(to) = {node, true, to_duration}; query_heap.DecreaseKey(to, to_weight); @@ -269,7 +272,8 @@ void relaxOutgoingEdges(const DataFacade &facade, query_heap.Insert(to, to_weight, {node, false, to_duration}); } // Found a shorter Path -> Update weight - else if (to_weight < query_heap.GetKey(to)) + else if (std::tie(to_weight, to_duration) < + std::tie(query_heap.GetKey(to), query_heap.GetData(to).duration)) { // new parent query_heap.GetData(to) = {node, false, to_duration}; @@ -320,7 +324,7 @@ void forwardRoutingStep(const DataFacade &facade, current_duration = std::min(current_duration, new_duration); } } - else if (new_weight < current_weight) + else if (std::tie(new_weight, new_duration) < std::tie(current_weight, current_duration)) { current_weight = new_weight; current_duration = new_duration; @@ -514,7 +518,7 @@ std::vector oneToManySearch(SearchEngineData &engine_wo } } - // Handler if node is in the destinations list and update weights/durations + // Check if node is in the destinations list and update weights/durations auto update_values = [&](NodeID node, EdgeWeight weight, EdgeDuration duration) { auto candidates = target_nodes_index.equal_range(node); for (auto it = candidates.first; it != candidates.second;) @@ -525,15 +529,18 @@ std::vector oneToManySearch(SearchEngineData &engine_wo std::tie(index, target_weight, target_duration) = it->second; const auto path_weight = weight + target_weight; - if (path_weight >= 0 && - path_weight < weights[index]) // TODO: check if path_weight < weights[index] needed - { - weights[index] = path_weight; - durations[index] = duration + target_duration; - } - if (path_weight >= 0) - { // Remove node from destinations list + { + const auto path_duration = duration + target_duration; + + if (std::tie(path_weight, path_duration) < + std::tie(weights[index], durations[index])) + { + weights[index] = path_weight; + durations[index] = path_duration; + } + + // Remove node from destinations list it = target_nodes_index.erase(it); } else