nextroute 1.8.1__cp38-cp38-macosx_14_0_arm64.whl → 1.12.3__cp38-cp38-macosx_14_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
nextroute/__about__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  # © 2019-present nextmv.io inc
2
2
 
3
- __version__ = "v1.8.1"
3
+ __version__ = "v1.12.3"
Binary file
nextroute/options.py CHANGED
@@ -16,6 +16,8 @@ from nextroute.base_model import BaseModel
16
16
  _DURATIONS_ARGS = [
17
17
  "-check.duration",
18
18
  "-solve.duration",
19
+ "-solve.plateau.duration",
20
+ "-solve.plateau.delay",
19
21
  ]
20
22
 
21
23
  # Arguments that require a string enum.
@@ -79,16 +81,20 @@ class Options(BaseModel):
79
81
  MODEL_OBJECTIVES_CAPACITIES: str = ""
80
82
  """
81
83
  Capacity objective, provide triple for each resource
82
- `name:default;factor:1.0;offset;0.0`.
84
+ `name=default;factor=1.0;offset=0.0`.
83
85
  """
84
86
  MODEL_OBJECTIVES_CLUSTER: float = 0.0
85
87
  """Factor to weigh the cluster objective."""
88
+ MODEL_OBJECTIVES_DISTANCE: float = 0.0
89
+ """Factor to weigh the distance objective."""
86
90
  MODEL_OBJECTIVES_EARLYARRIVALPENALTY: float = 1.0
87
91
  """Factor to weigh the early arrival objective."""
88
92
  MODEL_OBJECTIVES_LATEARRIVALPENALTY: float = 1.0
89
93
  """Factor to weigh the late arrival objective."""
90
94
  MODEL_OBJECTIVES_MINSTOPS: float = 1.0
91
95
  """Factor to weigh the min stops objective."""
96
+ MODEL_OBJECTIVES_STOPBALANCE: float = 0.0
97
+ """Factor to weigh the stop balance objective."""
92
98
  MODEL_OBJECTIVES_TRAVELDURATION: float = 0.0
93
99
  """Factor to weigh the travel duration objective."""
94
100
  MODEL_OBJECTIVES_UNPLANNEDPENALTY: float = 1.0
@@ -105,6 +111,8 @@ class Options(BaseModel):
105
111
  """Ignore the initial solution."""
106
112
  MODEL_PROPERTIES_DISABLE_STOPDURATIONMULTIPLIERS: bool = False
107
113
  """Ignore the stop duration multipliers defined on vehicles."""
114
+ MODEL_PROPERTIES_MAXIMUMTIMEHORIZON: int = 15552000
115
+ """Maximum time horizon for the model in seconds."""
108
116
  MODEL_VALIDATE_DISABLE_RESOURCES: bool = False
109
117
  """Disable the resources validation."""
110
118
  MODEL_VALIDATE_DISABLE_STARTTIME: bool = False
@@ -125,8 +133,48 @@ class Options(BaseModel):
125
133
  Maximum number of parallel runs, -1 results in using all available
126
134
  resources.
127
135
  """
136
+ SOLVE_PLATEAU_DELAY: float = 0.0
137
+ """Delay before starting to monitor for a plateau."""
138
+ SOLVE_PLATEAU_ABSOLUTETHRESHOLD: float = -1
139
+ """Absolute threshold for significant improvement."""
140
+ SOLVE_PLATEAU_DURATION: float = 0.0
141
+ """Maximum duration, in seconds, without (significant) improvement."""
142
+ SOLVE_PLATEAU_ITERATIONS: int = 0
143
+ """Maximum number of iterations without (significant) improvement."""
144
+ SOLVE_PLATEAU_RELATIVETHRESHOLD: float = 0.0
145
+ """Relative threshold for significant improvement."""
128
146
  SOLVE_RUNDETERMINISTICALLY: bool = False
129
147
  """Run the parallel solver deterministically."""
148
+ SOLVE_SOLVER_PLANGROUPSIZE_DELTA: int = 0
149
+ """Delta for the plan group size parameter."""
150
+ SOLVE_SOLVER_PLANGROUPSIZE_DELTAAFTERITERATIONS: int = 1000000000
151
+ """Delta after each iteration for the plan group size parameter."""
152
+ SOLVE_SOLVER_PLANGROUPSIZE_MAXVALUE: int = 2
153
+ """Maximum value for the plan group size parameter."""
154
+ SOLVE_SOLVER_PLANGROUPSIZE_MINVALUE: int = 2
155
+ """Minimum value for the plan group size parameter."""
156
+ SOLVE_SOLVER_PLANGROUPSIZE_SNAPBACKAFTERIMPROVEMENT: bool = True
157
+ """Snap back to start value after improvement of best solution for the plan group size parameter."""
158
+ SOLVE_SOLVER_PLANGROUPSIZE_STARTVALUE: int = 2
159
+ """Start value for the plan group size parameter."""
160
+ SOLVE_SOLVER_PLANGROUPSIZE_ZIGZAG: bool = True
161
+ """Zigzag between min and max value like a jig saw for the plan group size parameter."""
162
+ SOLVE_SOLVER_UNPLANUNITS_DELTA: int = 2
163
+ """Delta for the unplan units parameter."""
164
+ SOLVE_SOLVER_UNPLANUNITS_DELTAAFTERITERATIONS: int = 125
165
+ """Delta after each iteration for the unplan units parameter."""
166
+ SOLVE_SOLVER_UNPLANUNITS_MAXVALUE: int = -1
167
+ """Maximum value for the unplan units parameter."""
168
+ SOLVE_SOLVER_UNPLANUNITS_MINVALUE: int = 2
169
+ """Minimum value for the unplan units parameter."""
170
+ SOLVE_SOLVER_UNPLANUNITS_SNAPBACKAFTERIMPROVEMENT: bool = True
171
+ """Snap back to start value after improvement of best solution for the unplan units parameter."""
172
+ SOLVE_SOLVER_UNPLANUNITS_STARTVALUE: int = 2
173
+ """Start value for the unplan units parameter."""
174
+ SOLVE_SOLVER_UNPLANUNITS_ZIGZAG: bool = True
175
+ """Zigzag between min and max value like a jig saw for the unplan units parameter."""
176
+ SOLVE_SOLVER_UNPLANWEIGHTS: str = "Vehicle:3,Island:1,Location:293"
177
+ """Unplan heuristic weights parameter."""
130
178
  SOLVE_STARTSOLUTIONS: int = -1
131
179
  """
132
180
  Number of solutions to generate on top of those passed in; one solution
nextroute/schema/input.py CHANGED
@@ -4,7 +4,8 @@
4
4
  Defines the input class.
5
5
  """
6
6
 
7
- from typing import Any, List, Optional
7
+ from datetime import datetime
8
+ from typing import Any, List, Optional, Union
8
9
 
9
10
  from nextroute.base_model import BaseModel
10
11
  from nextroute.schema.stop import AlternateStop, Stop, StopDefaults
@@ -30,6 +31,30 @@ class DurationGroup(BaseModel):
30
31
  """Stop IDs contained in the group."""
31
32
 
32
33
 
34
+ class MatrixTimeFrame(BaseModel):
35
+ """Represents a time-dependent duration matrix or scaling factor."""
36
+
37
+ start_time: datetime
38
+ """Start time of the time frame."""
39
+ end_time: datetime
40
+ """End time of the time frame."""
41
+ matrix: Optional[List[List[float]]] = None
42
+ """Duration matrix for the time frame."""
43
+ scaling_factor: Optional[float] = None
44
+ """Scaling factor for the time frame."""
45
+
46
+
47
+ class TimeDependentMatrix(BaseModel):
48
+ """Represents time-dependent duration matrices."""
49
+
50
+ vehicle_ids: Optional[List[str]] = None
51
+ """Vehicle IDs for which the duration matrix is defined."""
52
+ default_matrix: List[List[float]]
53
+ """Default duration matrix."""
54
+ matrix_time_frames: Optional[List[MatrixTimeFrame]] = None
55
+ """Time-dependent duration matrices."""
56
+
57
+
33
58
  class Input(BaseModel):
34
59
  """Input schema for Nextroute."""
35
60
 
@@ -46,10 +71,16 @@ class Input(BaseModel):
46
71
  """Default values for vehicles and stops."""
47
72
  distance_matrix: Optional[List[List[float]]] = None
48
73
  """Matrix of travel distances in meters between stops."""
49
- duratrion_groups: Optional[List[DurationGroup]] = None
74
+ duration_groups: Optional[List[DurationGroup]] = None
50
75
  """Duration in seconds added when approaching the group."""
51
- duration_matrix: Optional[List[List[float]]] = None
52
- """Matrix of travel durations in seconds between stops."""
76
+ duration_matrix: Optional[
77
+ Union[
78
+ List[List[float]],
79
+ TimeDependentMatrix,
80
+ List[TimeDependentMatrix],
81
+ ]
82
+ ] = None
83
+ """Matrix of travel durations in seconds between stops as a single matrix or duration matrices."""
53
84
  options: Optional[Any] = None
54
85
  """Arbitrary options."""
55
86
  stop_groups: Optional[List[List[str]]] = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: nextroute
3
- Version: 1.8.1
3
+ Version: 1.12.3
4
4
  Summary: Nextroute is an engine for solving Vehicle Routing Problems (VRPs).
5
5
  Author-email: Nextmv <tech@nextmv.io>
6
6
  Maintainer-email: Nextmv <tech@nextmv.io>
@@ -104,6 +104,7 @@ Classifier: Programming Language :: Python :: 3.9
104
104
  Classifier: Programming Language :: Python :: 3.10
105
105
  Classifier: Programming Language :: Python :: 3.11
106
106
  Classifier: Programming Language :: Python :: 3.12
107
+ Classifier: Programming Language :: Python :: 3.13
107
108
  Requires-Python: >=3.8
108
109
  Description-Content-Type: text/markdown
109
110
  License-File: LICENSE
@@ -197,7 +198,7 @@ file.
197
198
 
198
199
  For further information on how to get started, features, deployment, etc.,
199
200
  please refer to the [official
200
- documentation](https://www.nextmv.io/docs/vehicle-routing).
201
+ documentation](https://www.nextmv.io/docs/vehicle-routing/get-started).
201
202
 
202
203
  ### Go
203
204
 
@@ -1,14 +1,14 @@
1
- nextroute/__about__.py,sha256=QAWPbTk3M2yG_B_CwMV54PyoO6pTiEWmLXI54Z4A3-o,56
1
+ nextroute/__about__.py,sha256=H71OIfyHAXJOiG4wuGcoP506V3in6aScHaOMWCJknuM,57
2
2
  nextroute/__init__.py,sha256=wBHS73T_Mm2MfcEx4chZCI1QMbV-a1D7bw7megFLgb4,529
3
3
  nextroute/base_model.py,sha256=Jl205oJZvndkY8rIomZD2k5YhlGgRBn_2I1BKwQ8Vkk,541
4
- nextroute/options.py,sha256=a6tiIWWmLSgGjQKVA2ASPMzDEQl9G6Dx6jp4lbRy_kQ,7541
4
+ nextroute/options.py,sha256=tZcTLIjsx-6fq9Q9Y-Z8syKbPqGyR3GV6vfpWvVmzLQ,10280
5
5
  nextroute/solve.py,sha256=It1kDEdFk_AXX-gEUjvQbc7C-0ma9bEPRbnC_bHMsUU,4192
6
6
  nextroute/version.py,sha256=aA_wmIifNRCzxBigX4cSz1Y2CdXvuBNIiY7Nem5UqRA,325
7
- nextroute/bin/nextroute.exe,sha256=grmSufPLzfqURqNgZlpm_Oz8tdbjJugGKkTreORA8Pw,13300144
7
+ nextroute/bin/nextroute.exe,sha256=UrjmdA8fjj-s06wT5a6eI85RORVDbtEzB8JdK527r7c,14994304
8
8
  nextroute/check/__init__.py,sha256=Hrw5LUqdMeaBEsoIrJmWDhmAKAzGuzDnoBExwNWJvlU,1303
9
9
  nextroute/check/schema.py,sha256=hBC0Usw4_rEJHsWDxDtIi0-d6byXt8f9eYqBE9hqiCc,5853
10
10
  nextroute/schema/__init__.py,sha256=KSlnpJQMnCDq5IXyiltt9CiafcxUH40B3FdE1fc5wdI,1167
11
- nextroute/schema/input.py,sha256=8_-xi-P2t-A6mObLscKavT-Ro0td9VECp2pZOQ1dWmo,1863
11
+ nextroute/schema/input.py,sha256=uidXX_hpv1KpiIUCc_XhiiQf69vxiav9DsXfiLtpD2s,2856
12
12
  nextroute/schema/location.py,sha256=hihllMU3IXxQHugGC4Wn_TzDPr5zm4xqVqRsKanwrmA,301
13
13
  nextroute/schema/output.py,sha256=rJv_PpP0X0MdLTRa2tbDsLLbGhTRi43hGmMNmzvNZEw,4810
14
14
  nextroute/schema/statistics.py,sha256=lNlb1mcpR6xWQclG-fkDMnFoy-sEKpXKk80zU1TKrpQ,3600
@@ -18,9 +18,9 @@ tests/schema/__init__.py,sha256=MRZbyX5fYnxsXV0YP6lf32c5YYMo3NsEFqPwdwf5W18,32
18
18
  tests/schema/test_input.py,sha256=kNIlUFqCkvvQieuJIo7-6C_NB9PZqZ72NpGwUWtDZcA,1851
19
19
  tests/schema/test_output.py,sha256=i0VreVBXamC-Pk-z7X3W9APjmjfG8iOPAt2jxP4hDQA,11579
20
20
  tests/solve_golden/__init__.py,sha256=MRZbyX5fYnxsXV0YP6lf32c5YYMo3NsEFqPwdwf5W18,32
21
- tests/solve_golden/main.py,sha256=N8QTju8Iq2ip6XVn1PxcoaVY1N-GzOJUhDH31blV2Ro,1545
22
- nextroute-1.8.1.dist-info/LICENSE,sha256=ElKAl6B15yj4LTFL_Dh1hje431kMHut2urxo5nheRWs,4107
23
- nextroute-1.8.1.dist-info/METADATA,sha256=9RAaN9vgMdqBvslv1hPfGbbDdT7TdoYnGk2CUgQIEhY,15526
24
- nextroute-1.8.1.dist-info/WHEEL,sha256=fPG3h-vfL70uR7eF-JqKg0bPUCORdIAQuRpuVxflUVo,108
25
- nextroute-1.8.1.dist-info/top_level.txt,sha256=KNsuo1j7tr-QvBFS_ELmo68OmJ-orEZiOXqstGLJDXA,16
26
- nextroute-1.8.1.dist-info/RECORD,,
21
+ tests/solve_golden/main.py,sha256=VScx0kPD8ihGR5bSIpLrPTIxRh7mkk9YQ9g0eg8XZMc,1738
22
+ nextroute-1.12.3.dist-info/LICENSE,sha256=ElKAl6B15yj4LTFL_Dh1hje431kMHut2urxo5nheRWs,4107
23
+ nextroute-1.12.3.dist-info/METADATA,sha256=tB7ipov9kgEDYAuBkcA9595NCSBnlR37Kmfj6simJeo,15590
24
+ nextroute-1.12.3.dist-info/WHEEL,sha256=7oHrrmTB-AnaDl8j1Eeuo7QImBG4q2CMfROfSJb1CuE,107
25
+ nextroute-1.12.3.dist-info/top_level.txt,sha256=KNsuo1j7tr-QvBFS_ELmo68OmJ-orEZiOXqstGLJDXA,16
26
+ nextroute-1.12.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.44.0)
2
+ Generator: setuptools (75.3.2)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp38-cp38-macosx_14_0_arm64
5
5
 
@@ -1,8 +1,6 @@
1
1
  # This script is copied to the `src` root so that the `nextroute` import is
2
2
  # resolved. It is fed an input via stdin and is meant to write the output to
3
3
  # stdout.
4
- from typing import Any, Dict
5
-
6
4
  import nextmv
7
5
 
8
6
  import nextroute
@@ -16,8 +14,8 @@ def main() -> None:
16
14
  nextmv.Parameter("output", str, "", "Path to output file. Default is stdout.", False),
17
15
  ]
18
16
 
19
- nextroute_options = nextroute.Options()
20
- for name, default_value in nextroute_options.to_dict().items():
17
+ default_options = nextroute.Options()
18
+ for name, default_value in default_options.to_dict().items():
21
19
  parameters.append(nextmv.Parameter(name.lower(), type(default_value), default_value, name, False))
22
20
 
23
21
  options = nextmv.Options(*parameters)
@@ -28,18 +26,24 @@ def main() -> None:
28
26
  nextmv.log(f" - stops: {len(input.data.get('stops', []))}")
29
27
  nextmv.log(f" - vehicles: {len(input.data.get('vehicles', []))}")
30
28
 
31
- output = solve(input, options)
29
+ model = DecisionModel()
30
+ output = model.solve(input)
32
31
  nextmv.write_local(output, path=options.output)
33
32
 
34
33
 
35
- def solve(input: nextmv.Input, options: nextmv.Options) -> Dict[str, Any]:
36
- """Solves the given problem and returns the solution."""
34
+ class DecisionModel(nextmv.Model):
35
+ def solve(self, input: nextmv.Input) -> nextmv.Output:
36
+ """Solves the given problem and returns the solution."""
37
37
 
38
- nextroute_input = nextroute.schema.Input.from_dict(input.data)
39
- nextroute_options = nextroute.Options.extract_from_dict(options.to_dict())
40
- nextroute_output = nextroute.solve(nextroute_input, nextroute_options)
38
+ nextroute_input = nextroute.schema.Input.from_dict(input.data)
39
+ nextroute_options = nextroute.Options.extract_from_dict(input.options.to_dict())
40
+ nextroute_output = nextroute.solve(nextroute_input, nextroute_options)
41
41
 
42
- return nextroute_output.to_dict()
42
+ return nextmv.Output(
43
+ options=input.options,
44
+ solution=nextroute_output.solutions[0].to_dict(),
45
+ statistics=nextroute_output.statistics.to_dict(),
46
+ )
43
47
 
44
48
 
45
49
  if __name__ == "__main__":