Skip to content
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

Improve rerouting logic if all candidates are very different from the initial route #3664

Merged
merged 6 commits into from
Jan 12, 2022

Conversation

azarovalex
Copy link
Contributor

Fixes #3597

@azarovalex azarovalex requested a review from a team December 17, 2021 14:45
@azarovalex azarovalex self-assigned this Dec 17, 2021
expectedTravelTime: 0,
typicalTravelTime: nil,
profileIdentifier: .automobile)
super.init(legs: [leg], shape: nil, distance: 0, expectedTravelTime: 0, typicalTravelTime: nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Little hack, because description property cannot be overriden

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxCoreNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxNavigation

Comment on lines 411 to 412


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

// If the most similar route is still more than 50% different from the original route,
// we fallback to the fastest route which index is 0.
guard bestCandidate.element.route.description.count > 0 else { return 0 }
let similarityScore = Double(bestCandidate.element.editDistance) / Double(bestCandidate.element.route.description.count)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bestCandidate.element.route.description or target?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, I don’t have a good intuition for this. Can we try out a few scenarios to see which would be more correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the best candidate is when we remove letters from the target, then we might get more than 1 here. I.e.

target = "AAAAAA"
bestCandidate = "AA"
editDistance = 4 // remove any 4 letters
score = 4 / len("AA") = 4 / 2 = 2

At the same time, if the best candidate is when you add letters, then we can get the same "larger than 1" if compared to the target length.

We can divide by the sum of the sizes to guarantee that we get the value within 0...1, but it's a bit more difficult to interpret such a score, i.e.

"AAAAAA" -> "AAAAAA" = 0 / 12 = 0.00
"AAAAAA" -> "AAAAA"  = 1 / 11 = 0.09
"AAAAAA" -> "AAAA"   = 2 / 10 = 0.20
"AAAAAA" -> "AAA"    = 3 /  9 = 0.33
"AAAAAA" -> "AA"     = 4 /  8 = 0.50
"AAAAAA" -> "A"      = 5 /  7 = 0.71
"AAAAAA" -> ""       = 6 /  6 = 1.00

"AAAAAA" -> "AAAABB" = 2 / 12 = 0.17
"AAAAAA" -> "AAABBB" = 3 / 12 = 0.25
"AAAAAA" -> "AABBBB" = 4 / 12 = 0.33
"AAAAAA" -> "BBBBBB" = 6 / 12 = 0.50

"AAAAAA" -> "BBB"    = 6 /  9 = 0.6

"AAAAAA" -> "AAAAAAC"     = 1 / 13 = 0.08
"AAAAAA" -> "AAAAAACCCC"  = 4 / 16 = 0.25
"AAAAAA" -> "AAAAAACCCCC" = 5 / 17 = 0.29

Maybe we can compare the score to 0.25 as for "replacing the half of the string" or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some tests for different candidate lengths and it seems like @bamx23's algorithm might show better results for some edge cases.
It's now a little bit harder to understand, but I added a comment with a link to this explanation.

Even if we are unable to select the most common route we will fallback to the fastest route which not as bad.

}).enumerated().min(by: { $0.element.editDistance < $1.element.editDistance }) else { return nil }


// If the most similar route is still more than 50% different from the original route,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 50%?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This number came from #3597 (comment). There are only ever two road names in the route description per leg, so a 50% match is roughly one of the two names matching (modulo any differences in name length or minor things like “South”). We could probably lower the threshold without much problem, but this becomes a bugfarm, then the per-step approach in mapbox/mapbox-navigation-android#3116 (comment) would be a decent plan B.

@1ec5 1ec5 added this to the v2.2-beta milestone Dec 17, 2021
@1ec5 1ec5 added bug Something isn’t working topic: directions labels Dec 17, 2021
Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested changelog entry:

  • When rerouting the user, if none of the new routes is very similar to the original route selection, the Router now follows the most optimal route, not a route that is only marginally similar. (#3664)

}).enumerated().min(by: { $0.element.editDistance < $1.element.editDistance }) else { return nil }


// If the most similar route is still more than 50% different from the original route,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This number came from #3597 (comment). There are only ever two road names in the route description per leg, so a 50% match is roughly one of the two names matching (modulo any differences in name length or minor things like “South”). We could probably lower the threshold without much problem, but this becomes a bugfarm, then the per-step approach in mapbox/mapbox-navigation-android#3116 (comment) would be a decent plan B.

Sources/MapboxCoreNavigation/Router.swift Outdated Show resolved Hide resolved
// If the most similar route is still more than 50% different from the original route,
// we fallback to the fastest route which index is 0.
guard bestCandidate.element.route.description.count > 0 else { return 0 }
let similarityScore = Double(bestCandidate.element.editDistance) / Double(bestCandidate.element.route.description.count)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, I don’t have a good intuition for this. Can we try out a few scenarios to see which would be more correct?

expectedTravelTime: 0,
typicalTravelTime: nil,
profileIdentifier: .automobile)
super.init(legs: [leg], shape: nil, distance: 0, expectedTravelTime: 0, typicalTravelTime: nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests/MapboxCoreNavigationTests/RerouteTests.swift Outdated Show resolved Hide resolved
@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxCoreNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxNavigation

@azarovalex azarovalex force-pushed the azarovalex/improve-reroute-logic branch from 53878e7 to 28efaa9 Compare December 21, 2021 14:34
@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxCoreNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxCoreNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxCoreNavigation

@mapbox-github-ci-issues-public-1

No breaking changes detected in MapboxNavigation

@azarovalex azarovalex merged commit c9ae2d2 into main Jan 12, 2022
@azarovalex azarovalex deleted the azarovalex/improve-reroute-logic branch January 12, 2022 15:24
@mapbox mapbox deleted a comment Mar 7, 2022
@mapbox mapbox deleted a comment Mar 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn’t working topic: directions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Router chooses most similar route leg summary even when very dissimilar
3 participants