0
# Route Optimization
1
2
Core single-request route optimization functionality for optimizing vehicle tours against custom objectives and constraints. This capability provides the primary API method for solving vehicle routing problems with shipments, vehicles, and optimization parameters.
3
4
## Capabilities
5
6
### optimize_tours
7
8
Optimizes vehicle tours for a single ShipmentModel, returning optimized routes that minimize total cost while satisfying constraints.
9
10
```python { .api }
11
def optimize_tours(
12
request: OptimizeToursRequest,
13
*,
14
retry: Optional[Retry] = gapic_v1.method.DEFAULT,
15
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
16
metadata: Sequence[Tuple[str, Union[str, bytes]]] = ()
17
) -> OptimizeToursResponse: ...
18
```
19
20
**Parameters:**
21
- `request`: `OptimizeToursRequest` - The optimization request containing the ShipmentModel and parameters
22
- `retry`: Optional retry configuration for the request
23
- `timeout`: Optional timeout for the request (float seconds or object)
24
- `metadata`: Optional metadata sequence for the request
25
26
**Returns:** `OptimizeToursResponse` containing optimized routes, metrics, and any validation errors
27
28
### Request/Response Types
29
30
#### OptimizeToursRequest
31
32
```python { .api }
33
class OptimizeToursRequest:
34
parent: str # Required. Format: "projects/{project-id}" or "projects/{project-id}/locations/{location-id}"
35
timeout: Optional[duration_pb2.Duration] # Maximum computation time
36
model: Optional[ShipmentModel] # The shipment model to optimize
37
solving_mode: Optional[SolvingMode] # Optimization approach (DEFAULT_SOLVE, VALIDATE_ONLY, DETECT_SOME_INFEASIBLE_SHIPMENTS)
38
search_mode: Optional[SearchMode] # Search strategy (RETURN_FAST, CONSUME_ALL_AVAILABLE_TIME)
39
injected_first_solution_routes: Optional[Sequence[ShipmentRoute]] # Pre-assigned routes
40
injected_solution_constraint: Optional[InjectedSolutionConstraint] # Solution constraints
41
refresh_details_routes: Optional[Sequence[ShipmentRoute]] # Routes to refresh
42
interpret_injected_solutions_using_labels: Optional[bool] # Use labels for injected solutions
43
consider_road_traffic: Optional[bool] # Include traffic in routing
44
populate_polylines: Optional[bool] # Include route polylines in response
45
populate_transitions: Optional[bool] # Include transition details
46
allow_large_deadline_despite_interruption_risk: Optional[bool] # Allow long deadlines
47
use_geodesic_distances: Optional[bool] # Use geodesic distance calculations
48
geodesic_meters_per_second: Optional[float] # Speed for geodesic calculations
49
max_validation_errors: Optional[int] # Maximum validation errors to return
50
label: Optional[str] # Request label for tracking
51
```
52
53
#### OptimizeToursResponse
54
55
```python { .api }
56
class OptimizeToursResponse:
57
routes: Sequence[ShipmentRoute] # Optimized vehicle routes
58
request_label: str # Label from the request
59
skipped_shipments: Sequence[SkippedShipment] # Shipments that couldn't be assigned
60
validation_errors: Sequence[OptimizeToursValidationError] # Input validation errors
61
metrics: Optional[AggregatedMetrics] # Optimization statistics and costs
62
total_cost: float # Total cost of the solution
63
```
64
65
## Usage Examples
66
67
### Basic Route Optimization
68
69
```python
70
from google.maps import routeoptimization_v1
71
72
client = routeoptimization_v1.RouteOptimizationClient()
73
74
# Create optimization request
75
request = routeoptimization_v1.OptimizeToursRequest(
76
parent="projects/my-project",
77
model=routeoptimization_v1.ShipmentModel(
78
shipments=[
79
routeoptimization_v1.Shipment(
80
display_name="Delivery 1",
81
deliveries=[{
82
"location": {"lat_lng": {"latitude": 37.7749, "longitude": -122.4194}},
83
"time_windows": [{"start_time": {"seconds": 28800}, "end_time": {"seconds": 64800}}], # 8 AM - 6 PM
84
"duration": {"seconds": 300} # 5 minutes
85
}]
86
)
87
],
88
vehicles=[
89
routeoptimization_v1.Vehicle(
90
display_name="Truck 1",
91
start_location={"lat_lng": {"latitude": 37.7649, "longitude": -122.4294}},
92
end_location={"lat_lng": {"latitude": 37.7649, "longitude": -122.4294}},
93
start_time_windows=[{"start_time": {"seconds": 28800}, "end_time": {"seconds": 32400}}], # 8 AM - 9 AM
94
end_time_windows=[{"start_time": {"seconds": 57600}, "end_time": {"seconds": 64800}}], # 4 PM - 6 PM
95
cost_per_hour=25.0,
96
cost_per_kilometer=1.2
97
)
98
]
99
)
100
)
101
102
# Optimize tours
103
response = client.optimize_tours(request=request)
104
105
# Process results
106
print(f"Total cost: ${response.total_cost:.2f}")
107
for i, route in enumerate(response.routes):
108
print(f"Route {i}: {len(route.visits)} stops")
109
for visit in route.visits:
110
print(f" Stop: {visit.shipment_label} at {visit.start_time}")
111
```
112
113
### Optimization with Constraints
114
115
```python
116
from google.maps import routeoptimization_v1
117
from google.protobuf import duration_pb2
118
119
client = routeoptimization_v1.RouteOptimizationClient()
120
121
# Create request with time constraints and vehicle capacities
122
request = routeoptimization_v1.OptimizeToursRequest(
123
parent="projects/my-project",
124
timeout=duration_pb2.Duration(seconds=300), # 5 minute timeout
125
model=routeoptimization_v1.ShipmentModel(
126
global_start_time={"seconds": 28800}, # 8 AM
127
global_end_time={"seconds": 64800}, # 6 PM
128
shipments=[
129
routeoptimization_v1.Shipment(
130
display_name="Heavy Package",
131
deliveries=[{
132
"location": {"lat_lng": {"latitude": 37.7749, "longitude": -122.4194}},
133
"duration": {"seconds": 600}, # 10 minutes
134
"load_demands": {"weight": {"amount": 50}} # 50 units of weight
135
}]
136
)
137
],
138
vehicles=[
139
routeoptimization_v1.Vehicle(
140
display_name="Small Truck",
141
start_location={"lat_lng": {"latitude": 37.7649, "longitude": -122.4294}},
142
load_limits={"weight": {"max_load": 100}}, # Max 100 units
143
break_rule=routeoptimization_v1.BreakRule(
144
break_requests=[{
145
"earliest_start_time": {"seconds": 43200}, # 12 PM
146
"latest_start_time": {"seconds": 46800}, # 1 PM
147
"min_duration": {"seconds": 1800} # 30 minutes
148
}]
149
)
150
)
151
]
152
),
153
consider_road_traffic=True,
154
populate_polylines=True
155
)
156
157
response = client.optimize_tours(request=request)
158
159
# Check for skipped shipments
160
if response.skipped_shipments:
161
print("Some shipments could not be assigned:")
162
for skipped in response.skipped_shipments:
163
print(f" {skipped.label}: {[r.name for r in skipped.reasons]}")
164
```
165
166
### Validation Mode
167
168
```python
169
from google.maps import routeoptimization_v1
170
171
client = routeoptimization_v1.RouteOptimizationClient()
172
173
# Validate model without optimization
174
request = routeoptimization_v1.OptimizeToursRequest(
175
parent="projects/my-project",
176
solving_mode=routeoptimization_v1.OptimizeToursRequest.SolvingMode.VALIDATE_ONLY,
177
model=your_shipment_model
178
)
179
180
response = client.optimize_tours(request=request)
181
182
# Check validation errors
183
if response.validation_errors:
184
print("Model validation errors:")
185
for error in response.validation_errors:
186
print(f" {error.error_message}")
187
else:
188
print("Model is valid")
189
```
190
191
## Types
192
193
### SolvingMode
194
195
```python { .api }
196
class SolvingMode(enum.Enum):
197
DEFAULT_SOLVE = 0 # Solve the model
198
VALIDATE_ONLY = 1 # Only validate, don't solve
199
DETECT_SOME_INFEASIBLE_SHIPMENTS = 2 # Detect infeasible shipments
200
```
201
202
### SearchMode
203
204
```python { .api }
205
class SearchMode(enum.Enum):
206
RETURN_FAST = 0 # Return quickly with good solution
207
CONSUME_ALL_AVAILABLE_TIME = 1 # Use all available time for best solution
208
```
209
210
### AggregatedMetrics
211
212
```python { .api }
213
class AggregatedMetrics:
214
performed_shipment_count: int # Number of shipments performed
215
travel_duration: Optional[duration_pb2.Duration] # Total travel duration
216
wait_duration: Optional[duration_pb2.Duration] # Total wait duration
217
delay_duration: Optional[duration_pb2.Duration] # Total delay duration
218
break_duration: Optional[duration_pb2.Duration] # Total break duration
219
visit_duration: Optional[duration_pb2.Duration] # Total visit duration
220
total_duration: Optional[duration_pb2.Duration] # Total route duration
221
travel_distance_meters: float # Total travel distance
222
max_loads: Mapping[str, ShipmentRoute.VehicleLoad] # Maximum loads achieved
223
```
224
225
### SkippedShipment
226
227
```python { .api }
228
class SkippedShipment:
229
index: int # Shipment index in original request
230
label: str # Shipment label
231
reasons: Sequence[SkippedShipment.Reason] # Reasons for skipping
232
233
class Reason:
234
code: SkippedShipment.Reason.Code # Reason code
235
display_name: str # Human-readable reason
236
example_vehicle_index: int # Example vehicle that couldn't handle shipment
237
example_exceeded_capacity_type: str # Capacity type that was exceeded
238
239
class Code(enum.Enum):
240
CODE_UNSPECIFIED = 0
241
NO_VEHICLE = 1 # No vehicle can handle this shipment
242
DEMAND_EXCEEDS_VEHICLE_CAPACITY = 2 # Shipment demands exceed capacity
243
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT = 3 # Distance limit exceeded
244
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT = 4 # Duration limit exceeded
245
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TRAVEL_DURATION_LIMIT = 5 # Travel duration exceeded
246
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TIME_WINDOWS = 6 # Time window conflicts
247
VEHICLE_NOT_ALLOWED = 7 # Vehicle not allowed for this shipment
248
```
249
250
### OptimizeToursValidationError
251
252
```python { .api }
253
class OptimizeToursValidationError:
254
code: int # Error code
255
display_name: str # Human-readable error name
256
fields: Sequence[OptimizeToursValidationError.FieldReference] # Fields with errors
257
error_message: str # Detailed error message
258
offset_index: int # Index of problematic element
259
260
class FieldReference:
261
name: str # Field name with error
262
index: int # Index if field is repeated
263
key: str # Key if field is a map
264
sub_field: Optional[OptimizeToursValidationError.FieldReference] # Nested field reference
265
```
266
267
### ShipmentRoute
268
269
```python { .api }
270
class ShipmentRoute:
271
vehicle_index: int # Index of vehicle performing this route
272
vehicle_label: str # Label of vehicle performing this route
273
vehicle_start_time: Optional[timestamp_pb2.Timestamp] # Route start time
274
vehicle_end_time: Optional[timestamp_pb2.Timestamp] # Route end time
275
visits: Sequence[ShipmentRoute.Visit] # Visits in order
276
transitions: Sequence[ShipmentRoute.Transition] # Transitions between visits
277
has_traffic_infeasibilities: bool # Whether route has traffic issues
278
route_polyline: Optional[ShipmentRoute.EncodedPolyline] # Encoded route polyline
279
breaks: Sequence[ShipmentRoute.Break] # Driver breaks
280
metrics: Optional[AggregatedMetrics] # Route metrics
281
route_costs: Mapping[str, float] # Cost breakdown by request fields
282
route_total_cost: float # Total cost for this route
283
284
class Visit:
285
shipment_index: int # Index of shipment being visited
286
is_pickup: bool # True if pickup, false if delivery
287
visit_request_index: int # Index of visit request within shipment
288
start_time: Optional[timestamp_pb2.Timestamp] # Visit start time
289
load_demands: Mapping[str, ShipmentRoute.VehicleLoad] # Load demands
290
detour: Optional[duration_pb2.Duration] # Detour caused by this visit
291
shipment_label: str # Label of visited shipment
292
visit_label: str # Label of this visit
293
294
class Transition:
295
travel_duration: Optional[duration_pb2.Duration] # Travel time
296
travel_distance_meters: float # Travel distance
297
traffic_info_unavailable: bool # Whether traffic info was available
298
delay_duration: Optional[duration_pb2.Duration] # Traffic delays
299
break_duration: Optional[duration_pb2.Duration] # Break time during transition
300
wait_duration: Optional[duration_pb2.Duration] # Wait time
301
total_duration: Optional[duration_pb2.Duration] # Total transition duration
302
start_time: Optional[timestamp_pb2.Timestamp] # Transition start time
303
vehicle_loads: Mapping[str, ShipmentRoute.VehicleLoad] # Vehicle loads
304
route_polyline: Optional[ShipmentRoute.EncodedPolyline] # Transition polyline
305
306
class VehicleLoad:
307
amount: int # Load amount
308
309
class EncodedPolyline:
310
value: str # Encoded polyline string
311
312
class Break:
313
start_time: Optional[timestamp_pb2.Timestamp] # Break start time
314
duration: Optional[duration_pb2.Duration] # Break duration
315
```
316
317
### InjectedSolutionConstraint
318
319
```python { .api }
320
class InjectedSolutionConstraint:
321
routes: Sequence[ShipmentRoute] # Routes to inject as constraints
322
constraint_relaxations: Sequence[InjectedSolutionConstraint.ConstraintRelaxation] # Relaxation settings
323
324
class ConstraintRelaxation:
325
relaxations: Sequence[InjectedSolutionConstraint.ConstraintRelaxation.Relaxation] # Individual relaxations
326
vehicle_indices: Sequence[int] # Vehicles to apply relaxations to
327
328
class Relaxation:
329
level: InjectedSolutionConstraint.ConstraintRelaxation.Relaxation.Level # Relaxation level
330
threshold_time: Optional[timestamp_pb2.Timestamp] # Time threshold
331
threshold_visit_count: int # Visit count threshold
332
333
class Level(enum.Enum):
334
LEVEL_UNSPECIFIED = 0
335
RELAX_VISIT_TIMES_AFTER_THRESHOLD = 1 # Relax visit times
336
RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD = 2 # Relax times and sequence
337
RELAX_ALL_AFTER_THRESHOLD = 3 # Relax all constraints
338
```