-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implements Reasonable Alternative Routes for MLD #4047
Conversation
Tasks (not in order; also I will split off into sub-tasks as I see fit):
|
f399636
to
006d2d1
Compare
We have the full set of all possible alternatives available now. From the search space overlap, candidate generation based on boundary nodes and base graph nodes at the bottom, path reconstruction, path unpacking in the backend all through the pipeline to the response. Screenshot from local frontend:
The next task will be filtering via-candidates as soon as possible (for performance reasons) based on
For the stretch-test @MoKob just brought up a good point I haven't thought about. For restricted areas (think: Here is where we apply the penalty weight and here is where it is defined. In the case of restricted areas on the paths the stretch-test based on raw weights suddenly makes no sense anymore. For example a route that is longer in terms of weight can be of almost the same duration but passing a restricted area instead. In the case when start and / or target are inside a restricted area both our primary route as well as all alternatives have at least the start and / or target penalty weight on them. We probably also want to filter via candidates which are inside a restricted area to begin with. If we could access the high turn penalty from the C++ side we could simply subtract it from the route's weights. But we can't since the restricted penalty is only set in the Lua profile and is not bound in our scripting environment. Binding it would be a breaking profile API change. Not binding it means I can't do reasonable stretch-tests on weights - at least not for the case when restricted areas are involved. |
006d2d1
to
f519916
Compare
f519916
to
0c5a40f
Compare
For those following along - the "stretch test" means "how much longer is the alternative than the shortest/fastest/least-weight path". A stretch factor of 1.2 means a path is 20% longer than the shortest ("longer" is in terms of the metric being used for shortest-path routing, in our case, @daniel-j-h Given that we're applying these weights in order to avoid these restricted ways, how does this cause problems when using weight to calculate stretch? If an alternative enters a restricted way, it will have a high weight, and the stretch will be large, possibly causing it to be pruned. Is this not desirable behaviour? If we're using weights to avoid private roads, why would we want alternatives that use private roads? It seems to me that we want all our other metrics (avoid private roads, etc) to hold for alternatives as well, and using weight to calculate stretch would generally achieve this. Am I missing something? |
@danpat when travelling a-b, there are two valid locations for private roads (begin/end, if you are starting/ending on it). In our case, we can get intermediate vertices on private roads, if we aren't careful. Right now we add 50 mins per entry/exit. Now if you have a long path that has a privat path as a shortcut, you could end up taking that part (since you only find a candidate in that area and can't see whether it is private or not). If the road around the (e.g.) private bridge is long enough, suddenly we allow paying that penalty in the middle. Its all about avoiding private areas, not allowing them. But stretch alone is not guaranteed to work out. It will in most cases, since military bases or other private roads should hopefully not be the easiest path of reaching an area, but in any remote areas it could well be the case. It can, of course, already happen with the shortest path itself. By allowing stretch, we reduce the effective penalty of the already rather small penalty when it comes to remote areas. |
For the record this is already a problem in the current impl. (see here) and not specific to this changeset. |
0c5a40f
to
e1d43a9
Compare
@danpat here's an example from Berlin where I filter candidate routes by at most |
fd50e7b
to
0334fac
Compare
I see, so because the penalty is so large in comparison to the total route weight, and because it's mandatory to take the penalty turn to access the endpoint, doing a simple stretch comparison of all alternatives makes them appear to be quite similar (the weight penalty dominates the total route weight). |
0334fac
to
db23f55
Compare
I just implemented a rough sharing-heuristic (how many ways does the alternative share with the primary route) making use of the cell structure we have at our hands from the partitioner. In contrast to the techniques described in comments above this heuristic already needs the packed paths from the heaps. I then compute the similarity based on the cell ids for the nodes on the packed path. At the moment I'm still comparing There are a few open questions I don't have answers to yet:
|
cd65d3f
to
09674c3
Compare
Comparing sharing between all combination of routes is implemented by now. The simple approach of taking the pre-filtered via candidates ranking them by weight and then filtering based on the cell structure for the packed paths on the first level already gives good looking results: What's next is local optimality, investigating cell structure sharing on multiple levels, experimenting with parameters and trying to solve the open questions from above. |
0dc8e4b
to
d53bb80
Compare
96a6249
to
5ce6f96
Compare
db1460e
to
89295c2
Compare
{ | ||
util::static_assert_iter_category<RandIt, std::random_access_iterator_tag>(); | ||
util::static_assert_iter_value<RandIt, WeightedViaNode>(); | ||
|
||
// Assumes weight roughly corresponds to duration-ish. If this is not the case e.g. | ||
// because users are setting weight to be distance in the profiles, then we might | ||
// either generate more candidates than we have to or not enough. But is okay. | ||
const auto scaledAtMostLongerBy = scaledAtMostLongerByFactorBasedOnDuration(weight); | ||
const auto scaledAtMostLongerBy = | ||
scaledAtMostLongerByFactorBasedOnDuration(weight / weight_multiplier); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@oxidase do you think this is good enough for now until we have durations in the overlay?
cfd798c
to
0cbca29
Compare
4643114
to
2257c70
Compare
@oxidase just helped me out running his plotting scripts for the osrm-runner bench runs on Bavaria. Seem's like our alternatives on mld are a bit slow in the current state. Here's ch And here is ch I think we need to do two things here:
|
e914ea1
to
8bc33ac
Compare
Here are the callgraphs and the functions' contribution total time sampled via after reducing the search space and only using vias with which shows generating the via candidates and unpacking paths as the most expensive operations. With the latest performance improvements in place here are the plots for and for two clusters could be from the partitions; we can check by changing cell sizes. |
6890ecd
to
726b4aa
Compare
Oops, I accidentally deleted your comment about the 400ms outlier @MoKob on bavaria - to be clear here this is on purpose using a Our default partition config values: Making the top most level smaller: And introducing an additional level: |
726b4aa
to
bb1ad09
Compare
For #3905. Implements reasonable alternatives using the via-method. See the ticket for details.