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 组成。ShipmentRouteShipment 分配给 Vehicle。更具体地说,它们为每辆车分配一系列 Visit,其中 Visit 对应 VisitRequestShipment 的取货或送货方式)。

目标是为 Vehicle 分配 ShipmentRoute,以最大限度降低在费用在 ShipmentModel 中定义许多组成部分的情况下的总费用。

授权范围

需要以下 OAuth 作用域:

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

AggregatedMetrics

ShipmentRoute(反映OptimizeToursResponse所有 Transition 和/或 Visit(针对所有 ShipmentRoute)元素的汇总指标。

字段
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(响应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 小时的任何滑动时间窗口中,必须至少有 1 个广告插播时间点(至少一小时),该示例可转换为以下 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 错误详情的形式附加到 INVALID_STRING 错误载荷中 (https://cloud.google.com/apis/design/errors#error_details),除非 resolve_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 条路线对应于模型中的第 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>

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

total_cost

double

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

OptimizeToursValidationError

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

字段
code

int32

验证错误由始终存在的键值对(codedisplay_name)定义。

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

多个错误:当存在多个错误时,验证流程会尝试输出多个错误。这个过程与编译器非常相似,但并不完美。有些验证错误是“严重”错误,也就是说,这些错误会停止整个验证流程。display_name="UNSPECIFIED" 错误就是如此。有些错误可能会导致验证流程跳过其他错误。

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

参考:所有(代码、名称)对的列表:

  • UNSPECIFIED = 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;
    • INJECTED_SOLUTION_MISSING_LABEL = 2000;
    • INJECTED_SOLUTION_DUPLICATE_LABEL = 2001;
    • INJECTED_SOLUTION_AMBIGUOUS_INDEX = 2002;
    • INJECTED_SOLUTION_INFEASIBLE_after_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;
    • 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;
    • 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_ After_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_after_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_after_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_after_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;
    • AMOUNT_NEGATIVE_VALUE = 3100;
  • LOAD_LIMIT_ERROR = 33;
    • 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;
    • 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;
    • DISTANCE_LIMIT_INVALID_COST_after_SOFT_MAX = 3601;
    • DISTANCE_LIMIT_SOFT_MAX_WITHOUT_COST_after_SOFT_MAX = 3602;
    • DISTANCE_LIMIT_COST_after_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;
    • DURATION_LIMIT_MAX_DURATION_NEGATIVE_OR_NAN = 3800;
    • DURATION_LIMIT_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3801;
    • DURATION_LIMIT_INVALID_COST_PER_HOUR_webkit_SOFT_MAX = 3802;
    • DURATION_LIMIT_SOFT_MAX_WITHOUT_COST_after_SOFT_MAX = 3803;
    • DURATION_LIMIT_COST_after_SOFT_MAX_WITHOUT_SOFT_MAX = 3804;
    • DURATION_LIMIT_QUADRATIC_SOFT_MAX_DURATION_NEGATIVE_OR_NAN = 3805;
    • DURATION_LIMIT_INVALID_COST_after_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;
    • 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;
    • 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;
    • 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;
    • 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;
    • 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_INCOMPATIBILITIES = 5005;
  • SHIPMENT_TYPE_REQUIREMENT_ERROR = 52;
    • 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;
    • 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;
    • 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(当代码 !=“UNSPECIFIED”时)之间是 1:1 的映射。

STABILITY:不稳定:与给定 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

字段的名称,例如“车辆”。

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

指定每辆车送达此运单时产生的费用。如果指定,则必须包含以下其中一个:

  • costs_per_vehicle_indices 相同数量的元素。costs_per_vehicle[i] 对应于模型的车辆 costs_per_vehicle_indices[i]
  • 具有与模型中车辆相同的元素数量。第 i 个元素对应于车型的车辆 #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

指定与从自提到送货的最短路径相比,最大绝对绕行时间。如果指定,此值必须是非负数,并且装运必须至少包含自提和配送。

例如,我们将 t 设为从所选自提备选方案直接到所选备选配送方式所用的最短时间。然后,设置 pickup_to_delivery_absolute_detour_limit 会强制执行:

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

如果为同一件运单同时指定了相对限制和绝对限制,则系统会对每个可能的自提/送货对使用限制性更强的限制。自 2017/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

指定最大相对绕行时间(相对于从取货到送货的最短路径)。如果指定,此值必须是非负数,并且装运必须至少包含自提和配送。

例如,我们将 t 设为从所选自提备选方案直接到所选备选配送方式所用的最短时间。然后,设置 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 起,仅当行程时长与车辆无关时,才支持绕行功能。

加载

执行到访时,如果是取车,则可能会增加车辆装运金额,如果是送货,则会减去预定义的货物量。此消息指定了此金额。请参阅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

模型的全局开始时间和结束时间:凡是超出此范围的时间均不会被视为有效。

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

使用 cost_per_*hour 字段时,您可能希望将此时间范围设置为较短的时间间隔以提高性能(例如,如果为某一天建模,则应将全局时间限制设置为该日期)。如果未设置,则默认为 1970 年 1 月 1 日 00:00:00 UTC(即秒:0,nanos:0)。

global_end_time

Timestamp

如果未设置,则默认使用世界协调时间 (UTC) 1971 年 1 月 1 日 00:00:00(即秒:31536000,nanos:0)。

global_duration_cost_per_hour

double

整体方案的“全球时长”是指所有车辆的最早有效开始时间和最新有效结束时间之间的差值。例如,用户可以为该数量指定每小时费用,以尝试进行优化,从而尽可能缩短作业时间。此费用必须与“Shipment.penalty_cost”采用同一单位。

duration_distance_matrices[]

DurationDistanceMatrix

指定模型中使用的持续时间和距离矩阵。如果此字段为空,系统将改用 Google 地图或测地距离,具体取决于 use_geodesic_distances 字段的值。如果不为空,则 use_geodesic_distances 不得为 true,且 duration_distance_matrix_src_tagsduration_distance_matrix_dst_tags 均不得为空。

用法示例:

  • 有两个位置:locA 和 locB。
  • 1 辆车从 locA 出发,到 locA 结束
  • 在 locB 有 1 个自提到访请求。
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 结束
  • 位于 locC 的 1 个自提到访请求。
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)) 定义了从矩阵 i 中带有 duration_distance_matrix_src_tags(j) 标记的访问到带有 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

两个事件(每个事件为提货或提货事件)之间的优先规则:“第二个”事件的开始日期必须在“第一个”事件开始后至少 offset_duration

多个优先级可以指代相同(或相关)事件,例如,“取货 B 发生在 A 交付之后”和“自提 C 发生在取货 B 之后”。

此外,只有在同时完成这两件运单时,才适用优先级,否则会被忽略。

字段
first_is_delivery

bool

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

second_is_delivery

bool

指明“second”事件是否为传送。

offset_duration

Duration

“first”和“second”事件之间的偏移量。此值可以为负数。

first_index

int32

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

second_index

int32

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

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。

  • 它们不会重叠。
  • 延迟是唯一的,必须是下次访问(或车辆结束)之前的连续时间段。因此,知道延迟时长即可知道其开始时间和结束时间。
  • 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

此路线的时长、距离和负载指标。根据上下文,系统会针对所有 ShipmentRoute.transitionsShipmentRoute.visitsAggregatedMetrics 的字段进行求和。

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
  • fragment_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

根据 shipping_type [运单类型] 指定发货间的不兼容问题。根据不兼容模式,在同一航线中显示不兼容的配送选项会受到限制。

字段
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”字段中类型的所有运单都要求在同一航线上至少访问一个类型为“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_tagsrc_tagexcluded_src_tag 中必须有一个不得为空。

dst_tag

string

当目的地到访或车辆终点匹配时,如果其 VisitRequest.tagsVehicle.end_tags 包含 dst_tag 或不包含 excluded_dst_tag(具体取决于这两个字段中哪个不为空)。

excluded_dst_tag

string

请参阅 dst_tagdst_tagexcluded_dst_tag 中必须有一个不得为空。

cost

double

指定执行此转换所需的费用。此单位与模型中的所有其他费用属于同一单位,且不能为负数。它是在所有其他现有费用基础上收取的。

cost_per_kilometer

double

指定在执行此转换时所行驶距离应用的每公里费用。它等于车辆上指定的任意 Vehicle.cost_per_kilometer

distance_limit

DistanceLimit

指定执行此转换时行程距离的限制。

从 2021 年 6 月开始,仅支持软性限制。

delay

Duration

指定执行此转换时发生的延迟。

这种延迟始终发生在来源访问完成之后、目的地访问开始之前。

交通工具

为遇到运输问题的车辆建模。解决运输问题后,系统会为此车辆构建一条从 start_location 开始、到 end_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 中报告的距离,不适用于从 arrival_location 到单个 VisitRequestdeparture_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 字符串到持续时间的映射。该时长是对具有指定 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,且差值不得大于 1 天:

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 Routes Preferred 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。