Package google.maps.routeoptimization.v1

索引

RouteOptimization

一种用于优化车辆行程的服务。

某些类型的字段的有效性:

  • google.protobuf.Timestamp
    • 时间采用 Unix 时间:自 1970-01-01T00:00:00+00:00 以来的秒数。
    • 秒必须采用 [0, 253402300799] 格式,例如 [1970-01-01T00:00:00+00:00, 9999-12-31T23:59:59+00:00]。
    • nanos 必须取消设置或设置为 0。
  • google.protobuf.Duration
    • 秒必须采用 [0, 253402300799] 格式,例如 [1970-01-01T00:00:00+00:00, 9999-12-31T23:59:59+00:00]。
    • nanos 必须取消设置或设置为 0。
  • google.type.LatLng
    • 纬度必须在 [-90.0, 90.0] 内。
    • 经度必须采用 [-180.0, 180.0] 格式。
    • 纬度和经度必须至少有一个为非零。
BatchOptimizeTours

rpc BatchOptimizeTours(BatchOptimizeToursRequest) returns (Operation)

批量优化一条或多条 OptimizeToursRequest 消息的车辆游览体验。

此方法是一种长时间运行的操作 (LRO)。用于优化的输入(OptimizeToursRequest 消息)和输出(OptimizeToursResponse 消息)以用户指定的格式在 Cloud Storage 中读取/写入。与 OptimizeTours 方法一样,每个 OptimizeToursRequest 包含一个 ShipmentModel 并返回一个包含 ShipmentRouteOptimizeToursResponse,后者是一组由车辆执行的路线,可将总费用降至最低。

授权范围

需要以下 OAuth 范围:

  • https://www.googleapis.com/auth/cloud-platform
OptimizeTours

rpc OptimizeTours(OptimizeToursRequest) returns (OptimizeToursResponse)

发送包含 ShipmentModelOptimizeToursRequest,并返回包含 ShipmentRouteOptimizeToursResponse,这是一组由车辆执行的路线,可将总费用降至最低。

ShipmentModel 模型主要由需要执行的 Shipment 和可用于传输 ShipmentVehicle 组成。ShipmentRoute 会将 Shipment 分配给 Vehicle。更具体地说,它们为每辆车分配了一系列 Visit,其中 Visit 对应于 VisitRequest,即 Shipment 的取货或送货服务。

目标是为 Vehicle 分配 ShipmentRoute,从而最大限度地降低总费用,因为 ShipmentModel 中定义了许多组件。

授权范围

需要以下 OAuth 范围:

  • https://www.googleapis.com/auth/cloud-platform

AggregatedMetrics

ShipmentRoute(代表所有 Transition 和/或 Visit(代表所有 ShipmentRoute)元素的 OptimizeToursResponse)的汇总指标。

字段
performed_shipment_count

int32

执行的运单次数。请注意,取货和送货对只计算一次。

travel_duration

Duration

路线或解决方案的总行程时长。

wait_duration

Duration

路由或解决方案的总等待时长。

delay_duration

Duration

路由或解决方案的总延迟时长。

break_duration

Duration

路由或解决方案的总中断时长。

visit_duration

Duration

路线或解决方案的总访问时长。

total_duration

Duration

总时长应等于上述所有时长的总和。对于路线,它还对应于:

[ShipmentRoute.vehicle_end_time][google.maps.routeoptimization.v1.ShipmentRoute.vehicle_end_time] - [ShipmentRoute.vehicle_start_time][google.maps.routeoptimization.v1.ShipmentRoute.vehicle_start_time]
travel_distance_meters

double

路线或解决方案的总行程距离。

max_loads

map<string, VehicleLoad>

针对该路线上的每一个数量(响应解决方案),在整个路线上实现的最大负载(响应解决方案),根据所有Transition.vehicle_loads (resp.ShipmentRoute.metrics.max_loads

BatchOptimizeToursMetadata

此类型没有字段。

BatchOptimizeToursRequest 调用的操作元数据。

BatchOptimizeToursRequest

请求以异步操作的形式批量优化游览。每个输入文件应包含一个 OptimizeToursRequest,每个输出文件将包含一个 OptimizeToursResponse。该请求包含用于读取/写入和解析文件的信息。所有输入和输出文件都应位于同一项目下。

字段
parent

string

必需。定位项目和位置以进行呼叫。

格式:* projects/{project-id} * projects/{project-id}/locations/{location-id}

如果未指定位置,系统会自动选择区域。

model_configs[]

AsyncModelConfig

必需。每个购买模型的输入/输出信息,例如文件路径和数据格式。

AsyncModelConfig

用于异步解决一个优化模型的信息。

字段
display_name

string

可选。用户定义的模型名称,用户可以将其用作别名来跟踪模型。

input_config

InputConfig

必需。输入模型的相关信息。

output_config

OutputConfig

必需。所需的输出位置信息。

BatchOptimizeToursResponse

此类型没有字段。

BatchOptimizeToursRequest 的响应。操作完成后,该操作将在长时间运行的操作中返回。

BreakRule

用于生成车辆休息时间的规则(例如午餐时间)。休息是一个连续时间段,在此期间,车辆会停留在当前位置,无法执行任何造访操作。在以下情况下可能会中断:

  • 在两次访问之间间隔的时间(包括访问之前或之后,但不在访问过程中的时间),在这种情况下,它会延长两次访问之间的相应运送时间,
  • 或车辆开始前(车辆可能不会在休息期间启动),在这种情况下,启动时间不影响车辆的启动时间。
  • 或在车辆结束之后(同上,显示车辆结束时间)。
字段
break_requests[]

BreakRequest

插播时间点的顺序。请参阅 BreakRequest 消息。

frequency_constraints[]

FrequencyConstraint

可能需要支付多个FrequencyConstraint。它们必须都满足此 BreakRuleBreakRequest。请参阅 FrequencyConstraint

BreakRequest

您必须事先知道适用于每辆车的插播时间点顺序(即其数量和顺序)。重复的 BreakRequest 会按照必须出现的先后顺序定义该序列。它们的时间范围 (earliest_start_time / latest_start_time) 可以重叠,但必须与订单兼容(已勾选)。

字段
earliest_start_time

Timestamp

必需。广告插播时间点开始处的下限(含边界值)。

latest_start_time

Timestamp

必需。插播时间点开始时的上限(含边界值)。

min_duration

Duration

必需。广告插播时长下限。必须为正值。

FrequencyConstraint

可以通过强制设定最小广告插播频率(例如“每 12 小时至少有 1 小时的广告插播时间”),进一步限制上述广告插播的频率和时长。假设这可解释为“在 12 小时的任何滑动时间段内,必须至少有一次休息时间至少一小时”,该示例可转换为以下 FrequencyConstraint

{
   min_break_duration { seconds: 3600 }         # 1 hour.
   max_inter_break_duration { seconds: 39600 }  # 11 hours (12 - 1 = 11).
}

除了 BreakRequest 中已指定的时间范围和最短时长之外,解决方案中插播时间点的时间和时长将遵循所有此类约束条件。

在实践中,FrequencyConstraint 可能适用于不连续的插播时间点。例如,以下时间表将遵循“每 12 小时 1 小时”这一设置示例:

  04:00 vehicle start
   .. performing travel and visits ..
  09:00 1 hour break
  10:00 end of the break
   .. performing travel and visits ..
  12:00 20-min lunch break
  12:20 end of the break
   .. performing travel and visits ..
  21:00 1 hour break
  22:00 end of the break
   .. performing travel and visits ..
  23:59 vehicle end
字段
min_break_duration

Duration

必需。此限制条件的最短广告插播时长。非负数。请参阅 FrequencyConstraint 的说明。

max_inter_break_duration

Duration

必需。路线中至少部分间隔 duration >= min_break_duration 内的任何时间段的允许跨度上限。必须为正值。

DataFormat

输入和输出文件的数据格式。

枚举
DATA_FORMAT_UNSPECIFIED 值无效,格式不能为 UNSPECIFIED。
JSON JavaScript 对象表示法。
PROTO_TEXT Protocol Buffers 文本格式。请参阅 https://protobuf.dev/reference/protobuf/textformat-spec/

DistanceLimit

定义可行驶的最大距离的限制。它可以是硬性质的,也可以是软的。

如果定义了软性限制,则必须将 soft_max_meterscost_per_kilometer_above_soft_max 都定义为非负数。

字段
max_meters

int64

将距离限制为不超过 max_meters 的硬性限制。上限必须是非负数。

soft_max_meters

int64

不强制执行最大距离限制的软性限制,但如果违反,则产生的费用将与模型中定义的其他费用相加,且单位相同。

如果定义的 soft_max_meters 必须小于 max_meters,并且必须为非负数。

cost_per_kilometer_above_soft_max

double

如果距离超过 soft_max_meters 的上限,则产生的每公里费用。如果距离低于上限,则额外费用为 0,否则用于计算费用的公式如下所示:

  (distance_meters - soft_max_meters) / 1000.0 *
  cost_per_kilometer_above_soft_max.

费用必须是非负数。

GcsDestination

将写入输出文件的 Google Cloud Storage 位置。

字段
uri

string

必需。Google Cloud Storage URI。

GcsSource

将读取输入文件的 Google Cloud Storage 位置。

字段
uri

string

必需。Google Cloud Storage 对象的 URI,格式为 gs://bucket/path/to/object

InjectedSolutionConstraint

请求中注入的解决方案,包括有关必须限制哪些访问以及如何限制访问的信息。

字段
routes[]

ShipmentRoute

要注入的解决方案的路径。原始解决方案中可能会省略某些路由。路线和跳过的运单必须满足针对injected_first_solution_routes列出的基本有效性假设。

skipped_shipments[]

SkippedShipment

跳过了运送要注入的解决方案。某些可能从原始解决方案中省略。请参阅 routes 字段。

constraint_relaxations[]

ConstraintRelaxation

对于零组或多组车辆,指定放宽约束的时机和程度。如果此字段为空,则所有非空车辆路线都将完全约束。

ConstraintRelaxation

对于一组车辆,指定在什么阈值对访问限制放宽以及到什么级别。skipped_shipment 字段中列出的运单只能跳过;也就是说,它们无法执行。

字段
relaxations[]

Relaxation

所有访问限制放宽,将应用于 vehicle_indices 中有交通工具的路线访问。

vehicle_indices[]

int32

指定访问限制条件 relaxations 适用的车辆索引。如果为空,则会被视为默认值,并且 relaxations 适用于未在其他 constraint_relaxations 中指定的所有车辆。最多只能有一个默认值,即最多只允许有一个约束放宽字段为空 vehicle_indices。一个车辆索引只能列出一次,即使在多个 constraint_relaxations 中也是如此。

如果 interpret_injected_solutions_using_labels 为 true,则车辆索引与 ShipmentRoute.vehicle_index 的映射方式相同(请参阅 fields 注释)。

娱乐

如果 relaxations 为空,则 routes 上所有访问的开始时间和顺序将受到完全限制,并且不得在这些路线中插入或添加新的访问。此外,车辆的开始时间和结束时间在 routes 中是完全受限的,除非车辆是空的(即没有到访记录且在模型中将 used_if_route_is_empty 设置为 false)。

relaxations(i).level 指定应用于满足以下条件的访问 #j 的限制条件放宽级别:

  • route.visits(j).start_time >= relaxations(i).threshold_time
  • j + 1 >= relaxations(i).threshold_visit_count

同样,如果满足以下条件,车辆的启动时间会放宽为 relaxations(i).level

  • vehicle_start_time >= relaxations(i).threshold_time
  • relaxations(i).threshold_visit_count == 0,且车辆端在满足以下条件时放宽为 relaxations(i).level
  • vehicle_end_time >= relaxations(i).threshold_time
  • route.visits_size() + 1 >= relaxations(i).threshold_visit_count

如需在访问符合 threshold_visit_countthreshold_time 的情况下应用放松级别,请添加两个具有相同 levelrelaxations:一个仅设置了 threshold_visit_count,另一个仅设置了 threshold_time。如果访问满足多个 relaxations 的条件,则应用最宽松的级别。因此,从车辆启动到路线访问,一直到车辆结束,放松级别将变得更宽松:即,放松级别不会随着路线的推进而减少。

不符合任何 relaxations 阈值条件的路线访问的时间和顺序都是完全限制的,不得将任何到访插入这些序列中。此外,如果车辆的开始或结束不符合任何放松条件,相应时间便会固定,除非车辆为空。

字段
level

Level

在满足 threshold_time 或之后的条件且至少为 threshold_visit_count 时应用的约束放宽级别。

threshold_time

Timestamp

可以应用放宽 level 的时间或之后。

threshold_visit_count

int32

达到或超过该次数后,系统可能会应用放宽 level。如果 threshold_visit_count 为 0(或未设置),则可在车辆启动时直接应用 level

如果值为 route.visits_size() + 1,则 level 可能仅适用于车辆端。如果超过 route.visits_size() + 1,则 level 完全不会应用于该路线。

级别

表示应用于访问和后续访问满足阈值条件时应用的不同约束放宽级别。

以下枚举按增加放松程度的顺序排列。

枚举
LEVEL_UNSPECIFIED

隐式默认放宽级别:没有放宽限制,即所有访问都完全受限。

不得在 level 中明确使用此值。

RELAX_VISIT_TIMES_AFTER_THRESHOLD 访问开始时间和车辆开始/结束时间将放宽,但每次访问仍绑定到同一辆车,并且必须遵守访问顺序:在它们之间或之前不能插入任何访问。
RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD RELAX_VISIT_TIMES_AFTER_THRESHOLD 相同,但访问顺序也放宽:访问仍然仅绑定到其车辆。
RELAX_ALL_AFTER_THRESHOLD RELAX_VISIT_TIMES_AND_SEQUENCE_AFTER_THRESHOLD 相同,但车辆也很放松:在阈值时间当天或之后访问完全免费,并且可能无法正常运行。

InputConfig

为 [BatchOptimizeTours][google.maps.routeoptimization.v1.RouteOptimizationService.BatchOptimizeTours] 指定输入。

字段
data_format

DataFormat

必需。输入数据格式。

联合字段 source。必需。source 只能是下列其中一项:
gcs_source

GcsSource

Google Cloud Storage 位置。此项目必须是单个对象(文件)。

位置

封装位置(地理点和可选标题)。

字段
lat_lng

LatLng

航点的地理坐标。

heading

int32

与交通流动方向相关联的罗盘航向。此值用于指定上车点和下车点的公路一侧。方位值的范围为 0 到 360,其中 0 指定正北方位,90 指定正北方方向,依此类推。

OptimizeToursRequest

请求提供给游览优化求解器,该求解器定义了要求解的运单模型以及优化参数。

字段
parent

string

必需。请定位到项目或位置以拨打电话。

格式:* projects/{project-id} * projects/{project-id}/locations/{location-id}

如果未指定位置,系统会自动选择区域。

timeout

Duration

如果设置了此超时,服务器将在超时期限已过或同步请求的服务器截止时间之前(以时间较早者为准)返回响应。

对于异步请求,服务器会在超时过去之前生成解决方案(如果可能)。

model

ShipmentModel

要解决的配送模式。

solving_mode

SolvingMode

默认情况下,解析模式为 DEFAULT_SOLVE (0)。

search_mode

SearchMode

用于解决请求的搜索模式。

injected_first_solution_routes[]

ShipmentRoute

指导优化算法找到与先前解决方案类似的首个解决方案。

构建第一个解决方案时,模型会受到限制。第一个解决方案中会隐式跳过未在路线上执行的任何运送,但它们可能会在后续解决方案中执行。

此解决方案必须满足一些基本的有效性假设:

  • 对于所有路线,vehicle_index 必须在范围内且不重复。
  • 对于所有访问,shipment_indexvisit_request_index 必须在范围内。
  • 只能引用一条航线。
  • 必须在发货前执行自提配送操作。
  • 只能为一件商品提供一种备选自提方式或一种备选方式的配送方式。
  • 所有路线的用时都会增加(即vehicle_start_time <= visits[0].start_time <= visits[1].start_time ... <= vehicle_end_time)。
  • 只能在允许的车辆上运送。如果 Shipment.allowed_vehicle_indices 为空或其 vehicle_index 包含在 Shipment.allowed_vehicle_indices 中,则允许车辆通行。

如果注入的解决方案不可行,不一定会返回验证错误,而是可能会返回指示不可行的错误。

injected_solution_constraint

InjectedSolutionConstraint

限制优化算法以找到与先前解决方案类似的最终解决方案。例如,这可用于冻结已完成或即将完成但不得修改的路线部分。

如果注入的解决方案不可行,不一定会返回验证错误,而是可能会返回指示不可行的错误。

refresh_details_routes[]

ShipmentRoute

如果不为空,则将刷新给定路线,而不修改其基本访问顺序或行程时间:仅更新其他详细信息。这无法解决模型问题。

自 2020 年 11 月起,此方法仅会填充非空路线的多段线,并要求 populate_polylines 为 true。

传入路由的 route_polyline 字段可能与路由 transitions 不一致。

此字段不得与 injected_first_solution_routesinjected_solution_constraint 一起使用。

Shipment.ignoreVehicle.ignore 对此行为没有影响。无论相关货运或车辆是否被忽略,所有非空路线中的所有访问之间仍会填充多段线。

interpret_injected_solutions_using_labels

bool

如果为 true:

这种解释适用于 injected_first_solution_routesinjected_solution_constraintrefresh_details_routes 字段。如果请求中的运单或车辆索引自解决方案创建后发生了变化(可能是因为运单或车辆已从该请求中移除或添加到该请求中),则可以使用此参数。

如果为 true,以下类别中的标签必须在其类别中最多出现一次:

如果注入的解决方案中的 vehicle_label 与请求车辆不对应,则系统会从解决方案中移除相应的路线及其到访记录。如果注入的解决方案中的 shipment_label 与运单请求不相符,系统会从解决方案中移除相应的访问。如果注入的解决方案中的 SkippedShipment.label 与运单请求不对应,系统会从解决方案中移除 SkippedShipment

从注入的解决方案中移除路线访问或整个路线可能会影响隐含的约束条件,这可能会导致解决方案发生变化、验证错误或不可行性。

注意:调用方必须确保每个 Vehicle.label (resp.Shipment.label)可唯一标识下列两个相关请求中使用的车辆(响应运单)实体:生成了注入解决方案中使用的 OptimizeToursResponse 的过往请求,以及包含注入解决方案的当前请求。上述唯一性检查不足以保证此要求。

consider_road_traffic

bool

在计算 ShipmentRoute 字段 Transition.travel_durationVisit.start_timevehicle_end_time 时考虑流量估算;设置 ShipmentRoute.has_traffic_infeasibilities 字段,以及计算 OptimizeToursResponse.total_cost 字段。

populate_polylines

bool

如果为 true,将在响应 ShipmentRoute 中填充多段线。

populate_transition_polylines

bool

如果为 true,将在响应 ShipmentRoute.transitions 中填充多段线。

allow_large_deadline_despite_interruption_risk

bool

如果设置此属性,则请求的截止时间(请参阅 https://grpc.io/blog/deadlines)最长为 60 分钟。否则,最长期限只有 30 分钟。请注意,长期请求存在的中断风险要大得多(但也很小)。

use_geodesic_distances

bool

如果为 true,系统将使用测地距离(而非 Google 地图距离)计算行程距离,并使用由 geodesic_meters_per_second 定义的速度的测地距离计算行程时间。

label

string

可用于识别此请求的标签,会在 OptimizeToursResponse.request_label 中报告。

geodesic_meters_per_second

double

use_geodesic_distances 为 true 时,必须设置此字段并定义用于计算行程时间的速度。其值必须至少为 1.0 米/秒。

max_validation_errors

int32

截断返回的验证错误数。这些错误通常作为 BadRequest 错误详情 (https://cloud.google.com/apis/design/errors#error_details) 附加到 INVALID_ARGUMENT 错误载荷中,除非 Solve_mode=VALIDATE_ONLY: 请参阅 OptimizeToursResponse.validation_errors 字段。默认值为 100,上限为 10,000。

SearchMode

用于定义搜索行为的模式,在延迟时间与解决方案质量之间进行权衡。在所有模式下,都会强制执行全局请求截止时间。

枚举
SEARCH_MODE_UNSPECIFIED 未指定的搜索模式,相当于 RETURN_FAST
RETURN_FAST 找到第一个好的解决方案后,停止搜索。
CONSUME_ALL_AVAILABLE_TIME 请充分利用所有时间来寻找更好的解决方案。

SolvingMode

定义求解器应如何处理请求。在除 VALIDATE_ONLY 以外的所有模式下,如果请求无效,您会收到 INVALID_REQUEST 错误。请参阅 max_validation_errors 以限制返回的错误数。

枚举
DEFAULT_SOLVE 解模型。
VALIDATE_ONLY 仅验证模型而不解决问题:填充尽可能多的 OptimizeToursResponse.validation_errors
DETECT_SOME_INFEASIBLE_SHIPMENTS

仅填充 OptimizeToursResponse.validation_errorsOptimizeToursResponse.skipped_shipments,不会实际解决请求的其余部分(响应中未设置 statusroutes)。如果检测到 injected_solution_constraint 路由中不可行,系统会将它们填充到 OptimizeToursResponse.validation_errors 字段中,并将 OptimizeToursResponse.skipped_shipments 留空。

重要提示:并非所有不可行的货物都会返回此处,只会返回在预处理过程中检测到不可行的货物。

OptimizeToursResponse

解决游览优化问题后给出的响应,其中包括每辆车所走的路线、跳过的运单以及解决方案的总体成本。

字段
routes[]

ShipmentRoute

为每辆车计算的路线;第 i-th 号路线对应于模型中的第 i 号交通工具。

request_label

string

OptimizeToursRequest.label 的副本(如果在请求中指定了标签)。

skipped_shipments[]

SkippedShipment

跳过的所有运单的列表。

validation_errors[]

OptimizeToursValidationError

我们能够单独检测到的所有验证错误的列表。请参阅“多个错误”OptimizeToursValidationError 消息的说明。

metrics

Metrics

此解决方案的时长、距离和用量指标。

指标

所有路由的汇总指标。

字段
aggregated_route_metrics

AggregatedMetrics

通过路由进行汇总。每个指标都是所有同名 ShipmentRoute.metrics 字段的总和(或负载最大值)。

skipped_mandatory_shipment_count

int32

跳过的强制性运单数。

used_vehicle_count

int32

使用的车辆数量。注意:如果车辆路线为空且 Vehicle.used_if_route_is_empty 为 true,则系统会认为车辆属于二手车。

earliest_vehicle_start_time

Timestamp

二手车最早的开始时间,根据 ShipmentRoute.vehicle_start_time 的所有二手车的最短时间计算得出。

latest_vehicle_end_time

Timestamp

二手车最晚结束时间,根据 ShipmentRoute.vehicle_end_time 的所有二手车的最大值计算得出。

costs

map<string, double>

解决方案费用,按与费用相关的请求字段细分。键是相对于输入 OptimizationToursRequest 的 proto 路径,例如:"model.shipments.pickups.cost",这些值是相应费用字段生成的总费用,汇总到整个解决方案中。换句话说,cost["model.shipments.pickups.cost"] 是解决方案的所有提货费用的总和。模型中定义的所有费用均在此处详细报告,但与 TransitionAttributes 相关的费用自 2022 年 1 月起仅以汇总方式报告。

total_cost

double

解决方案的总费用。费用映射中所有值的总和。

OptimizeToursValidationError

描述验证 OptimizeToursRequest 时遇到的错误。

字段
code

int32

验证错误由始终存在的对 (code, display_name) 定义。

其他字段(见下文)提供了有关此错误的更多背景信息。

多个错误:如果存在多个错误,验证流程会尝试输出多个错误。这是一个不完美的过程,就像编译器一样。有些验证错误是“严重”错误,也就是说,它们会停止整个验证流程。display_name="UNSPECIFIED" 错误就属于这种情况。有些可能会导致验证流程跳过其他错误。

STABILITYcodedisplay_name 应非常稳定。但是,随着时间的推移,可能会出现新的代码和显示名称,这可能会导致某个给定(无效)的请求生成不同的 (codedisplay_name) 对,因为新错误隐藏了旧错误(请参阅“多个错误”)。

REFERENCE:所有 (code, name) 对的列表:

  • 未指定 = 0;
  • VALIDATION_TIMEOUT_ERROR = 10;无法在期限内完成验证。
  • REQUEST_OPTIONS_ERROR = 12;

    • REQUEST_OPTIONS_INVALID_SOLVING_MODE = 1201;
    • REQUEST_OPTIONS_INVALID_MAX_VALIDATION_ERRORS = 1203;
    • REQUEST_OPTIONS_INVALID_GEODESIC_METERS_PER_SECOND = 1204;
    • REQUEST_OPTIONS_GEODESIC_METERS_PER_SECOND_TOO_SMALL = 1205;
    • REQUEST_OPTIONS_MISSING_GEODESIC_METERS_PER_SECOND = 1206;
    • REQUEST_OPTIONS_POPULATE_PATHFINDER_TRIPS_AND_GEODESIC_DISTANCE = 1207;
    • REQUEST_OPTIONS_COST_MODEL_OPTIONS_AND_GEODESIC_DISTANCE = 1208;
    • REQUEST_OPTIONS_TRAVEL_MODE_INCOMPATIBLE_WITH_TRAFFIC = 1211;
    • REQUEST_OPTIONS_MULTIPLE_TRAFFIC_FLAVORS = 1212;
    • REQUEST_OPTIONS_INVALID_TRAFFIC_FLAVOR = 1213;
    • REQUEST_OPTIONS_TRAFFIC_ENABLED_WITHOUT_GLOBAL_START_TIME = 1214;
    • REQUEST_OPTIONS_TRAFFIC_ENABLED_WITH_PRECEDENCES = 1215;
    • REQUEST_OPTIONS_TRAFFIC_PREFILL_MODE_INVALID = 1216;
    • REQUEST_OPTIONS_TRAFFIC_PREFILL_ENABLED_WITHOUT_TRAFFIC = 1217;
  • INJECTED_SOLUTION_ERROR = 20; <ph type="x-smartling-placeholder">
      </ph>
    • INJECTED_SOLUTION_MISSING_LABEL = 2000;
    • INJECTED_SOLUTION_DUPLICATE_LABEL = 2001;
    • INJECTED_SOLUTION_AMBIGUOUS_INDEX = 2002;
    • INJECTED_SOLUTION_INFEASIBLE_REMAINING_GETTING_TRAVEL_TIMES = 2003;
    • INJECTED_SOLUTION_TRANSITION_INCONSISTENT_WITH_ACTUAL_TRAVEL = 2004;
    • INJECTED_SOLUTION_CONCURRENT_SOLUTION_TYPES = 2005;
    • INJECTED_SOLUTION_MORE_THAN_ONE_PER_TYPE = 2006;
    • INJECTED_SOLUTION_REFRESH_WITHOUT_POPULATE = 2008;
    • INJECTED_SOLUTION_CONSTRAINED_ROUTE_PORTION_INFEASIBLE = 2010;
  • SHIPMENT_MODEL_ERROR = 22; <ph type="x-smartling-placeholder">
      </ph>
    • SHIPMENT_MODEL_TOO_LARGE = 2200;
    • SHIPMENT_MODEL_TOO_MANY_CAPACITY_TYPES = 2201;
    • SHIPMENT_MODEL_GLOBAL_START_TIME_NEGATIVE_OR_NAN = 2202;
    • SHIPMENT_MODEL_GLOBAL_END_TIME_TOO_LARGE_OR_NAN = 2203;
    • SHIPMENT_MODEL_GLOBAL_START_TIME_AFTER_GLOBAL_END_TIME = 2204;
    • SHIPMENT_MODEL_GLOBAL_DURATION_TOO_LONG = 2205;
    • SHIPMENT_MODEL_MAX_ACTIVE_VEHICLES_NOT_POSITIVE = 2206;
    • SHIPMENT_MODEL_DURATION_MATRIX_TOO_LARGE = 2207;
  • INDEX_ERROR = 24;
  • TAG_ERROR = 26;
  • TIME_WINDOW_ERROR = 28; <ph type="x-smartling-placeholder">
      </ph>
    • TIME_WINDOW_INVALID_START_TIME = 2800;
    • TIME_WINDOW_INVALID_END_TIME = 2801;
    • TIME_WINDOW_INVALID_SOFT_START_TIME = 2802;
    • TIME_WINDOW_INVALID_SOFT_END_TIME = 2803;
    • TIME_WINDOW_OUTSIDE_GLOBAL_TIME_WINDOW = 2804;
    • TIME_WINDOW_START_TIME_AFTER_END_TIME = 2805;
    • TIME_WINDOW_INVALID_COST_PER_HOUR_BEFORE_SOFT_START_TIME = 2806;
    • TIME_WINDOW_INVALID_COST_PER_HOUR_AFTER_SOFT_END_TIME = 2807;
    • TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_WITHOUT_SOFT_START_TIME = 2808;
    • TIME_WINDOW_COST_REMAINING_SOFT_END_TIME_WITHOUT_SOFT_END_TIME = 2809;
    • TIME_WINDOW_SOFT_START_TIME_WITHOUT_COST_BEFORE_SOFT_START_TIME = 2810;
    • TIME_WINDOW_SOFT_END_TIME_WITHOUT_COST_REMAINING_SOFT_END_TIME = 2811;
    • TIME_WINDOW_OVERLAPPING_ADJACENT_OR_EARLIER_THAN_PREVIOUS = 2812;
    • TIME_WINDOW_START_TIME_AFTER_SOFT_START_TIME = 2813;
    • TIME_WINDOW_SOFT_START_TIME_AFTER_END_TIME = 2814;
    • TIME_WINDOW_START_TIME_REMAINING_SOFT_END_TIME = 2815;
    • TIME_WINDOW_SOFT_END_TIME_AFTER_END_TIME = 2816;
    • TIME_WINDOW_COST_BEFORE_SOFT_START_TIME_SET_AND_MULTIPLE_WINDOWS = 2817;
    • TIME_WINDOW_COST_REMAINING_SOFT_END_TIME_SET_AND_MULTIPLE_WINDOWS = 2818;
    • TRANSITION_ATTRIBUTES_ERROR = 30;
    • TRANSITION_ATTRIBUTES_INVALID_COST = 3000;
    • TRANSITION_ATTRIBUTES_INVALID_COST_PER_KILOMETER = 3001;
    • TRANSITION_ATTRIBUTES_DUPLICATE_TAG_PAIR = 3002;
    • TRANSITION_ATTRIBUTES_DISTANCE_LIMIT_MAX_METERS_UNSUPPORTED = 3003;
    • TRANSITION_ATTRIBUTES_UNSPECIFIED_SOURCE_TAGS = 3004;
    • TRANSITION_ATTRIBUTES_CONFLICTING_SOURCE_TAGS_FIELDS = 3005;
    • TRANSITION_ATTRIBUTES_UNSPECIFIED_DESTINATION_TAGS = 3006;
    • TRANSITION_ATTRIBUTES_CONFLICTING_DESTINATION_TAGS_FIELDS = 3007;
    • TRANSITION_ATTRIBUTES_DELAY_DURATION_NEGATIVE_OR_NAN = 3008;
    • TRANSITION_ATTRIBUTES_DELAY_DURATION_EXCEEDS_GLOBAL_DURATION = 3009;
  • AMOUNT_ERROR = 31; <ph type="x-smartling-placeholder">
      </ph>
    • AMOUNT_NEGATIVE_VALUE = 3100;
  • LOAD_LIMIT_ERROR = 33; <ph type="x-smartling-placeholder">
      </ph>
    • LOAD_LIMIT_INVALID_COST_ABOVE_SOFT_MAX = 3303;
    • LOAD_LIMIT_SOFT_MAX_WITHOUT_COST_ABOVE_SOFT_MAX = 3304;
    • LOAD_LIMIT_COST_ABOVE_SOFT_MAX_WITHOUT_SOFT_MAX = 3305;
    • LOAD_LIMIT_NEGATIVE_SOFT_MAX = 3306;
    • LOAD_LIMIT_MIXED_DEMAND_TYPE = 3307;
    • LOAD_LIMIT_MAX_LOAD_NEGATIVE_VALUE = 3308;
    • LOAD_LIMIT_SOFT_MAX_ABOVE_MAX = 3309;
  • INTERVAL_ERROR = 34; <ph type="x-smartling-placeholder">
      </ph>
    • INTERVAL_MIN_EXCEEDS_MAX = 3401;
    • INTERVAL_NEGATIVE_MIN = 3402;
    • INTERVAL_NEGATIVE_MAX = 3403;
    • INTERVAL_MIN_EXCEEDS_CAPACITY = 3404;
    • INTERVAL_MAX_EXCEEDS_CAPACITY = 3405;
  • DISTANCE_LIMIT_ERROR = 36; <ph type="x-smartling-placeholder">
      </ph>
    • DISTANCE_LIMIT_INVALID_COST_REMAINING_SOFT_MAX = 3601;
    • DISTANCE_LIMIT_SOFT_MAX_WITHOUT_COST_REMAINING_SOFT_MAX = 3602;
    • DISTANCE_LIMIT_COST_REMAINING_SOFT_MAX_WITHOUT_SOFT_MAX = 3603;
    • DISTANCE_LIMIT_NEGATIVE_MAX = 3604;
    • DISTANCE_LIMIT_NEGATIVE_SOFT_MAX = 3605;
    • DISTANCE_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3606;
  • DURATION_LIMIT_ERROR = 38; <ph type="x-smartling-placeholder">
      </ph>
    • DURATION_LIMIT_MAX_DURATION_NEGATIVE_OR_NAN = 3800;
    • DURATION_LIMIT_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3801;
    • DURATION_LIMIT_INVALID_COST_PER_HOUR_AFTER_SOFT_MAX = 3802;
    • DURATION_LIMIT_SOFT_MAX_WITHOUT_COST_REMAINING_SOFT_MAX = 3803;
    • DURATION_LIMIT_COST_REMAINING_SOFT_MAX_WITHOUT_SOFT_MAX = 3804;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3805;
    • DURATION_LIMIT_INVALID_COST_REMAINING_QUADRATIC_SOFT_MAX = 3806;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_COST_PER_SQUARE_HOUR = 3807;
    • DURATION_LIMIT_COST_PER_SQUARE_HOUR_WITHOUT_QUADRATIC_SOFT_MAX = 3808;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_WITHOUT_MAX = 3809;
    • DURATION_LIMIT_SOFT_MAX_LARGER_THAN_MAX = 3810;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_LARGER_THAN_MAX = 3811;
    • DURATION_LIMIT_DIFF_BETWEEN_MAX_AND_QUADRATIC_SOFT_MAX_TOO_LARGE = 3812;
    • DURATION_LIMIT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3813;
    • DURATION_LIMIT_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3814;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_EXCEEDS_GLOBAL_DURATION = 3815;
  • SHIPMENT_ERROR = 40; <ph type="x-smartling-placeholder">
      </ph>
    • SHIPMENT_PD_LIMIT_WITHOUT_PICKUP_AND_DELIVERY = 4014;
    • SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_NEGATIVE_OR_NAN = 4000;
    • SHIPMENT_PD_ABSOLUTE_DETOUR_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4001;
    • SHIPMENT_PD_RELATIVE_DETOUR_LIMIT_INVALID = 4015;
    • SHIPMENT_PD_DETOUR_LIMIT_AND_EXTRA_VISIT_DURATION = 4016;
    • SHIPMENT_PD_TIME_LIMIT_DURATION_NEGATIVE_OR_NAN = 4002;
    • SHIPMENT_PD_TIME_LIMIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4003;
    • SHIPMENT_EMPTY_SHIPMENT_TYPE = 4004;
    • SHIPMENT_NO_PICKUP_NO_DELIVERY = 4005;
    • SHIPMENT_INVALID_PENALTY_COST = 4006;
    • SHIPMENT_ALLOWED_VEHICLE_INDEX_OUT_OF_BOUNDS = 4007;
    • SHIPMENT_DUPLICATE_ALLOWED_VEHICLE_INDEX = 4008;
    • SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITHOUT_INDEX = 4009;
    • SHIPMENT_INCONSISTENT_COST_FOR_VEHICLE_SIZE_WITH_INDEX = 4010;
    • SHIPMENT_INVALID_COST_FOR_VEHICLE = 4011;
    • SHIPMENT_COST_FOR_VEHICLE_INDEX_OUT_OF_BOUNDS = 4012;
    • SHIPMENT_DUPLICATE_COST_FOR_VEHICLE_INDEX = 4013;
  • VEHICLE_ERROR = 42; <ph type="x-smartling-placeholder">
      </ph>
    • VEHICLE_EMPTY_REQUIRED_OPERATOR_TYPE = 4200;
    • VEHICLE_DUPLICATE_REQUIRED_OPERATOR_TYPE = 4201;
    • VEHICLE_NO_OPERATOR_WITH_REQUIRED_OPERATOR_TYPE = 4202;
    • VEHICLE_EMPTY_START_TAG = 4203;
    • VEHICLE_DUPLICATE_START_TAG = 4204;
    • VEHICLE_EMPTY_END_TAG = 4205;
    • VEHICLE_DUPLICATE_END_TAG = 4206;
    • VEHICLE_EXTRA_VISIT_DURATION_NEGATIVE_OR_NAN = 4207;
    • VEHICLE_EXTRA_VISIT_DURATION_EXCEEDS_GLOBAL_DURATION = 4208;
    • VEHICLE_EXTRA_VISIT_DURATION_EMPTY_KEY = 4209;
    • VEHICLE_FIRST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4210;
    • VEHICLE_FIRST_SHIPMENT_IGNORED = 4211;
    • VEHICLE_FIRST_SHIPMENT_NOT_BOUND = 4212;
    • VEHICLE_LAST_SHIPMENT_INDEX_OUT_OF_BOUNDS = 4213;
    • VEHICLE_LAST_SHIPMENT_IGNORED = 4214;
    • VEHICLE_LAST_SHIPMENT_NOT_BOUND = 4215;
    • VEHICLE_IGNORED_WITH_USED_IF_ROUTE_IS_EMPTY = 4216;
    • VEHICLE_INVALID_COST_PER_KILOMETER = 4217;
    • VEHICLE_INVALID_COST_PER_HOUR = 4218;
    • VEHICLE_INVALID_COST_PER_TRAVELED_HOUR = 4219;
    • VEHICLE_INVALID_FIXED_COST = 4220;
    • VEHICLE_INVALID_TRAVEL_DURATION_MULTIPLE = 4221;
    • VEHICLE_TRAVEL_DURATION_MULTIPLE_WITH_SHIPMENT_PD_DETOUR_LIMITS = 4223;
    • VEHICLE_MATRIX_INDEX_WITH_SHIPMENT_PD_DETOUR_LIMITS = 4224;
    • VEHICLE_MINIMUM_DURATION_LONGER_THAN_DURATION_LIMIT = 4222;
  • VISIT_REQUEST_ERROR = 44; <ph type="x-smartling-placeholder">
      </ph>
    • VISIT_REQUEST_EMPTY_TAG = 4400;
    • VISIT_REQUEST_DUPLICATE_TAG = 4401;
    • VISIT_REQUEST_DURATION_NEGATIVE_OR_NAN = 4404;
    • VISIT_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4405;
  • PRECEDENCE_ERROR = 46;
  • BREAK_ERROR = 48; <ph type="x-smartling-placeholder">
      </ph>
    • BREAK_RULE_EMPTY = 4800;
    • BREAK_REQUEST_UNSPECIFIED_DURATION = 4801;
    • BREAK_REQUEST_UNSPECIFIED_EARLIEST_START_TIME = 4802;
    • BREAK_REQUEST_UNSPECIFIED_LATEST_START_TIME = 4803;
    • BREAK_REQUEST_DURATION_NEGATIVE_OR_NAN = 4804;= 4804;
    • BREAK_REQUEST_LATEST_START_TIME_BEFORE_EARLIEST_START_TIME = 4805;
    • BREAK_REQUEST_EARLIEST_START_TIME_BEFORE_GLOBAL_START_TIME = 4806;
    • BREAK_REQUEST_LATEST_END_TIME_AFTER_GLOBAL_END_TIME = 4807;
    • BREAK_REQUEST_NON_SCHEDULABLE = 4808;
    • BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_NEGATIVE_OR_NAN = 4809;
    • BREAK_FREQUENCY_MIN_BREAK_DURATION_NEGATIVE_OR_NAN = 4810;
    • BREAK_FREQUENCY_MIN_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION = 4811;
    • BREAK_FREQUENCY_MAX_INTER_BREAK_DURATION_EXCEEDS_GLOBAL_DURATION = 4812;
    • BREAK_REQUEST_DURATION_EXCEEDS_GLOBAL_DURATION = 4813;
    • BREAK_FREQUENCY_MISSING_MAX_INTER_BREAK_DURATION = 4814;
    • BREAK_FREQUENCY_MISSING_MIN_BREAK_DURATION = 4815;
  • SHIPMENT_TYPE_INCOMPATIBILITY_ERROR = 50; <ph type="x-smartling-placeholder">
      </ph>
    • SHIPMENT_TYPE_INCOMPATIBILITY_EMPTY_TYPE = 5001;
    • SHIPMENT_TYPE_INCOMPATIBILITY_LESS_THAN_TWO_TYPES = 5002;
    • SHIPMENT_TYPE_INCOMPATIBILITY_DUPLICATE_TYPE = 5003;
    • SHIPMENT_TYPE_INCOMPATIBILITY_INVALID_INCOMPATIBILITY_MODE = 5004;
    • SHIPMENT_TYPE_INCOMPATIBILITY_TOO_MANY_INCOMPATIBILITY = 5005;
  • SHIPMENT_TYPE_REQUIREMENT_ERROR = 52; <ph type="x-smartling-placeholder">
      </ph>
    • SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE = 52001;
    • SHIPMENT_TYPE_REQUIREMENT_NO_DEPENDENT_TYPE = 52002;
    • SHIPMENT_TYPE_REQUIREMENT_INVALID_REQUIREMENT_MODE = 52003;
    • SHIPMENT_TYPE_REQUIREMENT_TOO_MANY_REQUIREMENTS = 52004;
    • SHIPMENT_TYPE_REQUIREMENT_EMPTY_REQUIRED_TYPE = 52005;
    • SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_REQUIRED_TYPE = 52006;
    • SHIPMENT_TYPE_REQUIREMENT_NO_REQUIRED_TYPE_FOUND = 52007;
    • SHIPMENT_TYPE_REQUIREMENT_EMPTY_DEPENDENT_TYPE = 52008;
    • SHIPMENT_TYPE_REQUIREMENT_DUPLICATE_DEPENDENT_TYPE = 52009;
    • SHIPMENT_TYPE_REQUIREMENT_SELF_DEPENDENT_TYPE = 52010;
    • SHIPMENT_TYPE_REQUIREMENT_GRAPH_HAS_CYCLES = 52011;
  • VEHICLE_OPERATOR_ERROR = 54; <ph type="x-smartling-placeholder">
      </ph>
    • VEHICLE_OPERATOR_EMPTY_TYPE = 5400;
    • VEHICLE_OPERATOR_MULTIPLE_START_TIME_WINDOWS = 5401;
    • VEHICLE_OPERATOR_SOFT_START_TIME_WINDOW = 5402;
    • VEHICLE_OPERATOR_MULTIPLE_END_TIME_WINDOWS = 5403;
    • VEHICLE_OPERATOR_SOFT_END_TIME_WINDOW = 5404;
  • DURATION_SECONDS_MATRIX_ERROR = 56; <ph type="x-smartling-placeholder">
      </ph>
    • DURATION_SECONDS_MATRIX_DURATION_NEGATIVE_OR_NAN = 5600;
    • DURATION_SECONDS_MATRIX_DURATION_EXCEEDS_GLOBAL_DURATION = 5601;
display_name

string

错误的显示名称。

fields[]

FieldReference

错误上下文可能涉及 0 个、1 个(大多数时候)或多个字段。例如,对于车辆 4 和运单 2 的首次取货,可以按如下方式完成:

fields { name: "vehicles" index: 4}
fields { name: "shipments" index: 2 sub_field {name: "pickups" index: 0} }

但请注意,对于给定的错误代码,fields 的基数不应发生变化。

error_message

string

用于描述错误的简单易懂的字符串。codeerror_message 之间存在 1 对 1 映射(如果代码 != "UNSPECIFIED")。

稳定性:不稳定:与给定 code 关联的错误消息可能会随时间而变化(希望加以澄清)。请改用 display_namecode

offending_values

string

可以包含字段的值。此功能不一定始终可用。您绝对不能依赖它,而只能将其用于手动模型调试。

FieldReference

指定验证错误的上下文。FieldReference 始终引用此文件中的给定字段,并采用相同的层次结构。例如,我们可以使用以下命令指定 5 号车辆的 start_time_windows 元素 2:

name: "vehicles" index: 5 sub_field { name: "end_time_windows" index: 2 }

不过,我们会省略 OptimizeToursRequestShipmentModel 等顶级实体,以避免造成消息拥挤。

字段
name

string

字段的名称,例如“vehicles”

sub_field

FieldReference

以递归方式嵌套子字段(如果需要)。

联合字段 index_or_key

index_or_key 只能是下列其中一项:

index

int32

字段的索引(如果重复)。

key

string

键(如果字段是映射)。

OutputConfig

为 [BatchOptimizeTours][google.maps.routeoptimization.v1.RouteOptimizationService.BatchOptimizeTours] 结果指定目的地。

字段
data_format

DataFormat

必需。输出数据格式。

联合字段 destination。必需。destination 只能是下列其中一项:
gcs_destination

GcsDestination

要向其中写入输出的 Google Cloud Storage 位置。

发货

单个商品的运单,从其一次自提到一次送货。要想视为已发货,专属车辆必须前往其中一个上车点(并相应减少其备用容量),然后前往某个送货地点(以便相应地重新增加其备用容量)。

字段
display_name

string

用户定义的运单显示名称。长度不得超过 63 个字符,且可以使用 UTF-8 字符。

pickups[]

VisitRequest

与运单关联的一组备选自提选项。如果未指定,车辆只需前往与送货相对应的地点。

deliveries[]

VisitRequest

与运单关联的一组备选配送方式。如果未指定,车辆只需前往与上车点相对应的位置。

load_demands

map<string, Load>

加载货物需求信息(例如重量、体积、托盘数量等)。映射中的键应该是描述相应加载类型的标识符,最好也包括单位。例如:“weight_kg”“volume_gallons”“pallet_count”等。如果给定键未出现在映射中,则相应的加载会被视为 null。

allowed_vehicle_indices[]

int32

可以履行此运单的一组车辆。如果留空,所有车辆都可以执行此操作。车辆由其在 ShipmentModelvehicles 列表中的索引指定。

costs_per_vehicle[]

double

指定每辆车交付此运单时产生的费用。如果指定,它必须具有以下 EITHER:

  • 元素数量与 costs_per_vehicle_indices 相同。costs_per_vehicle[i] 对应于模型的车辆 costs_per_vehicle_indices[i]
  • 元素数量与模型中车辆数量相同。第 i-th 元素对应于模型的第 #i 辆车。

这些费用的单位必须与“penalty_cost”相同,且不得为负数。如果没有此类费用,请将此字段留空。

costs_per_vehicle_indices[]

int32

costs_per_vehicle 所适用的车辆的索引。如果非空,则其元素数量必须与 costs_per_vehicle 相同。一个车辆索引只能指定一次。如果某个车辆已从 costs_per_vehicle_indices 中排除,则其费用为零。

pickup_to_delivery_absolute_detour_limit

Duration

指定与从自提到送餐的最短路径相比的最长绝对绕行时间。如果指定,则必须为非负数,并且运单中必须至少包含自提和送货信息。

例如,可以是从所选的自提备选方案直接到所选的备选配送方式所需的最短时间。然后,设置 pickup_to_delivery_absolute_detour_limit 会强制执行:

start_time(delivery) - start_time(pickup) <=
t + pickup_to_delivery_absolute_detour_limit

如果为同一批商品同时指定了相对限制和绝对限制,系统会对每个可能的自提/送货对使用更具限制性的限制。从 2017 年 10 月 10 日开始,仅当行程时长不取决于车辆时才支持绕行。

pickup_to_delivery_time_limit

Duration

指定从开始自提到开始配送的最长时长。如果指定,则必须为非负数,并且运单中必须至少包含自提和送货信息。这既不取决于为自提和配送选择的替代选项,也不取决于车辆速度。这可以与最大绕行约束条件一起指定:解决方案将同时遵循这两种规范。

shipment_type

string

指定“类型”的非空字符串。此功能可用于定义 shipment_types 之间的不兼容性或要求(请参阅 ShipmentModel 中的 shipment_type_incompatibilitiesshipment_type_requirements)。

与为单次访问指定的 visit_types 不同:属于同一运单的所有自取/配送都共用同一个 shipment_type

label

string

指定此运单的标签。此标签会在相应 ShipmentRoute.Visitshipment_label 的响应中报告。

ignore

bool

如果为 true,则跳过此运单,但不应用 penalty_cost

如果模型中存在任何 shipment_type_requirements,忽略运单会导致验证错误。

允许忽略在 injected_first_solution_routesinjected_solution_constraint 中执行的配送;求解器会从执行路线中移除相关的自提/送货访问信息。引用已忽略的运单的precedence_rules也会被忽略。

penalty_cost

double

如果未能完成运输,则此处罚将添加到路线的总费用中。如果使用了某个自提和配送备选方式,则视为配送已完成。费用可以用用于模型中所有其他费用相关字段的相同单位表示,并且必须为正值。

重要提示:如果未指定此处罚,则会被视为无限期,即必须完成发货。

pickup_to_delivery_relative_detour_limit

double

指定与从自提到送餐的最短路径相比的最长相对绕行时间。如果指定,则必须为非负数,并且运单中必须至少包含自提和送货信息。

例如,可以是从所选的自提备选方案直接到所选的备选配送方式所需的最短时间。然后,设置 pickup_to_delivery_relative_detour_limit 会强制执行:

start_time(delivery) - start_time(pickup) <=
std::ceil(t * (1.0 + pickup_to_delivery_relative_detour_limit))

如果为同一批商品同时指定了相对限制和绝对限制,系统会对每个可能的自提/送货对使用更具限制性的限制。从 2017 年 10 月 10 日开始,仅当行程时长不取决于车辆时才支持绕行。

加载

上门时,如果是上车点,则车辆装载量可能会增加预定义的金额;如果是送餐,则加上车辆负荷金额。此消息定义了此类金额。请参阅 load_demands

字段
amount

int64

执行相应访问的车辆的重量会有所不同。由于它是一个整数,因此建议用户选择适当的单位,以避免精度损失。必须大于或等于 0。

VisitRequest

可通过车辆完成的上门服务请求:请求具有地理位置(或两个,见下文)、开始和结束时间(以时间窗口表示)和服务持续时间(车辆在抵达取货或还车时所花的时间)。

字段
arrival_location

LatLng

执行此 VisitRequest 时,车辆抵达的地理位置。如果运单模型具有时长距离矩阵,则不得指定 arrival_location

arrival_waypoint

Waypoint

执行此 VisitRequest 时车辆到达的航点。如果运单模型具有时长距离矩阵,则不得指定 arrival_waypoint

departure_location

LatLng

完成此 VisitRequest 后,车辆离开的地理位置。如果与 arrival_location 相同,则可以省略。如果运单模型具有时长距离矩阵,则不得指定 departure_location

departure_waypoint

Waypoint

完成此 VisitRequest 后,车辆离开的航点。如果与 arrival_waypoint 相同,则可以省略。如果运单模型具有时长距离矩阵,则不得指定 departure_waypoint

tags[]

string

指定附加到访问请求的标记。不允许使用空字符串或重复字符串。

time_windows[]

TimeWindow

限制访问的到达时间的时间范围。请注意,车辆可能会在到达时间窗口之外离开,即到达时间 + 持续时间无需在时间窗口内。如果车辆在 TimeWindow.start_time之前抵达,您可能需要等待一段时间。

如果缺少 TimeWindow,则表示车辆可以随时进行此访问。

时间窗口必须是不相交的,即所有时间窗口都不得与其他时间窗口重叠或相邻,并且顺序必须递增。

仅当存在单个时间范围时才能设置 cost_per_hour_after_soft_end_timesoft_end_time

duration

Duration

访问持续时间,即车辆从到达到出发所花费的时间(将添加到可能的等待时间中;请参阅 time_windows)。

cost

double

在车辆行驶路线上处理此访问请求的费用。此属性可用于为不同的商品自提或配送选项支付不同的费用。此费用的单位必须与“Shipment.penalty_cost”相同,且不得为负数。

load_demands

map<string, Load>

加载此访问请求的需求。这类似于 Shipment.load_demands 字段,只不过它仅适用于此 VisitRequest,而不是整个 Shipment。此处列出的需求已添加到“Shipment.load_demands”中列出的需求。

visit_types[]

string

指定访问的类型。系统可能会据此分配车辆完成此次访问所需的额外时间(请参阅Vehicle.extra_visit_duration_for_visit_type)。

一个类型只能出现一次。

label

string

为此 VisitRequest 指定标签。在响应中,此标签会在相应 ShipmentRoute.Visit 中报告为 visit_label

ShipmentModel

一个运单模式包含一组必须由一组车辆执行运单,同时最大限度地降低总体成本,即:

  • 车辆路线费用(每总时间成本、每次行程费用以及所有车辆的固定成本的总和)。
  • 不履行的发货惩罚。
  • 全球运送时间的费用
字段
shipments[]

Shipment

一组必须在模型中执行的运单。

vehicles[]

Vehicle

可用于执行访问的车辆集。

global_start_time

Timestamp

模型的全局开始时间和结束时间:此范围以外的时间都不能视为有效时间。

模型的时间跨度必须少于 1 年,即 global_end_timeglobal_start_time 之间的间隔必须在 31536000 秒以内。

使用 cost_per_*hour 字段时,不妨将此时间范围设置为较小的时间间隔以提高性能(例如,如果您针对一天进行建模,则应将全局时间限制设置为当天)。如果未设置,系统将使用 1970 年 1 月 1 日 00:00:00 世界协调时间 (UTC)(即秒数:0,纳米:0)作为默认值。

global_end_time

Timestamp

如果未设置,系统将使用世界协调时间 (UTC) 1971 年 1 月 1 日 00:00:00(即秒数:31536000,纳米:0)作为默认值。

global_duration_cost_per_hour

double

“全局持续时间”是指所有车辆的最早有效开始时间与最晚有效结束时间之间的差值。例如,用户可以为此数量指定每小时费用,以尝试进行优化,以便尽早完成作业。此费用必须与Shipment.penalty_cost使用同一个单位。

duration_distance_matrices[]

DurationDistanceMatrix

指定模型中使用的时长和距离矩阵。如果此字段为空,则会根据 use_geodesic_distances 字段的值,改用 Google 地图距离或测地距离。如果不为空,则 use_geodesic_distances 不为 true,duration_distance_matrix_src_tagsduration_distance_matrix_dst_tags 均不得为空。

用法示例:

  • 有两个位置:locA 和 locB。
  • 1 辆车在 locA 开始其路线,并在 locA 结束行驶。
  • 1 次在 locB 提交的自提上门服务请求。
model {
  vehicles { start_tags: "locA"  end_tags: "locA" }
  shipments { pickups { tags: "locB" } }
  duration_distance_matrix_src_tags: "locA"
  duration_distance_matrix_src_tags: "locB"
  duration_distance_matrix_dst_tags: "locA"
  duration_distance_matrix_dst_tags: "locB"
  duration_distance_matrices {
    rows {  # from: locA
      durations { seconds: 0 }   meters: 0    # to: locA
      durations { seconds: 100 } meters: 1000 # to: locB
    }
    rows {  # from: locB
      durations { seconds: 102 } meters: 990 # to: locA
      durations { seconds: 0 }   meters: 0   # to: locB
    }
  }
}
  • 有三个位置:locA、locB 和 locC。
  • 使用矩阵“快速”的 1 辆车在 locA 开始其路线并在 locB 结束。
  • 使用矩阵“慢”的 1 辆车在 locB 开始其路线并在 locB 结束。
  • 使用矩阵“快速”的 1 辆车在 locB 开始其路线并在 locB 结束。
  • 1 次在 locC 提交的自提上门服务请求。
model {
  vehicles { start_tags: "locA" end_tags: "locB" start_tags: "fast" }
  vehicles { start_tags: "locB" end_tags: "locB" start_tags: "slow" }
  vehicles { start_tags: "locB" end_tags: "locB" start_tags: "fast" }
  shipments { pickups { tags: "locC" } }
  duration_distance_matrix_src_tags: "locA"
  duration_distance_matrix_src_tags: "locB"
  duration_distance_matrix_src_tags: "locC"
  duration_distance_matrix_dst_tags: "locB"
  duration_distance_matrix_dst_tags: "locC"
  duration_distance_matrices {
    vehicle_start_tag: "fast"
    rows {  # from: locA
      durations { seconds: 1000 } meters: 2000 # to: locB
      durations { seconds: 600 }  meters: 1000 # to: locC
    }
    rows {  # from: locB
      durations { seconds: 0 }   meters: 0    # to: locB
      durations { seconds: 700 } meters: 1200 # to: locC
    }
    rows {  # from: locC
      durations { seconds: 702 } meters: 1190 # to: locB
      durations { seconds: 0 }   meters: 0    # to: locC
    }
  }
  duration_distance_matrices {
    vehicle_start_tag: "slow"
    rows {  # from: locA
      durations { seconds: 1800 } meters: 2001 # to: locB
      durations { seconds: 900 }  meters: 1002 # to: locC
    }
    rows {  # from: locB
      durations { seconds: 0 }    meters: 0    # to: locB
      durations { seconds: 1000 } meters: 1202 # to: locC
    }
    rows {  # from: locC
      durations { seconds: 1001 } meters: 1195 # to: locB
      durations { seconds: 0 }    meters: 0    # to: locC
    }
  }
}
duration_distance_matrix_src_tags[]

string

定义时长和距离矩阵来源的标签;duration_distance_matrices(i).rows(j) 定义了从带有 duration_distance_matrix_src_tags(j) 标记的访问到矩阵 i 中的其他访问的持续时间和距离。

标记对应于 VisitRequest.tagsVehicle.start_tags。指定的 VisitRequestVehicle 必须与此字段中的一个标记完全匹配。请注意,Vehicle 的源标记、目标标记和矩阵标记可能相同;同样,VisitRequest 的源标记和目标标记可能相同。所有标签不得相同,且不能为空字符串。如果此字段不为空,则 duration_distance_matrices 不得为空。

duration_distance_matrix_dst_tags[]

string

用于定义时长和距离矩阵目的地的标签;duration_distance_matrices(i).rows(j).durations(k)(响应duration_distance_matrices(i).rows(j).meters(k)) 定义从带有 duration_distance_matrix_src_tags(j) 标记的访问到矩阵 i 中带有 duration_distance_matrix_dst_tags(k) 标记的访问的行程时长(代表距离)。

标记对应于 VisitRequest.tagsVehicle.start_tags。指定的 VisitRequestVehicle 必须与此字段中的一个标记完全匹配。请注意,Vehicle 的源标记、目标标记和矩阵标记可能相同;同样,VisitRequest 的源标记和目标标记可能相同。所有标签不得相同,且不能为空字符串。如果此字段不为空,则 duration_distance_matrices 不得为空。

transition_attributes[]

TransitionAttributes

添加到模型的过渡属性。

shipment_type_incompatibilities[]

ShipmentTypeIncompatibility

不兼容的 shipping_types 集(请参阅 ShipmentTypeIncompatibility)。

shipment_type_requirements[]

ShipmentTypeRequirement

shipment_type 要求集(请参阅 ShipmentTypeRequirement)。

precedence_rules[]

PrecedenceRule

一组必须在模型中强制执行的优先规则。

max_active_vehicles

int32

限制有效车辆的最大数量。如果车辆的路线至少完成一次送货,则车辆处于活跃状态。在司机数量少于车辆数量且车队类型不多时,可以使用此属性来限制路线数量。然后,优化操作会选择最合适的车辆子集进行使用。必须是正数。

DurationDistanceMatrix

指定从到访地点和车辆开始位置到到访地点和车辆结束位置的时长和距离矩阵。

字段
rows[]

Row

指定时长和距离矩阵的行。它包含的元素数量必须与 ShipmentModel.duration_distance_matrix_src_tags 一样多。

vehicle_start_tag

string

用于定义此时长和距离矩阵应用于哪些车辆的标记。如果为空,则适用于所有车辆,并且只能有一个矩阵。

每次车辆启动都必须与一个矩阵完全一致,即其中一个 start_tags 字段必须与矩阵(且仅限该矩阵)的 vehicle_start_tag 匹配。

所有矩阵的 vehicle_start_tag 都必须不同。

指定时长和距离矩阵的一行。

字段
durations[]

Duration

给定行的时长值。它包含的元素数量必须与 ShipmentModel.duration_distance_matrix_dst_tags 一样多。

meters[]

double

给定行的距离值。如果模型中的距离没有任何费用或约束条件,则可以留空;否则,它的元素数量必须与 durations 相同。

PrecedenceRule

两个事件(每个事件都是自提或送货上门)之间的优先规则:第二个事件活动必须在“first”(第一个)之后至少 offset_duration开始已开始。

多个优先级可以指代相同(或相关)的事件,例如,“在商品 A 送达后提货 B”和“C 的提货发生在 B 的提货之后”。

此外,优先级仅在两批配送均执行时适用,否则会被忽略。

字段
first_is_delivery

bool

指明其是否为“第一个”事件是交付事件。

second_is_delivery

bool

指示“第二个”事件是交付事件。

offset_duration

Duration

“第一个”和“second”事件。它可以为负值。

first_index

int32

“第一个”的发货索引事件。必须指定此字段。

second_index

int32

“秒”的装运索引事件。必须指定此字段。

ShipmentRoute

车辆的路线可以沿时间轴分解,如下所示(我们假设有 n 次访问):

  |            |            |          |       |  T[2], |        |      |
  | Transition |  Visit #0  |          |       |  V[2], |        |      |
  |     #0     |    aka     |   T[1]   |  V[1] |  ...   | V[n-1] | T[n] |
  |  aka T[0]  |    V[0]    |          |       | V[n-2],|        |      |
  |            |            |          |       | T[n-1] |        |      |
  ^            ^            ^          ^       ^        ^        ^      ^
vehicle    V[0].start   V[0].end     V[1].   V[1].    V[n].    V[n]. vehicle
 start     (arrival)   (departure)   start   end      start    end     end

请注意,我们对以下两个方面有所不同:

  • “准时事件”,例如车辆开始和结束以及每次访问的开始和结束(也称为到达和离开)。它们发生在特定的某一秒。
  • “时间间隔”,例如访问本身以及访问之间的转换。虽然时间间隔有时的时长可能为零(即开始和结束时间相同),但它们的时长通常为正数。

不变量:

  • 如果有 n 次访问,则会出现 n+1 次转换。
  • 访问始终围绕在其之后的转换(索引相同)和之后的转换(索引 + 1)。
  • 车辆启动后始终是转场 #0。
  • 车辆结束始终在过渡 #n 之前。

放大后,下面是在 TransitionVisit 期间会发生的情况:

---+-------------------------------------+-----------------------------+-->
   |           TRANSITION[i]             |           VISIT[i]          |
   |                                     |                             |
   |  * TRAVEL: the vehicle moves from   |      PERFORM the visit:     |
   |    VISIT[i-1].departure_location to |                             |
   |    VISIT[i].arrival_location, which |  * Spend some time:         |
   |    takes a given travel duration    |    the "visit duration".    |
   |    and distance                     |                             |
   |                                     |  * Load or unload           |
   |  * BREAKS: the driver may have      |    some quantities from the |
   |    breaks (e.g. lunch break).       |    vehicle: the "demand".   |
   |                                     |                             |
   |  * WAIT: the driver/vehicle does    |                             |
   |    nothing. This can happen for     |                             |
   |    many reasons, for example when   |                             |
   |    the vehicle reaches the next     |                             |
   |    event's destination before the   |                             |
   |    start of its time window         |                             |
   |                                     |                             |
   |  * DELAY: *right before* the next   |                             |
   |    arrival. E.g. the vehicle and/or |                             |
   |    driver spends time unloading.    |                             |
   |                                     |                             |
---+-------------------------------------+-----------------------------+-->
   ^                                     ^                             ^
V[i-1].end                           V[i].start                    V[i].end

最后,下面展示了如何在过渡期间安排 TRAVEL、BREAKS、DELAY 和 WAIT。

  • 不会重叠。
  • DELAY 是唯一的,且必须是下次访问(或车辆结束)之前的连续时间段。因此,只需知道延迟时长,即可知道其开始时间和结束时间。
  • 这些 BREAKS 是连续且不重叠的时间段。响应会指定每个插播时间点的开始时间和时长。
  • TRAVEL 和 WAIT 是“可抢占”的:在此转换过程中,它们可能会多次中断。客户可以假设出差“尽快”然后“等待”填充剩余时间。

(复杂)示例:

                               TRANSITION[i]
--++-----+-----------------------------------------------------------++-->
  ||     |       |           |       |           |         |         ||
  ||  T  |   B   |     T     |       |     B     |         |    D    ||
  ||  r  |   r   |     r     |   W   |     r     |    W    |    e    ||
  ||  a  |   e   |     a     |   a   |     e     |    a    |    l    ||
  ||  v  |   a   |     v     |   i   |     a     |    i    |    a    ||
  ||  e  |   k   |     e     |   t   |     k     |    t    |    y    ||
  ||  l  |       |     l     |       |           |         |         ||
  ||     |       |           |       |           |         |         ||
--++-----------------------------------------------------------------++-->
字段
vehicle_index

int32

执行路线的车辆,由其在源 ShipmentModel 中的索引标识。

vehicle_label

string

执行此路线的车辆的标签,等于 ShipmentModel.vehicles(vehicle_index).label(如果已指定)。

vehicle_start_time

Timestamp

车辆开始行驶路线的时间。

vehicle_end_time

Timestamp

车辆完成行驶路线的时间。

visits[]

Visit

表示路线的一系列按顺序进行的访问。Visits[i] 是路线中的第 i 次访问。如果此字段为空,车辆会被视为未使用。

transitions[]

Transition

路由的有序转换列表。

has_traffic_infeasibilities

bool

OptimizeToursRequest.consider_road_traffic 设置为 true 时,此字段表示路线时间的不一致情况是使用基于路况的行程时长估算值来预测的。可能没有足够的时间来完成根据交通调整后的行程、延误和中途停靠,无论是在第一次访问之前还是之后,同时仍然满足访问和车辆时间范围要求。例如,

  start_time(previous_visit) + duration(previous_visit) +
  travel_duration(previous_visit, next_visit) > start_time(next_visit)

由于交通原因,预计行程时间 (travel_duration(previous_visit, next_visit)) 增加,到达 next_visit 的时间可能会晚于其当前时间窗口。此外,由于行程时间估算值的增加以及到访或休息时间窗口限制,休息时间可能不得与到访时间重叠。

route_polyline

EncodedPolyline

路线的编码多段线表示形式。仅当 OptimizeToursRequest.populate_polylines 设置为 true 时,系统才会填充此字段。

breaks[]

Break

为执行此路线的车辆安排的休息时间。breaks 序列表示时间间隔,每个时间间隔都从相应的 start_time 开始,持续 duration 秒。

metrics

AggregatedMetrics

此路线的时长、距离和负载指标。AggregatedMetrics 的字段对所有 ShipmentRoute.transitionsShipmentRoute.visits 求和,具体取决于上下文。

route_costs

map<string, double>

路由的费用,按与费用相关的请求字段细分。键是相对于输入 OptimizationToursRequest 的 proto 路径,例如:"model.shipments.pickups.cost",这些值是相应费用字段生成的总费用,汇总到整个路线中。换句话说,cost["model.shipments.pickups.cost"] 是路线中所有提货费用的总和。模型中定义的所有费用均在此处详细报告,但与 TransitionAttributes 相关的费用自 2022 年 1 月起仅以汇总方式报告。

route_total_cost

double

路线的总费用。费用映射中所有费用的总和。

休息时间

表示广告插播执行的数据。

字段
start_time

Timestamp

休息的开始时间。

duration

Duration

休息时长。

EncodedPolyline

多段线的编码表示形式。如需详细了解多段线编码,请访问以下网址:https://developers.google.com/maps/documentation/utilities/polylinealgorithmhttps://developers.google.com/maps/documentation/javascript/reference/geometry#encoding

字段
points

string

表示多段线的编码点的字符串。

转换

路线上两个事件之间的转换。请参阅 ShipmentRoute 的说明。

如果车辆没有 start_location 和/或 end_location,则相应的行程指标为 0。

字段
travel_duration

Duration

此过渡期间的旅行时长。

travel_distance_meters

double

转换期间移动的距离。

traffic_info_unavailable

bool

如果通过 OptimizeToursRequest.consider_road_traffic 请求路况,但无法获取 Transition 的路况信息,则此布尔值会设置为 true。这可能是暂时的(实时流量服务器中很少出现故障),也可能是永久性的(该位置没有数据)。

delay_duration

Duration

应用于此过渡的延迟时间总和。如果有,延迟从下一个事件(访问或车辆结束)前正好 delay_duration 秒开始。请参阅TransitionAttributes.delay

break_duration

Duration

此过渡期间发生的插播时间点的时长总和(如果有)。每个广告插播时间点的开始时间和时长的详细信息存储在 ShipmentRoute.breaks 中。

wait_duration

Duration

此转换期间的等待时间。等待时长对应闲置时间,且不包括暂停时间。另请注意,此等待时间可能会分成几个不连续的时间间隔。

total_duration

Duration

转换的总时长(为方便起见提供)。它等于:

  • 下次访问 start_time(如果是最后一次过渡,则访问 vehicle_end_time)- 此过渡的 start_time
  • 如果 ShipmentRoute.has_traffic_infeasibilities 为 false,以下还会进一步规定:`total_duration = travel_duration + delay_duration
  • break_duration +wait_duration”。
start_time

Timestamp

此转换的开始时间。

route_polyline

EncodedPolyline

过渡期间所遵循路线的编码多段线表示形式。仅当 populate_transition_polylines 设置为 true 时,系统才会填充此字段。

vehicle_loads

map<string, VehicleLoad>

在此次过渡期间,对于此车辆的Vehicle.load_limits中显示的每类车辆,或此航线上的部分货物,其 Shipment.load_demands 为非零的车辆加载。

第一次转换期间的负载是车辆路线的起始负载。然后,在每次访问之后,都会加上或减去访问的 load_demands,以获取下一个过渡的加载,具体取决于访问是自提还是外卖。

VehicleLoad

对于给定类型,报告车辆在路线沿途某个点的实际负载(请参阅 Transition.vehicle_loads)。

字段
amount

int64

车辆的负载量(针对指定类型)。负载单位通常用类型表示。请参阅 Transition.vehicle_loads

访问

在路线期间进行的访问。本次访问对应于 Shipment 的自取或交付。

字段
shipment_index

int32

来源 ShipmentModelshipments 字段的索引。

is_pickup

bool

如果为 true,则该访问对应于 Shipment 的提货。否则,它对应于投放。

visit_request_index

int32

Shipment 的自提或送货字段中的 VisitRequest 的索引(请参阅 is_pickup)。

start_time

Timestamp

访问的开始时间。请注意,车辆可能会提前到达造访地点。时间与 ShipmentModel 一致。

load_demands

map<string, Load>

总访问加载需求,即运单和访问请求 load_demands 的总和。如果访问属于送货服务,则值为负数。系统会针对与 Transition.loads 相同的类型报告需求(请参阅此字段)。

detour

Duration

由于在造访路线前造访过货物,以及因时间范围而可能需等待的时间,需要额外的绕行时间。如果访问是送餐,系统会根据相应的取货造访计算绕行时间,并且等于:

start_time(delivery) - start_time(pickup)
- (duration(pickup) + travel duration from the pickup location
to the delivery location).

否则,它根据车辆 start_location 计算得出,等于:

start_time - vehicle_start_time - travel duration from
the vehicle's `start_location` to the visit.
shipment_label

string

相应 Shipment.label 的副本(如果在 Shipment 中指定)。

visit_label

string

相应 VisitRequest.label 的副本(如果在 VisitRequest 中指定)。

ShipmentTypeIncompatibility

根据运单类型指定运单之间的不兼容情况。由于不兼容模式,同一航线上出现不兼容的运单会受到限制。

字段
types[]

string

不兼容的类型列表。列出的 shipment_types 不同的两件运单是“不兼容”的。

incompatibility_mode

IncompatibilityMode

应用于不兼容的模式。

IncompatibilityMode

定义如何在同一条航线上限制出现不相容运单的情况。

枚举
INCOMPATIBILITY_MODE_UNSPECIFIED 未指定的不兼容模式。不应使用此值。
NOT_PERFORMED_BY_SAME_VEHICLE 在此模式下,类型不兼容的两件货品绝不能共用同一辆车。
NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY

对于类型不兼容且NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY不兼容的两件货品:

  • 如果两者均为仅自提(不送货)或仅送货(不自提),则两人不能共用同一辆车。
  • 如果其中一批货物已送达,而另一批货物为取货商品,且前一批货物在其取件前送达,则这两批货物可以共用同一辆车。

ShipmentTypeRequirement

根据 shipping_type [运单类型] 指定运单之间的要求。具体要求由要求模式定义。

字段
required_shipment_type_alternatives[]

string

dependent_shipment_types要求的备选运单类型的列表。

dependent_shipment_types[]

string

对于所有属于“dependent_shipment_types”字段的运单,同一条航线上必须有至少 1 个类型为 required_shipment_type_alternatives 的运单。

注意:不允许使用导致 shipment_type 依赖于自身的要求链。

requirement_mode

RequirementMode

应用于要求的模式。

RequirementMode

用于定义路线上依赖性货物的外观的模式。

枚举
REQUIREMENT_MODE_UNSPECIFIED 未指定的要求模式。不应使用此值。
PERFORMED_BY_SAME_VEHICLE 在此模式下,所有“依赖项”必须至少与其“必需”运单中的一辆车共用同一辆车运单。
IN_SAME_VEHICLE_AT_PICKUP_TIME

对于 IN_SAME_VEHICLE_AT_PICKUP_TIME 模式,所有“从属”需要有至少一个“必需”属性并在上车点上车。

“被抚养人”因此,运单自提必须具有以下任一项:

  • 仅提供送餐服务的“必需”运单上的包裹
  • “必需”运单已交付,则该交付必须在“依赖”送货上门。
IN_SAME_VEHICLE_AT_DELIVERY_TIME 与之前相同,但“从属项”除外需要有一个“必需”在交付时为其发货。

SkippedShipment

指定解决方案中未执行的运单的详细信息。对于无关紧要的情况和/或如果我们能够确定跳过的原因,我们会在此处报告原因。

字段
index

int32

该指数与来源 ShipmentModel 中的运单对应的索引。

label

string

相应 Shipment.label 的副本(如果在 Shipment 中指定)。

reasons[]

Reason

解释为何跳过发货的原因列表。查看 Reason 上方的评论。

原因

如果我们能说明跳过发货的原因,则会在此处列出相关原因。如果所有车辆的原因各不相同,reason 将包含多个元素。跳过的运单不能有重复的原因,即除“example_vehicle_index”以外的所有字段都相同。示例:

reasons {
  code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
  example_vehicle_index: 1
  example_exceeded_capacity_type: "Apples"
}
reasons {
  code: DEMAND_EXCEEDS_VEHICLE_CAPACITY
  example_vehicle_index: 3
  example_exceeded_capacity_type: "Pears"
}
reasons {
  code: CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT
  example_vehicle_index: 1
}

跳过的运单与所有车辆都不兼容。所有车辆的原因可能不同,但至少有一辆车是“苹果”会超出容量限制(包括车辆 1),而至少有一辆车的“梨”超出容量限制(包括车辆 3),且至少会超出一辆车的距离限制(包括车辆 1)。

字段
code

Code

请参阅代码的注释。

example_exceeded_capacity_type

string

如果原因代码为 DEMAND_EXCEEDS_VEHICLE_CAPACITY,则记录一个超出的容量类型。

example_vehicle_index

int32

如果原因与运输车辆不兼容,则此字段会提供一个相关车辆的索引。

代码

标识原因类型的代码。这里的顺序没有意义。特别是,它不会指出给定原因是否会在解决方案中的另一个原因出现之前(如果两者都适用)。

枚举
CODE_UNSPECIFIED 切勿使用此字段。如果我们无法理解某件商品被跳过的原因,则只需返回一组空白的原因即可。
NO_VEHICLE 模型中没有车辆,使得所有运送都无法进行。
DEMAND_EXCEEDS_VEHICLE_CAPACITY 此运单的需求超出某辆车的承载能力,无法承载部分承载能力,其中包括 example_exceeded_capacity_type
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DISTANCE_LIMIT

完成此运单所需的最短距离(即从车辆的start_location到货物的取货点和/或送货地点,以及到车辆的终点位置)的最小距离超过了车辆的 route_distance_limit

请注意,我们使用测地距离进行此计算。

CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT

完成此发货所需的最短时间(包括行程时间、等待时间和维修时间)超过车辆的route_duration_limit

请注意:行程时间在最佳情况下计算,即为测地距离 x 36 米/秒(约为 130 公里/小时)。

CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TRAVEL_DURATION_LIMIT 同上,但我们仅比较最短行程时间和车辆的 travel_duration_limit
CANNOT_BE_PERFORMED_WITHIN_VEHICLE_TIME_WINDOWS 如果车辆在最早的开始时间开始,则车辆无法在最佳情况下进行此装运(有关时间计算,请参阅 CANNOT_BE_PERFORMED_WITHIN_VEHICLE_DURATION_LIMIT):总时间会使车辆在最晚结束时间之后结束。
VEHICLE_NOT_ALLOWED 运单的“allowed_vehicle_indices”字段不为空,且不属于该车辆。

TimeWindow

时间窗口用于限制事件的时间,例如到达时间或车辆的开始时间和结束时间。

硬性时间范围边界(start_timeend_time)会强制实施事件的最早和最晚时间,例如 start_time <= event_time <= end_time。软时间窗口下限 soft_start_time 表示事件在 soft_start_time 当天或之后发生的偏好,它会产生与事件发生前 soft_start_time 成比例的费用。软时间窗口的上限 (soft_end_time) 表示根据事件发生后soft_end_time的时长按比例产生费用,从而表明事件在 soft_end_time 之前或之前发生的偏好。start_timeend_timesoft_start_timesoft_end_time 应在全局时间限制内(请参阅 ShipmentModel.global_start_timeShipmentModel.global_end_time),并应遵循:

  0 <= `start_time` <= `soft_start_time` <= `end_time` and
  0 <= `start_time` <= `soft_end_time` <= `end_time`.
字段
start_time

Timestamp

硬性时间范围的开始时间。如果未指定,则将设置为 ShipmentModel.global_start_time

end_time

Timestamp

硬性时间范围的结束时间。如果未指定,则将设置为 ShipmentModel.global_end_time

soft_start_time

Timestamp

时间范围的软启动时间。

soft_end_time

Timestamp

时间范围的软结束时间。

cost_per_hour_before_soft_start_time

double

如果事件在 soft_start_time 之前发生,则每小时的费用与模型中的其他费用相加,计算公式如下:

   max(0, soft_start_time - t.seconds)
                          * cost_per_hour_before_soft_start_time / 3600,
t being the time of the event.

此开销必须为正数,并且只有在设置了 soft_start_time 时才能设置该字段。

cost_per_hour_after_soft_end_time

double

如果事件发生在 soft_end_time 之后,则每小时的费用与模型中的其他费用相加,计算公式如下:

   max(0, t.seconds - soft_end_time.seconds)
                    * cost_per_hour_after_soft_end_time / 3600,
t being the time of the event.

此费用必须为正数,并且只有在已设置 soft_end_time 的情况下才能设置该字段。

TransitionAttributes

指定路线上两次连续访问之间的转换属性。多个 TransitionAttributes 可能会应用于同一转换:在这种情况下,所有额外费用都会累加,并应用最严格的限制条件或限制(遵循自然的“AND”语义)。

字段
src_tag

string

用于定义这些属性所适用的 (src->dst) 转换集的标记。

当来源访问或车辆启动匹配时,仅当其 VisitRequest.tagsVehicle.start_tags 包含 src_tag 或不包含 excluded_src_tag(具体取决于这两个字段中哪个字段为非空)时匹配。

excluded_src_tag

string

请参阅 src_tag。“src_tag”和“excluded_src_tag”必须有且不得为空。

dst_tag

string

当目的地访问或车辆结束与 VisitRequest.tagsVehicle.end_tags 包含 dst_tag 或不包含 excluded_dst_tag 时匹配(具体取决于这两个字段中哪个字段不为空)。

excluded_dst_tag

string

请参阅 dst_tag。“dst_tag”和“excluded_dst_tag”必须有且不得为空。

cost

double

指定执行此转换的费用。此费用与模型中的其他所有费用位于同一单位中,并且不得为负数。该费用在所有其他现有费用的基础上加收。

cost_per_kilometer

double

指定对执行此过渡时行驶的距离应用的每公里费用。此值等于车辆上指定的任何 Vehicle.cost_per_kilometer

distance_limit

DistanceLimit

指定执行此转场时移动的距离限制。

自 2021 年 6 月起,仅支持软性限额。

delay

Duration

指定执行此过渡时产生的延迟。

这种延迟总是发生在完成来源访问之后和开始目标访问之前。

交通工具

模拟运输问题中的车辆。解决运送问题后,系统会为此车辆创建从 start_locationend_location 的路线。路线是指一系列访问(请参阅 ShipmentRoute)。

字段
display_name

string

用户定义的车辆显示名称。长度不得超过 63 个字符,且可以使用 UTF-8 字符。

travel_mode

TravelMode

会影响车辆可使用的道路及其速度的出行方式。另请参阅 travel_duration_multiple

start_location

LatLng

车辆在取走任何货物之前出发的地理位置。如果未指定,车辆会在首次上车点启动。如果运单模型具有时长和距离矩阵,则不得指定 start_location

start_waypoint

Waypoint

表示车辆在取走任何货物前出发的地理位置的航点。如果 start_waypointstart_location 均未指定,则车辆会在首次上车点启动。如果运单模型具有时长和距离矩阵,则不得指定 start_waypoint

end_location

LatLng

车辆在最后一次行驶 VisitRequest后结束的地理位置。如果未指定,车辆的 ShipmentRoute 会在完成最后一个 VisitRequest 后立即结束。如果运单模型具有时长和距离矩阵,则不得指定 end_location

end_waypoint

Waypoint

表示车辆在结束上一个VisitRequest后结束的地理位置的航点。如果 end_waypointend_location 均未指定,则车辆的 ShipmentRoute 将在完成最后一个 VisitRequest 后立即结束。如果运单模型具有时长和距离矩阵,则不得指定 end_waypoint

start_tags[]

string

指定附加到车辆路线起点的标记。

不允许使用空字符串或重复字符串。

end_tags[]

string

指定附加到车辆路线末尾的标记。

不允许使用空字符串或重复字符串。

start_time_windows[]

TimeWindow

车辆可能离开其起始位置的时间窗口。它们必须在全局时间限制内(请参阅 ShipmentModel.global_* 字段)。如果未指定,则除了这些全局时间限制之外,没有其他限制。

属于同一重复字段的时间窗口必须是不相交的,即任何时间窗口都不能与其他时间窗口重叠或相邻,并且必须按时间顺序排列。

仅当存在一个时间范围时,才能设置 cost_per_hour_after_soft_end_timesoft_end_time

end_time_windows[]

TimeWindow

车辆可到达终点位置的时间范围。它们必须在全局时间限制内(请参阅 ShipmentModel.global_* 字段)。如果未指定,则除了这些全局时间限制之外,没有其他限制。

属于同一重复字段的时间窗口必须是不相交的,即任何时间窗口都不能与其他时间窗口重叠或相邻,并且必须按时间顺序排列。

仅当存在单个时间范围时才能设置 cost_per_hour_after_soft_end_timesoft_end_time

unloading_policy

UnloadingPolicy

已在车辆上强制执行卸载政策。

load_limits

map<string, LoadLimit>

车辆容量(例如重量、体积、托盘数)。映射中的键是加载类型的标识符,与 Shipment.load_demands 字段的键一致。如果此映射中没有给定键,则相应的容量被视为无限量。

cost_per_hour

double

车辆费用:所有费用相加,且必须与“Shipment.penalty_cost”处于同一单位。

车辆路线的每小时费用。该费用适用于相应路线的总时间,包括行程时间、等候时间和到访时间。使用 cost_per_hour 而不是仅使用 cost_per_traveled_hour 可能会导致额外的延迟。

cost_per_traveled_hour

double

车辆路线每行驶小时的费用。此费用仅适用于相应路线所用行程时间(即在 ShipmentRoute.transitions 中报告的时间),不包括等候时间和到访时间。

cost_per_kilometer

double

车辆行驶路线的每公里费用。此开销会应用于 ShipmentRoute.transitions 中报告的距离,而不适用于从单个 VisitRequestarrival_locationdeparture_location 隐式传输的任何距离。

fixed_cost

double

如果此车辆用于处理运单,则会收取固定费用。

used_if_route_is_empty

bool

此字段仅适用于相应车辆路线不提供任何运单的车辆。用于指明在这种情况下是否应将车辆视为二手。

如果为 true,则即使车辆不提供任何装运,也会从起点到终点位置,以及从起点开始产生的时间和距离成本 -->包括结束旅行

否则,它不会从出发位置前往目的地,并且没有为此车辆安排break_rule或延迟(从 TransitionAttributes开始)。在这种情况下,车辆的 ShipmentRoute 不包含车辆索引和标签以外的任何信息。

route_duration_limit

DurationLimit

应用于车辆路线的总时长的限制。在给定的 OptimizeToursResponse 中,车辆的路线时长是其 vehicle_end_timevehicle_start_time 之间的差值。

travel_duration_limit

DurationLimit

应用于车辆路线行程时长的限制。在给定的 OptimizeToursResponse 中,路线行程时长是其所有 transitions.travel_duration 的总和。

route_distance_limit

DistanceLimit

应用于车辆路线的总距离的限制。在给定的 OptimizeToursResponse 中,路线距离是其所有 transitions.travel_distance_meters 的总和。

extra_visit_duration_for_visit_type

map<string, Duration>

指定从访问类型字符串到持续时间的映射。时长是指在指定了 visit_types 的访问时获取的 VisitRequest.duration 之外的时间。如果指定了 cost_per_hour,这种额外的访问持续时间会增加费用。键(即 visit_types)不能为空字符串。

如果访问请求有多种类型,系统会为地图中的每种类型分别添加一个时长。

break_rule

BreakRule

说明要在这辆车上强制执行的休息时间表。如果留空,系统不会为此车辆安排任何休息时间。

label

string

指定此车辆的标签。此标签会在响应中报告为相应 ShipmentRoutevehicle_label

ignore

bool

如果设为 true,used_if_route_is_empty 必须为 false,这辆车将保持未使用状态。

如果配送由 injected_first_solution_routes 中忽略的车辆执行,第一个解决方案中会跳过该操作,但可以在响应中执行该操作。

如果配送由忽略的车辆在 injected_solution_constraint 中执行,并且任何相关的取货/送货限制被限制为留在车辆上(即未放宽到 RELAX_ALL_AFTER_THRESHOLD 级),则响应中会跳过该操作。如果某个运单包含非空的 allowed_vehicle_indices 字段,并且所有允许的车辆都被忽略,则系统在响应中会跳过该运单。

travel_duration_multiple

double

指定可用于延长或缩短此车辆行程时间的乘法系数。例如,将此值设为 2.0 表示车辆速度较慢,其行程时间是标准车辆的两倍。此值不会影响访问持续时间。如果指定了 cost_per_hourcost_per_traveled_hour,则会影响费用。必须在 [0.001, 1000.0] 范围内。如果未设置,则车辆为标准车辆,系统会视为 1.0 乘数。

警告:应用此倍数后,行程时间将四舍五入为最接近的秒数,但在执行任何数值运算之前,因倍数过小可能会导致精度损失。

另请参阅下面的 extra_visit_duration_for_visit_type

DurationLimit

定义车辆路线的最大时长的限制。它可以是硬性质的,也可以是软的。

定义软性限制字段后,必须同时定义软最大阈值及其相关费用。

字段
max_duration

Duration

将时长限制为不超过 max_duration 的硬性限制。

soft_max_duration

Duration

软性限制,未强制实施时长上限,但如果违反,则会导致路线产生费用。此费用与模型中定义的其他费用相加,单位相同。

如果已定义,则 soft_max_duration 必须是非负数。如果还定义了 max_duration,则 soft_max_duration 必须小于 max_duration。

quadratic_soft_max_duration

Duration

不强制执行时长上限的软性限制,但如果违反,会导致路线产生费用,即持续时间的二次方。此费用与模型中定义的其他费用相加,单位相同。

如果已定义,则 quadratic_soft_max_duration 必须是非负数。如果还定义了 max_duration,则 quadratic_soft_max_duration 必须小于 max_duration,且差值不得大于一天:

max_duration - quadratic_soft_max_duration <= 86400 seconds

cost_per_hour_after_soft_max

double

违反 soft_max_duration 阈值时产生的每小时费用。如果时长低于阈值,则额外费用为 0,否则费用取决于时长,如下所示:

  cost_per_hour_after_soft_max * (duration - soft_max_duration)

费用必须是非负数。

cost_per_square_hour_after_quadratic_soft_max

double

违反 quadratic_soft_max_duration 阈值时产生的每平方小时费用。

如果时长低于阈值,则额外费用为 0,否则费用取决于时长,如下所示:

  cost_per_square_hour_after_quadratic_soft_max *
  (duration - quadratic_soft_max_duration)^2

费用必须是非负数。

LoadLimit

定义适用于车辆的负载限制,例如“这辆卡车最多只能载重 3500 千克”。请参阅 load_limits

字段
soft_max_load

int64

负载的软性限制。请参阅 cost_per_unit_above_soft_max

cost_per_unit_above_soft_max

double

如果车辆沿这辆车路线的负载超过 soft_max_load,则适用以下费用罚款(每辆车只能收费一次):(负载 - soft_max_load) * cost_per_unit_above_soft_max。所有费用相加,且必须与Shipment.penalty_cost处于同一单位。

start_load_interval

Interval

车辆在路线起点的可接受装入间隔时间。

end_load_interval

Interval

车辆在路线终点的可接受装运间隔。

max_load

int64

可接受的最大负载量。

间隔时间

可接受的加载量的间隔。

字段
min

int64

可接受的最小负载。必须 ≥ 0。如果同时指定这两者,则 min 必须 ≤ max

max

int64

可接受的最大负载。必须 ≥ 0。如果未指定最大负载,则不受此消息的限制。如果同时指定这两者,则 min 必须 ≤ max

TravelMode

可用于车辆的出行方式。

这些模式应是 Google Maps Platform 路线首选 API 出行方式的一部分,详见:https://developers.google.com/maps/documentation/routes_preferred/reference/rest/Shared.Types/RouteTravelMode

枚举
TRAVEL_MODE_UNSPECIFIED 未指定的出行方式,相当于DRIVING
DRIVING 与行车路线相对应的出行方式(汽车...)。
WALKING 与步行路线对应的出行方式。

UnloadingPolicy

关于如何卸载车辆的政策。仅适用于同时提供取货和送货服务的货品。

其他运输服务可以在运输途中的任何地方免费送货,不受unloading_policy的影响。

枚举
UNLOADING_POLICY_UNSPECIFIED 未指定的卸载政策;送货必须刚好在其相应自取之后。
LAST_IN_FIRST_OUT 送货顺序必须与取货顺序相反
FIRST_IN_FIRST_OUT 送货顺序必须与取货顺序相同

关键点

封装航点。航点用于标记 VisitRequest 的到达和出发位置,以及车辆的起点和终点。

字段
side_of_road

bool

可选。表示此航点的位置优先让车辆停靠在道路的某一侧。设置此值后,路线会经过相应位置,这样车辆才能在偏离道路中心的道路一侧停靠。此选项不适用于“步行”出行方式。

联合字段 location_type。表示位置的不同方式。location_type 只能是下列其中一项:
location

Location

使用地理坐标指定的点,包含可选标题。

place_id

string

与航点相关联的地图注点地点 ID。