Skip to content

Commit

Permalink
Merge pull request #79 from nextmv-io/merschformann/adjust-max-time-h…
Browse files Browse the repository at this point in the history
…orizon

Bumping default max time horizon to 6 months
  • Loading branch information
merschformann authored Dec 16, 2024
2 parents ae8e297 + 6d21884 commit f0dc5de
Show file tree
Hide file tree
Showing 109 changed files with 10,128 additions and 73 deletions.
2 changes: 1 addition & 1 deletion factory/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type Options struct {
DurationGroups bool `json:"duration_groups" usage:"ignore the durations groups of stops"`
InitialSolution bool `json:"initial_solution" usage:"ignore the initial solution"`
} `json:"disable"`
MaximumTimeHorizon int `json:"maximum_time_horizon" usage:"maximum time horizon for the model in seconds" default:"2592000"`
MaximumTimeHorizon int `json:"maximum_time_horizon" usage:"maximum time horizon for the model in seconds" default:"15552000"`
} `json:"properties"`
Validate struct {
Disable struct {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/nextmv-io/nextroute
go 1.21

require (
github.com/nextmv-io/sdk v1.8.1
github.com/nextmv-io/sdk v1.8.2
gonum.org/v1/gonum v0.14.0
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nextmv-io/sdk v1.8.1 h1:CYhhDtd4ZeFYfHXSinVQpvH4mIPJHOqtQGUaSwBfpp8=
github.com/nextmv-io/sdk v1.8.1/go.mod h1:Y48XLPcIOOxRgO86ICNpqGrH2N5+dd1TDNvef/FD2Kc=
github.com/nextmv-io/sdk v1.8.2 h1:9jqtchlgrt7aDzRCRRBr9AM192tRBaN82hUIxpOV/Xg=
github.com/nextmv-io/sdk v1.8.2/go.mod h1:Y48XLPcIOOxRgO86ICNpqGrH2N5+dd1TDNvef/FD2Kc=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ pydantic>=2.5.2
ruff>=0.1.7
twine>=4.0.2
hatch>=1.13.0
nextmv>=0.13.1
nextmv>=0.14.1
26 changes: 15 additions & 11 deletions src/tests/solve_golden/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# This script is copied to the `src` root so that the `nextroute` import is
# resolved. It is fed an input via stdin and is meant to write the output to
# stdout.
from typing import Any, Dict

import nextmv

import nextroute
Expand All @@ -16,8 +14,8 @@ def main() -> None:
nextmv.Parameter("output", str, "", "Path to output file. Default is stdout.", False),
]

nextroute_options = nextroute.Options()
for name, default_value in nextroute_options.to_dict().items():
default_options = nextroute.Options()
for name, default_value in default_options.to_dict().items():
parameters.append(nextmv.Parameter(name.lower(), type(default_value), default_value, name, False))

options = nextmv.Options(*parameters)
Expand All @@ -28,18 +26,24 @@ def main() -> None:
nextmv.log(f" - stops: {len(input.data.get('stops', []))}")
nextmv.log(f" - vehicles: {len(input.data.get('vehicles', []))}")

output = solve(input, options)
model = DecisionModel()
output = model.solve(input)
nextmv.write_local(output, path=options.output)


def solve(input: nextmv.Input, options: nextmv.Options) -> Dict[str, Any]:
"""Solves the given problem and returns the solution."""
class DecisionModel(nextmv.Model):
def solve(self, input: nextmv.Input) -> nextmv.Output:
"""Solves the given problem and returns the solution."""

nextroute_input = nextroute.schema.Input.from_dict(input.data)
nextroute_options = nextroute.Options.extract_from_dict(options.to_dict())
nextroute_output = nextroute.solve(nextroute_input, nextroute_options)
nextroute_input = nextroute.schema.Input.from_dict(input.data)
nextroute_options = nextroute.Options.extract_from_dict(input.options.to_dict())
nextroute_output = nextroute.solve(nextroute_input, nextroute_options)

return nextroute_output.to_dict()
return nextmv.Output(
options=input.options,
solution=nextroute_output.solutions[0].to_dict(),
statistics=nextroute_output.statistics.to_dict(),
)


if __name__ == "__main__":
Expand Down
5 changes: 3 additions & 2 deletions src/tests/solve_golden/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ func TestPythonSolveGolden(t *testing.T) {
{Key: "$.statistics.result.duration", Replacement: golden.StableFloat},
{Key: "$.statistics.run.duration", Replacement: golden.StableFloat},
{Key: "$.statistics.result.value", Replacement: golden.StableFloat},
{Key: "$.options.nextmv.output", Replacement: "output.json"},
{Key: "$.options.nextmv.input", Replacement: "input.json"},
{Key: "$.options.output", Replacement: "output.json"},
{Key: "$.options.input", Replacement: "input.json"},
{Key: "$.statistics.result.custom.max_travel_duration", Replacement: golden.StableFloat},
{Key: "$.statistics.result.custom.min_travel_duration", Replacement: golden.StableFloat},
{Key: "$.statistics.result.custom.max_duration", Replacement: golden.StableFloat},
Expand All @@ -83,6 +83,7 @@ func TestPythonSolveGolden(t *testing.T) {
Thresholds: golden.Tresholds{
Float: 0.01,
},
GoldenExtension: ".python.golden",
ExecutionConfig: &golden.ExecutionConfig{
Command: "python3",
Args: []string{pythonFileDestination},
Expand Down
2 changes: 1 addition & 1 deletion tests/check/input.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
2 changes: 1 addition & 1 deletion tests/custom_constraint/input.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
2 changes: 1 addition & 1 deletion tests/custom_matrices/input.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
2 changes: 1 addition & 1 deletion tests/custom_objective/input.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
2 changes: 1 addition & 1 deletion tests/custom_operators/input.json.golden
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
1 change: 1 addition & 0 deletions tests/golden/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func TestGolden(t *testing.T) {
// for deterministic tests
"-solve.startsolutions", "1",
},
GoldenExtension: ".go.golden",
TransientFields: []golden.TransientField{
{Key: "$.version.sdk", Replacement: golden.StableVersion},
{Key: "$.statistics.result.duration", Replacement: golden.StableFloat},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
208 changes: 208 additions & 0 deletions tests/golden/testdata/activation_penalty.json.python.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
{
"options": {
"check_duration": 30,
"check_verbosity": "off",
"format_disable_progression": true,
"input": "input.json",
"model_constraints_disable_attributes": false,
"model_constraints_disable_capacities": [],
"model_constraints_disable_capacity": false,
"model_constraints_disable_distancelimit": false,
"model_constraints_disable_groups": false,
"model_constraints_disable_maximumduration": false,
"model_constraints_disable_maximumstops": false,
"model_constraints_disable_maximumwaitstop": false,
"model_constraints_disable_maximumwaitvehicle": false,
"model_constraints_disable_mixingitems": false,
"model_constraints_disable_precedence": false,
"model_constraints_disable_starttimewindows": false,
"model_constraints_disable_vehicleendtime": false,
"model_constraints_disable_vehiclestarttime": false,
"model_constraints_enable_cluster": false,
"model_objectives_capacities": "",
"model_objectives_cluster": 0,
"model_objectives_earlyarrivalpenalty": 1,
"model_objectives_latearrivalpenalty": 1,
"model_objectives_minstops": 1,
"model_objectives_travelduration": 0,
"model_objectives_unplannedpenalty": 1,
"model_objectives_vehicleactivationpenalty": 1,
"model_objectives_vehiclesduration": 1,
"model_properties_disable_durationgroups": false,
"model_properties_disable_durations": false,
"model_properties_disable_initialsolution": false,
"model_properties_disable_stopdurationmultipliers": false,
"model_validate_disable_resources": false,
"model_validate_disable_starttime": false,
"model_validate_enable_matrix": false,
"model_validate_enable_matrixasymmetrytolerance": 20,
"output": "output.json",
"solve_duration": 10,
"solve_iterations": 50,
"solve_parallelruns": 1,
"solve_rundeterministically": true,
"solve_startsolutions": 1
},
"solution": {
"objective": {
"name": "1 * vehicle_activation_penalty + 1 * vehicles_duration + 1 * unplanned_penalty",
"objectives": [
{
"factor": 1,
"name": "vehicle_activation_penalty",
"value": 0
},
{
"base": 909.0466359667602,
"factor": 1,
"name": "vehicles_duration",
"value": 909.0466359667602
},
{
"factor": 1,
"name": "unplanned_penalty",
"value": 0
}
],
"value": 909.0466359667602
},
"unplanned": [],
"vehicles": [
{
"id": "v1",
"route": [],
"route_duration": 0,
"route_travel_duration": 0
},
{
"id": "v2",
"route": [
{
"cumulative_travel_duration": 0,
"stop": {
"id": "v2-start",
"location": {
"lat": 35.017209,
"lon": 135.672009
}
},
"travel_duration": 0
},
{
"cumulative_travel_duration": 0,
"stop": {
"id": "Arashiyama Bamboo Forest",
"location": {
"lat": 35.017209,
"lon": 135.672009
}
},
"travel_duration": 0
},
{
"cumulative_travel_distance": 5752,
"cumulative_travel_duration": 287,
"stop": {
"id": "Kinkaku-ji",
"location": {
"lat": 35.039705,
"lon": 135.728898
}
},
"travel_distance": 5752,
"travel_duration": 287
},
{
"cumulative_travel_distance": 9081,
"cumulative_travel_duration": 454,
"stop": {
"id": "Nijō Castle",
"location": {
"lat": 35.014239,
"lon": 135.748134
}
},
"travel_distance": 3329,
"travel_duration": 166
},
{
"cumulative_travel_distance": 10857,
"cumulative_travel_duration": 542,
"stop": {
"id": "Kyoto Imperial Palace",
"location": {
"lat": 35.025431,
"lon": 135.762057
}
},
"travel_distance": 1776,
"travel_duration": 88
},
{
"cumulative_travel_distance": 13696,
"cumulative_travel_duration": 684,
"stop": {
"id": "Gionmachi",
"location": {
"lat": 35.002457,
"lon": 135.775682
}
},
"travel_distance": 2839,
"travel_duration": 141
},
{
"cumulative_travel_distance": 14897,
"cumulative_travel_duration": 745,
"stop": {
"id": "Kiyomizu-dera",
"location": {
"lat": 34.994857,
"lon": 135.78506
}
},
"travel_distance": 1201,
"travel_duration": 60
},
{
"cumulative_travel_distance": 18177,
"cumulative_travel_duration": 909,
"stop": {
"id": "Fushimi Inari Taisha",
"location": {
"lat": 34.967146,
"lon": 135.772695
}
},
"travel_distance": 3280,
"travel_duration": 164
}
],
"route_duration": 909,
"route_travel_distance": 18177,
"route_travel_duration": 909
}
]
},
"statistics": {
"result": {
"custom": {
"activated_vehicles": 1,
"max_duration": 0.123,
"max_stops_in_vehicle": 7,
"max_travel_duration": 0.123,
"min_duration": 0.123,
"min_stops_in_vehicle": 7,
"min_travel_duration": 0.123,
"unplanned_stops": 0
},
"duration": 0.123,
"value": 0.123
},
"run": {
"duration": 0.123,
"iterations": 50
},
"schema": "v1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 2592000
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
Expand Down
Loading

0 comments on commit f0dc5de

Please sign in to comment.