Break tie for equal weights but different durations

There is no possibility until multiple-weights are implemented
to break tie in the contraction and the direct shortest path plugin
as duration is not computed during contraction.

This must be fixed after multiple-weights implementation
by using `std::tie(weight, duration)` pairs everywhere.
This commit is contained in:
Michael Krasnyk 2017-09-27 15:17:47 +02:00
parent a862e5fb3a
commit f2333eb31a
3 changed files with 79 additions and 19 deletions

View File

@ -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 |

View File

@ -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};
}
}
}

View File

@ -104,7 +104,8 @@ void relaxOutgoingEdges(const DataFacade<ch::Algorithm> &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<mld::Algorithm> &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<mld::Algorithm> &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<mld::Algorithm> &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<Algorithm> &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<EdgeDuration> oneToManySearch(SearchEngineData<Algorithm> &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<EdgeDuration> oneToManySearch(SearchEngineData<Algorithm> &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