-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Add a multiplier to the matrix #5298
Conversation
e9390bc
to
5a7f05d
Compare
src/engine/plugins/table.cpp
Outdated
@@ -127,6 +128,12 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, | |||
result_tables_pair.second[table_index] = distance_estimate; | |||
} | |||
} | |||
if (params.scale_factor > 1.0 && | |||
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION) |
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.
Hmm should scale_factor also scale the fallback speed result?
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.
Yes fallback speeds should mirror real speeds. Scaling one and not the other is questionable when feeding into a optimzation solver.
@@ -135,6 +140,9 @@ struct TableParameters : public BaseParameters | |||
if (fallback_speed < 0) | |||
return false; | |||
|
|||
if (scale_factor < 1) |
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.
Docs say > 0, but code enforces > 1.
I think any value should be allowed - scale_factor=-0.5
is weird, but possible to imagine.
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.
So we shouldn't really enforce anything here?
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.
Yeah - I can’t think of a reason to restrict this, who knows how people might want to use it.
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.
@danpat I'm actually going to clamp to >0. See #5298 (comment) for overflow checks and #5298 (comment) for why doubling the number of overflow checks would trigger computation growth.
include/nodejs/node_osrm_support.hpp
Outdated
Nan::ThrowError("scale_factor must be a number"); | ||
return table_parameters_ptr(); | ||
} | ||
else if (scale_factor->NumberValue() < 1) |
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.
Same again - docs say > 0, code enforces >= 1 (not the same as above btw, which does > 1, not >=).
Should allow any number I think, no need to restrict this, it doesn't trigger any computation growth if it's large.
src/engine/plugins/table.cpp
Outdated
@@ -96,15 +96,16 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms, | |||
} | |||
|
|||
// Scan table for null results - if any exist, replace with distance estimates | |||
if (params.fallback_speed > 0) | |||
if (params.fallback_speed > 0 || params.scale_factor > 1.0) |
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.
Should be != 1
src/engine/plugins/table.cpp
Outdated
result_tables_pair.first[table_index] != MAXIMAL_EDGE_DURATION) | ||
{ | ||
result_tables_pair.first[table_index] = | ||
result_tables_pair.first[table_index] * (double)params.scale_factor; |
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.
Should probably check for overflow here, and clamp the result to some very large number. - if value * scale_factor ends up > MAXIMAL_EDGE_DURATION (i.e. overflows), we should set value
to MAXIMAL_EDGE_DURATION-1
.
The value of MAXIMAL_EDGE_DURATION
is reserved to indicate "noroute", so we have to clamp slightly lower than that.
Something like:
double result = result_tables_pair.first[table_index] * params.scale_factor;
if (double > MAXIMAL_EDGE_DURATION) {
result_tables_pair.first[table_index] = MAXIMAL_EDGE_DURATION - 1;
} else {
result_tables_pair.first[table_index] = result;
}
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.
Also note - no need to cast params.scale_factor
to double
- it's already one of those. Also, it's preferred in C++ to use static_cast<double>(thingy)
instead of C-style (double)thing
casts - the C++ style has better defined behaviour, which makes it easier to debug if something goes wrong.
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.
👍
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.
@danpat after applying a clamp, should we return an error? Or return the raw really large value? For instance in this test case below, the really large unexplained number gets piped through.
Also, we need a clamp for a negative multiplier too, yes?
✔ Given the profile "testbot"
✔ And the partition extra arguments "--small-component-size 1 --max-cell-sizes 2,4,8,16"
✔ Given the query options
| scale_factor | 2147483647 |
✔ Given the node map
"""
a b
"""
✔ And the ways
| nodes |
| ab |
✖ When I request a travel time matrix I should get
| | a | b |
| a | 0 | 20 |
| b | 20 | 0 |
Failures:
1) Scenario: Testbot - Travel time matrix of minimal network with scale factor - features/testbot/duration_matrix.feature:611
Step: When I request a travel time matrix I should get - features/testbot/duration_matrix.feature:624
Step Definition: features/step_definitions/distance_matrix.js:10
Message:
Tables were not identical:
| | a | b |
| a | 0 | (-) 20 |
| a | 0 | (+) 214748364.6 |
| b | (-) 20 | 0 |
| b | (+) 214748364.6 | 0 |
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.
Hm I think we should clamp down the scale_factor
itself. Try to clamp the result down after an overflow has occured is too late, and to check every element before doing the multiplication to prevent an overflow will be expensive.
This is the kind of check that would happen before every multiplication:
EdgeDuration diff = MAXIMAL_EDGE_DURATION / result_tables_pair.first[table_index];
if (params.scale_factor > diff) {
// overflow will happen for std::lround(result_tables_pair.first[table_index] * params.scale_factor) so error
}
result_tables_pair.first[table_index] = std::lround(result_tables_pair.first[table_index] * params.scale_factor);
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.
I've gone with return the raw really large value
.
Is there a reason to forbid |
@jcoupey there is not a reason. I'm removing the greater than 1 restriction now. |
@ghoshkaj I think you want to keep a |
@jcoupey I'm coming to same conclusion as I'm trying to figure out checking for overflows. Doing two multiplications for each overflow is quite expensive and I don't think a negative durations matrix is useful. So @danpat I'm going with @jcoupey's suggestion of clamping |
e9a5471
to
8786ad4
Compare
src/server/service/table_service.cpp
Outdated
@@ -61,6 +61,11 @@ std::string getWrongOptionHelp(const engine::api::TableParameters ¶meters) | |||
help = "fallback_speed must be > 0"; | |||
} | |||
|
|||
if (parameters.scale_factor < 0) |
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.
This tests for < 0 but the error message says it must be > 0.
The if
should probably be <=
to match the message.
@ghoshkaj So we're failing on coverage. One more request: add some tests that exercise the failure conditions - |
b9ccb53
to
b805233
Compare
8df15e5
to
c23461b
Compare
* add a multiplier to the matrix * add rounding * remove scale_factor restrictions * clamp for overflow error * update check to match error message * enforce clamping on < 0 and increase test coverage * add an invalid scale_factor value to node tests * increase test coverage * changelog
- Changes from 5.20.0 - Features: - ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [Project-OSRM#5255](Project-OSRM#5255) - ADDED: if `fallback_speed` is used, a new structure `fallback_speed_cells` will describe which cells contain estimated values [Project-OSRM#5259](Project-OSRM#5259) - Table: - ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [Project-OSRM#5298](Project-OSRM#5298) - FIXED: only trigger `scale_factor` code to scan matrix when necessary. [Project-OSRM#5303](Project-OSRM#5303)
- Changes from 5.20.0 - Features: - ADDED: all waypoints in responses now contain a distance property between the original coordinate and the snapped location. [Project-OSRM#5255](Project-OSRM#5255) - ADDED: if `fallback_speed` is used, a new structure `fallback_speed_cells` will describe which cells contain estimated values [Project-OSRM#5259](Project-OSRM#5259) - REMOVED: we no longer publish Node 4 or 6 binary modules (they are still buildable from source) [Project-OSRM#5314](Project-OSRM#5314) - Table: - ADDED: new parameter `scale_factor` which will scale the cell `duration` values by this factor. [Project-OSRM#5298](Project-OSRM#5298) - FIXED: only trigger `scale_factor` code to scan matrix when necessary. [Project-OSRM#5303](Project-OSRM#5303) - FIXED: fix bug in reverse offset calculation that sometimes lead to negative (and other incorrect) values in distance table results [Project-OSRM#5315](Project-OSRM#5315) - Docker: - FIXED: use consistent boost version between build and runtime [Project-OSRM#5311](Project-OSRM#5311) - FIXED: don't override default permissions on /opt [Project-OSRM#5311](Project-OSRM#5311) - Matching: - CHANGED: matching will now consider edges marked with is_startpoint=false, allowing matching over ferries and other previously non-matchable edge types. [Project-OSRM#5297](Project-OSRM#5297) - Profile: - ADDED: Parse `source:maxspeed` and `maxspeed:type` tags to apply maxspeeds and add belgian flanders rural speed limit. [Project-OSRM#5217](Project-OSRM#5217) - CHANGED: Refactor maxspeed parsing to use common library. [Project-OSRM#5144](Project-OSRM#5144)
Issue
Route optimization solvers often require custom inputs when feeding in the matrix. This is a simple dumb multiplier of table duration values.
Tasklist
Requirements / Relations
Link any requirements here. Other pull requests this PR is based on?