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,并返回一个包含 ShipmentRoute 字段的 OptimizeToursResponse,这些字段是车辆要执行的一组路线,可最大限度地降低总体费用。

用户可以轮询 operations.get 以检查 LRO 的状态:

如果 LRO done 字段为 false,则表示至少有一个请求仍在处理中。其他请求可能已成功完成,其结果可在 Cloud Storage 中找到。

如果 LRO 的 done 字段为 true,则表示所有请求都已处理。任何成功处理的请求都会将其结果存储在 Cloud Storage 中。任何失败的请求都不会在 Cloud Storage 中提供其结果。如果设置了 LRO 的 error 字段,则该字段包含其中一个失败请求的错误。

授权范围

需要以下 OAuth 范围:

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

需要拥有 parent 资源的以下 IAM 权限:

  • routeoptimization.operations.create

如需了解详情,请参阅 IAM 文档。

OptimizeTours

rpc OptimizeTours(OptimizeToursRequest) returns (OptimizeToursResponse)

发送包含 ShipmentModel 的 OptimizeToursRequest,并返回包含 ShipmentRoute 的 OptimizeToursResponse,这是一组由车辆执行的路线,可最大限度地降低总费用。

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

目标是提供 ShipmentRoute 到 Vehicle 的分配,以最大限度地降低总费用,其中费用包含 ShipmentModel 中定义的许多组成部分。

授权范围

需要以下 OAuth 范围:

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

需要拥有 parent 资源的以下 IAM 权限:

  • routeoptimization.locations.use

如需了解详情,请参阅 IAM 文档。

OptimizeToursLongRunning

rpc OptimizeToursLongRunning(OptimizeToursRequest) returns (Operation)

这是 OptimizeTours 方法的一种变体,专为具有较大超时值的优化而设计。对于耗时超过几分钟的优化,应优先使用此方法,而不是 OptimizeTours 方法。

返回的 long-running operation (LRO) 的名称格式为 <parent>/operations/<operation_id>,可用于跟踪计算进度。metadata 字段类型为 OptimizeToursLongRunningMetadata。如果成功,response 字段类型为 OptimizeToursResponse。

授权范围

需要以下 OAuth 范围:

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

需要拥有 parent 资源的以下 IAM 权限:

  • routeoptimization.operations.create

如需了解详情,请参阅 IAM 文档。

OptimizeToursUri

rpc OptimizeToursUri(OptimizeToursUriRequest) returns (Operation)

这是 OptimizeToursLongRunning 方法的一种变体,专为具有较大超时值和较大输入/输出大小的优化而设计。

客户端指定存储在 Google Cloud Storage 中的 OptimizeToursRequest 的 URI,服务器将 OptimizeToursResponse 写入客户端指定的 Google Cloud Storage URI。

对于耗时超过几分钟且输入/输出大小超过 8MB 的优化,应优先使用此方法,而不是 OptimizeTours 方法,不过此方法也可用于耗时更短、规模更小的优化。

返回的 long-running operation (LRO) 的名称格式为 <parent>/operations/<operation_id>,可用于跟踪计算进度。metadata 字段类型为 OptimizeToursUriMetadata。如果成功,response 字段类型为 OptimizeToursUriResponse。

授权范围

需要以下 OAuth 范围:

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

需要拥有 parent 资源的以下 IAM 权限:

  • routeoptimization.operations.create

如需了解详情,请参阅 IAM 文档。

AggregatedMetrics

所有 Transition 和/或 Visit(或所有 ShipmentRoute)元素的 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(或ShipmentRoute.metrics.max_loads。

performed_mandatory_shipment_count

int32

执行的强制性配送次数。

实验性:此字段的行为或存在情况将来可能会发生变化。

performed_shipment_penalty_cost_sum

double

已执行配送的 Shipment.penalty_cost 之和。

实验性:此字段的行为或存在情况将来可能会发生变化。

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。此 BreakRule 的 BreakRequest 必须满足所有这些条件。请参阅 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 协议缓冲区文本格式。请参阅 https://protobuf.dev/reference/protobuf/textformat-spec/

DistanceLimit

定义可行驶的最大距离的限制。可以是硬性或软性。

如果定义了软限制,则必须同时定义 soft_max_meters 和 cost_per_kilometer_above_soft_max,且两者都必须为非负数。

字段
max_meters

int64

一个硬性限制,用于将距离限制为最多 max_meters。限制必须是非负数。

soft_max_meters

int64

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

如果定义了 soft_max_meters,则其值必须小于 max_meters 且必须为非负数。

cost_per_kilometer_below_soft_max

double

产生的每公里费用,最高可达 soft_max_meters,计算公式如下:

  min(distance_meters, soft_max_meters) / 1000.0 *
  cost_per_kilometer_below_soft_max.

route_distance_limit 不支持此费用。

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 上所有到访的开始时间和顺序都会受到完全限制,并且无法在这些路线中插入或添加新的到访。此外,除非车辆为空(即没有访问,并且在模型中将 used_if_route_is_empty 设置为 false),否则车辆在 routes 中的开始时间和结束时间会受到完全限制。

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_count 或 threshold_time 时应用放宽级别,请添加两个具有相同 level 的 relaxations:一个仅设置 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 表示正东,以此类推。

OptimizeToursLongRunningMetadata

此类型没有字段。

OptimizeToursLongRunning 调用的操作元数据。

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_index 和 visit_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_routes 或 injected_solution_constraint 一起使用。

Shipment.ignore 和 Vehicle.ignore 对行为没有影响。无论相关运单或车辆是否被忽略,系统仍会在所有非空路线中的所有经停点之间填充多段线。

interpret_injected_solutions_using_labels

bool

如果为 true:

此解释适用于 injected_first_solution_routes、injected_solution_constraint 和 refresh_details_routes 字段。如果请求中的配送或车辆索引自解决方案创建以来发生了变化(可能是因为从请求中移除或添加了配送或车辆),则可以使用此字段。

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

如果注入的解决方案中的 vehicle_label 与请求车辆不对应,则系统会从解决方案中移除相应路线及其经停点。如果注入的解决方案中的 shipment_label 与请求配送不对应,则系统会从解决方案中移除相应的访问。如果注入的解决方案中的 SkippedShipment.label 与请求配送不对应,则会从解决方案中移除 SkippedShipment。

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

注意:调用方必须确保每个 Vehicle.label(或 Shipment.label)唯一标识在两个相关请求中使用的车辆(或配送)实体:产生注入解决方案中使用的 OptimizeToursResponse 的过去请求,以及包含注入解决方案的当前请求。上述唯一性检查不足以保证满足此要求。

consider_road_traffic

bool

在计算 ShipmentRoute 字段 Transition.travel_duration、Visit.start_time 和 vehicle_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 错误载荷,除非 solving_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 求解模型。警告可能会在 [OptimizeToursResponse.validation_errors][google.cloud.optimization.v1.OptimizeToursResponse.validation_errors] 中发出。
VALIDATE_ONLY 仅验证模型而不求解:尽可能多地填充 OptimizeToursResponse.validation_errors。
DETECT_SOME_INFEASIBLE_SHIPMENTS

仅填充 OptimizeToursResponse.validation_errors 或 OptimizeToursResponse.skipped_shipments,而不会实际解决请求的其余部分(status 和 routes 在响应中未设置)。如果检测到 injected_solution_constraint 路线中存在不可行性,系统会在 OptimizeToursResponse.validation_errors 字段中填充这些不可行性,并将 OptimizeToursResponse.skipped_shipments 留空。

重要提示:此处不会返回所有不可行的运单,而只会返回在预处理期间检测到不可行的运单。

TRANSFORM_AND_RETURN_REQUEST

仅当 ShipmentModel.objectives 不为空时,此模式才有效。请求未解决。系统只会验证该参数,并根据给定目标填充费用。另请参阅 ShipmentModel.objectives 的文档。生成的请求将作为 OptimizeToursResponse.processed_request 返回。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/objectives/make-request。

OptimizeToursResponse

解决行程优化问题后返回的响应,其中包含每辆车遵循的路线、已跳过的配送以及解决方案的总费用。

字段
routes[]

ShipmentRoute

为每辆车计算的路线;第 i 条路线对应于模型中的第 i 辆车。

request_label

string

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

skipped_shipments[]

SkippedShipment

所有跳过的配送的列表。

validation_errors[]

OptimizeToursValidationError

我们能够独立检测到的所有验证错误的列表。请参阅 OptimizeToursValidationError 消息的“多项错误”说明。如果 solving_mode 为 DEFAULT_SOLVE,则此操作将包含警告,而不是错误。

processed_request

OptimizeToursRequest

在某些情况下,我们会在求解之前修改传入的请求,例如添加费用。如果 solving_mode == TRANSFORM_AND_RETURN_REQUEST,则修改后的请求会在此处返回。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/objectives/make-request。

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”,值是相应费用字段生成的总费用,在整个解决方案中汇总。换句话说,costs["model.shipments.pickups.cost"] 是解决方案中所有自提费用的总和。此处会详细报告模型中定义的所有费用,但与 TransitionAttributes 相关的费用除外,自 2022 年 1 月起,此类费用仅以汇总方式报告。

total_cost

double

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

OptimizeToursUriMetadata

此类型没有字段。

OptimizeToursUri 调用的操作元数据。

OptimizeToursUriRequest

OptimizeToursUri 方法使用的请求。

字段
parent

string

必需。定位项目或位置以进行调用。

格式:

  • projects/{project-id}
  • projects/{project-id}/locations/-

不支持区域 {location-id} 值。

input

Uri

必需。包含 OptimizeToursRequest 的 Cloud Storage 对象的 URI。

output

Uri

必需。将包含 OptimizeToursResponse 的 Cloud Storage 对象的 URI。

OptimizeToursUriResponse

OptimizeToursUri 方法返回的响应。

字段
output

Uri

可选。包含 OptimizeToursResponse(编码为 JSON 或 textproto)的 Cloud Storage 对象的 URI。如果对象编码为 JSON,则对象名称的扩展名将为 .json。如果对象编码为 textproto,则对象名称的扩展名将为 .txtpb。

资源的 crc32_checksum 可用于验证资源的内容是否未被修改。

OptimizeToursValidationError

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

字段
code

int32

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

此部分后面的字段提供了有关错误的更多背景信息。

多个错误:如果存在多个错误,验证过程会尝试输出其中几个错误。与编译器一样,此过程并不完美。某些验证错误属于“严重”错误,这意味着它们会使整个验证流程停止。display_name="UNSPECIFIED" 错误就是其中的一个例子。某些错误可能会导致验证过程跳过其他错误。

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

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

用于描述错误的直观易懂的字符串。code 和 error_message 之间存在 1:1 的映射关系(当 code != "UNSPECIFIED" 时)。

稳定性:不稳定:与给定 code 关联的出错提示可能会随着时间的推移而发生变化(希望能够更清晰地说明问题)。请改用 display_name 和 code。

offending_values

string

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

FieldReference

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

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

不过,我们会省略 OptimizeToursRequest 或 ShipmentModel 等顶级实体,以免消息过于拥挤。

字段
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 位置。

RouteModifiers

封装一组在计算车辆路线时要满足的可选条件。这与 Google Maps Platform Routes Preferred API 中的 RouteModifiers 类似;请参阅:https://developers.google.com/maps/documentation/routes/reference/rest/v2/RouteModifiers。

字段
avoid_tolls

bool

指定是否在合理的情况下避开收费路段。系统会优先选择不含收费路段的路线。仅适用于机动出行方式。

avoid_highways

bool

指定是否在合理的情况下避开高速公路。系统会优先选择不包含高速公路的路线。仅适用于机动出行方式。

avoid_ferries

bool

指定是否在合理的情况下避开轮渡。系统会优先选择不包含轮渡行程的路线。仅适用于机动出行方式。

avoid_indoor

bool

可选。指定是否在合理的情况下避免室内导航。系统会优先选择不包含室内导航的路线。仅适用于 WALKING 出行方式。

发货

单件物品从取件到送达的运输过程。为了让系统将配送视为已执行,必须由一辆唯一的车辆访问其某个取货地点(并相应地减少其剩余容量),然后访问其某个送货地点(并相应地重新增加其剩余容量)。

字段
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

可能执行此配送的一组车辆。如果为空,则所有车辆都可以执行。车辆由其在 ShipmentModel 的 vehicles 列表中的索引指定。

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_incompatibilities 和 shipment_type_requirements)。

与为单次造访指定的 visit_types 不同:属于同一配送的所有取件/送货都共用同一个 shipment_type。

label

string

为此配送指定标签。此标签会在响应中相应 ShipmentRoute.Visit 的 shipment_label 中报告。

ignore

bool

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

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

允许忽略在 injected_first_solution_routes 或 injected_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_time 和 soft_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。

avoid_u_turns

bool

指定在此位置的驾车路线中是否应避免掉头。系统会尽力避免掉头,但无法保证完全避免。这是一项实验性功能,其行为可能会发生变化。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/u-turn-avoidance/make-request。

ShipmentModel

配送模型包含一组必须由一组车辆执行的配送,同时最大限度地降低总费用,即以下各项的总和:

  • 车辆路线规划费用(所有车辆的总时间费用、行程时间费用和固定费用之和)。
  • 未履行的配送惩罚。
  • 配送总时长对应的费用
字段
shipments[]

Shipment

必须在模型中执行的一组配送。

vehicles[]

Vehicle

可用于执行拜访的一组车辆。

objectives[]

Objective

此模型的目标集,我们将转换为费用。如果非空,则输入模型必须是免费的。如需获取修改后的请求,请使用 solving_mode = TRANSFORM_AND_RETURN_REQUEST。请注意,在这种情况下,请求将无法得到解决。请参阅相应文档。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/objectives/make-request。

global_start_time

Timestamp

模型的全局开始时间和结束时间:此范围之外的时间均视为无效。

模型的时间跨度必须小于一年,即 global_end_time 和 global_start_time 之间的间隔必须在 31536000 秒以内。

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

global_end_time

Timestamp

如果未设置,则默认使用 1971 年 1 月 1 日 00:00:00 UTC(即秒数:31536000,纳秒数: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_tags 和 duration_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 结束路线,使用矩阵“fast”。
  • 1 辆车从 locB 出发,在 locB 结束路线,使用矩阵“slow”。
  • 1 辆车从 locB 出发,在 locB 结束路线,使用矩阵“fast”。
  • 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.tags 或 Vehicle.start_tags。给定的 VisitRequest 或 Vehicle 必须与此字段中的一个标记完全匹配。请注意,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.tags 或 Vehicle.start_tags。给定的 VisitRequest 或 Vehicle 必须与此字段中的一个标记完全匹配。请注意,Vehicle 的来源、目标和矩阵标记可能相同;同样,VisitRequest 的来源和目标标记也可能相同。所有标记都必须不同,且不能是空字符串。如果此字段不为空,则 duration_distance_matrices 不得为空。

transition_attributes[]

TransitionAttributes

添加到模型中的过渡属性。

shipment_type_incompatibilities[]

ShipmentTypeIncompatibility

不兼容的 shipment_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 相同。

目标

目标会完全取代费用模型,因此与预先存在的费用不兼容。每个目标都会映射到多个预定义费用,例如车辆、配送或过渡属性。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/objectives/make-request。

字段
type

Type

目标的类型。

weight

double

此目标相对于其他目标的权重。该值可以是任何非负数,权重总和不必为 1。权重默认为 1.0。

类型

将映射到一组费用的目标类型。

枚举
DEFAULT 系统将使用一组默认费用,以确保提供合理的解决方案。注意:此目标可以单独使用,但如果用户指定的目标中尚未包含此目标,系统也会始终将其作为基准,以 1.0 的权重添加到用户指定的目标中。
MIN_DISTANCE “MIN”目标。最大限度地缩短总行驶距离。
MIN_WORKING_TIME 最大限度地缩短所有车辆的总工作时间。
MIN_TRAVEL_TIME 与上述相同,但仅关注行程时间。
MIN_NUM_VEHICLES 尽可能减少使用的车辆数量。

PrecedenceRule

两个事件之间的优先规则(每个事件都是一个运单的取件或送件):“第二个”事件必须在“第一个”事件开始后至少 offset_duration 开始。

多个优先顺序可以引用相同(或相关)事件,例如“B 的取货发生在 A 的送货之后”和“C 的取货发生在 B 的取货之后”。

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

字段
first_is_delivery

bool

指明“第一个”事件是否为递送。

second_is_delivery

bool

指明“第二个”事件是否为递送。

offset_duration

Duration

“第一个”事件与“第二个”事件之间的时间偏移。该值可以为负数。

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。

放大来看,Transition和Visit期间会发生以下情况:

---+-------------------------------------+-----------------------------+-->
   |           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.transitions 或 ShipmentRoute.visits 进行求和,具体取决于上下文。

vehicle_fullness

VehicleFullness

VehicleFullness 字段,用于计算设置了上限的指标与各自车辆限制的接近程度。其字段是受限指标字段(例如 AggregatedMetrics.travel_distance_meters)与相关车辆限制(例如 Vehicle.route_distance_limit)之间的比率。

实验性:此字段的行为或存在情况将来可能会发生变化。

route_costs

map<string, double>

路线费用,按与费用相关的请求字段细分。键是相对于输入 OptimizeToursRequest 的 proto 路径,例如“model.shipments.pickups.cost”,值是相应费用字段生成的总费用,在整条路线上汇总。换句话说,costs["model.shipments.pickups.cost"] 是路线中所有自提费用的总和。此处会详细报告模型中定义的所有费用,但与 TransitionAttributes 相关的费用除外,自 2022 年 1 月起,此类费用仅以汇总方式报告。

route_total_cost

double

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

休息时间

表示广告插播时间点执行情况的数据。

字段
start_time

Timestamp

休息时间的开始时间。

duration

Duration

休息时长。

EncodedPolyline

多段线的编码表示法。如需详细了解多段线编码,请访问以下网址:https://developers.google.com/maps/documentation/utilities/polylinealgorithm https://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 时,系统才会填充此字段。

route_token

string

仅限输出。一个不透明令牌,可传递给 Navigation SDK,以便在导航期间重建路线,并在重新规划路线时遵循创建路线时的原始意图。请将此令牌视为不透明 blob。请勿在不同请求之间比较其值,因为即使服务返回完全相同的路线,其值也可能会发生变化。仅当 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

来源 ShipmentModel 中 shipments 字段的索引。

is_pickup

bool

如果为 true,则表示该次造访对应于 Shipment 的取货。否则,它对应于一次配送。

visit_request_index

int32

VisitRequest 在 Shipment 的取货或送货字段中的索引(请参阅 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 中指定)。

visit_type

VisitType

可选。指定访问类型。替换 Visit.is_pickup 字段。

injected_solution_location_token

int32

一个不透明令牌,表示有关到访地点的信息。

如果此经停点的 VisitRequest.avoid_u_turns 设置为 true,或者请求 OptimizeToursRequest 中的 ShipmentModel.avoid_u_turns 设置为 true,则此字段可能会填充到结果路线的经停点中。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/u-turn-avoidance/make-request。

VisitType

指明此次到访是自提、送货还是到访 Stop。仅当启用了多模态优化时,系统才会使用对停靠点的访问。

枚举
VISIT_TYPE_UNSPECIFIED 未指定访问类型。
PICKUP_SHIPMENT 到访对应于取件。
DELIVER_SHIPMENT 到访对应于配送。

ShipmentTypeIncompatibility

指定运单之间的不兼容性,具体取决于其 shipment_type。不兼容的运单在同一路线上的出现情况会根据不兼容模式受到限制。

字段
types[]

string

不兼容的类型列表。如果两个配送任务在所列属性中具有不同的 shipment_types,则它们“不兼容”。

incompatibility_mode

IncompatibilityMode

应用于不兼容问题的模式。

IncompatibilityMode

定义如何在同一路线上限制不兼容运单的出现。

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

在此模式下,类型不兼容的两个配送任务绝不能同时由同一辆车执行:

  • 只有在其中一个订单送达后,另一个订单才会被取走,这样它们才能共用同一辆车。
  • 如果两个配送任务都仅限取货(无送货)或仅限送货(无取货),则它们根本无法共用同一辆车。

ShipmentTypeRequirement

根据配送类型指定配送之间的要求。要求的具体内容由要求模式定义。

字段
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。如果我们无法理解为何跳过某个配送,则不会设置原因。

penalty_cost

double

这是 Shipment.penalty_cost 的副本,在此处添加是为了让您更轻松地了解跳过配送的严重程度。

实验性:此字段的行为或存在情况将来可能会发生变化。

estimated_incompatible_vehicle_ratio

double

预计因以下至少一个原因而无法执行此配送任务的车辆比例。注意:只有在原因涉及车辆时,系统才会填充此字段。

实验性:此字段的行为或存在情况将来可能会发生变化。

原因

如果我们能解释为何跳过该配送,原因将列在此处。如果并非所有车辆的原因都相同,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

请参阅 Code 的注释。

example_vehicle_indices[]

int32

与 example_vehicle_index 相同,但我们会提供多个已识别车辆的列表。此列表不一定详尽无遗。仅当 [fill_example_vehicle_indices_in_skipped_reasons][] 为 true 时,系统才会填充此字段。

实验性:此字段的行为或存在情况将来可能会发生变化。

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 字段不为空,且此车辆不属于该字段。
VEHICLE_IGNORED

车辆的 ignore 字段为 true。

实验性:此字段的行为或存在情况将来可能会发生变化。

SHIPMENT_IGNORED

配送的 ignore 字段为 true。

实验性:此字段的行为或存在情况将来可能会发生变化。

SKIPPED_IN_INJECTED_SOLUTION_CONSTRAINT

injected_solution_constraint 中跳过了该配送。

实验性:此字段的行为或存在情况将来可能会发生变化。

VEHICLE_ROUTE_IS_FULLY_SEQUENCE_CONSTRAINED

injected_solution_constraint 中指定的车辆路线放宽条件不允许插入任何经停点。

实验性:此字段的行为或存在情况将来可能会发生变化。

ZERO_PENALTY_COST

该配送的惩罚费用为零。虽然这可以作为一种高级建模选择,但也可以在事后解释为何跳过了某个配送。

实验性:此字段的行为或存在情况将来可能会发生变化。

TimeWindow

时间窗口会限制事件的时间,例如到达访问地点的时间,或车辆的开始和结束时间。

硬性时间窗口边界 start_time 和 end_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_time、end_time、soft_start_time 和 soft_end_time 应在全局时间限制内(请参阅 ShipmentModel.global_start_time 和 ShipmentModel.global_end_time),并且应遵循:

  0 <= `start_time` <= `end_time` and
  0 <= `start_time` <= `soft_start_time` and
  0 <= `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

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

当且仅当来源访问或车辆开始的 VisitRequest.tags 或 Vehicle.start_tags 包含 src_tag 或不包含 excluded_src_tag(取决于这两个字段中哪个字段不为空)时,该来源访问或车辆开始才匹配。

excluded_src_tag

string

请参阅 src_tag。src_tag 和 excluded_src_tag 中必须且只能有一个不为空。

dst_tag

string

当且仅当目的地访问或车辆结束的 VisitRequest.tags 或 Vehicle.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

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

此延迟始终发生在完成来源访问之后和开始目标访问之前。

URI

指向可由 Route Optimization API 读取和写入的资源的通用资源标识符。

字段
uri

string

资源的 URI。资源可能尚不存在。

资源的内容会编码为 JSON 或 textproto。仅支持 Google Cloud Storage 资源。如果资源编码为 JSON,则资源名称必须带有 .json 后缀。如果资源编码为 textproto,则资源名称必须带有 .txtpb 后缀。例如,指向 JSON 编码文件的 Google Cloud Storage URI 可能如下所示:gs://bucket/path/input/object.json。

交通工具

为配送问题中的车辆建模。解决配送问题后,系统会为此车辆构建一条从 start_location 开始到 end_location 结束的路线。路线是一系列到访(请参阅 ShipmentRoute)。

字段
display_name

string

用户定义的车辆显示名称。最多可包含 63 个字符,并且可以使用 UTF-8 字符。

travel_mode

TravelMode

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

route_modifiers

RouteModifiers

一组需要满足的条件,这些条件会影响给定车辆的路线计算方式。

start_location

LatLng

车辆在取任何货物之前启动的地理位置。如果未指定,则车辆从其第一个取件点开始。如果配送模型具有时长和距离矩阵,则不得指定 start_location。

start_waypoint

Waypoint

表示车辆在取任何货物之前出发的地理位置的航点。如果既未指定 start_waypoint,也未指定 start_location,则车辆从其第一个取件点开始。如果配送模型具有时长和距离矩阵,则不得指定 start_waypoint。

end_location

LatLng

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

end_waypoint

Waypoint

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

start_tags[]

string

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

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

end_tags[]

string

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

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

start_time_windows[]

TimeWindow

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

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

只有在存在单个时间窗口时,才能设置 cost_per_hour_after_soft_end_time 和 soft_end_time。

end_time_windows[]

TimeWindow

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

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

只有在存在单个时间窗口时,才能设置 cost_per_hour_after_soft_end_time 和 soft_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 中报告的距离,不适用于从单个 VisitRequest 的 arrival_location 到 departure_location 隐式行驶的任何距离。

fixed_cost

double

如果使用此车辆处理配送,则会应用固定费用。

used_if_route_is_empty

bool

此字段仅适用于路线不配送任何运单的车辆。它指明在这种情况下是否应将车辆视为正在使用中。

如果为 true,则车辆会从其起始位置前往其结束位置,即使它不运送任何货物也是如此,并且系统会考虑其起始位置 -> 结束位置行程所产生的时间和距离费用。

否则,该车辆不会从其起始位置行驶到其结束位置,并且系统不会为此车辆安排任何 break_rule 或延迟(从 TransitionAttributes 开始)。在这种情况下,车辆的 ShipmentRoute 不包含除车辆索引和标签以外的任何信息。

route_duration_limit

DurationLimit

对车辆路线总时长施加的限制。在给定的 OptimizeToursResponse 中,车辆的路线时长是其 vehicle_end_time 与 vehicle_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

为此车辆指定标签。此标签在响应中报告为相应 ShipmentRoute 的 vehicle_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_hour 或 cost_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

可接受的最大负载量。

cost_per_kilometer

LoadCost

此车辆将一个单位的负载移动一公里所需的费用。这可以用作燃料消耗量的代理:如果负载是重量(以牛顿为单位),则负载*公里具有能量维度。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/load-cost/make-request。

cost_per_traveled_hour

LoadCost

此车辆在 1 小时内运送一个单位的负载的费用。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/load-cost/make-request。

间隔

可接受的负载量区间。

字段
min

int64

可接受的最低负载。必须 ≥ 0。如果同时指定了这两个参数,则 min 必须小于或等于 max。

max

int64

可接受的最大负载。必须 ≥ 0。如果未指定,则此消息不会限制最大负载。如果同时指定了这两个参数,则 min 必须小于或等于 max。

LoadCost

在Transition期间移动一个单位的负载所需的费用。对于给定的负载,费用由两部分组成:

  • min(load, load_threshold) * cost_per_unit_below_threshold
  • max(0, load - load_threshold) * cost_per_unit_above_threshold

有了这项费用,解决方案会优先配送高需求,或者最后取货高需求。例如,如果车辆有

load_limit {
  key: "weight"
  value {
    cost_per_kilometer {
      load_threshold: 15
      cost_per_unit_below_threshold: 2.0
      cost_per_unit_above_threshold: 10.0
    }
  }
}

其路线为“开始、取件、取件、送货、送货、结束”,并具有以下转换:

transition { vehicle_load['weight'] { amount: 0 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 20 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 0 }
             travel_distance_meters: 1000.0 }

则此 LoadCost 产生的费用为 (cost_below * load_below * kilometers + cost_above * load_above * kms)

  • transition 0: 0.0
  • 转换 1:2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • 转换 2:2.0 * 15 * 1.0 + 10.0 * (20 - 15) * 1.0 = 80.0
  • 转换 3:2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • transition 4: 0.0

因此,该路线的 LoadCost 为 120.0。

但是,如果路线为“起点、取件、送件、取件、送件、终点”,且具有以下转换:

transition { vehicle_load['weight'] { amount: 0 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 0 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 10 }
             travel_distance_meters: 1000.0 }
transition { vehicle_load['weight'] { amount: 0 }
             travel_distance_meters: 1000.0 }

则此 LoadCost 产生的费用为

  • transition 0: 0.0
  • 转换 1:2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • transition 2: 0.0
  • 转换 3:2.0 * 10 * 1.0 + 10.0 * 0 * 1.0 = 20.0
  • transition 4: 0.0

此处,路线上的 LoadCost 为 40.0。

LoadCost 会使具有重载过渡的解决方案成本更高。

实验性:如需了解详情,请参阅 https://developers.google.com/maps/tt/route-optimization/experimental/load-cost/make-request。

字段
load_threshold

int64

当负载量超过此值时,移动一个单位负载的费用会从 cost_per_unit_below_threshold 变为 cost_per_unit_above_threshold。必须大于等于 0。

cost_per_unit_below_threshold

double

移动一个单位的负载的费用,适用于 0 到阈值之间的每个单位。必须是有限值,且 >= 0。

cost_per_unit_above_threshold

double

移动一个单位负载的费用(针对超出阈值的每个单位)。在阈值 = 0 的特殊情况下,这是每单位的固定费用。必须是有限值,且 >= 0。

TravelMode

车辆可以使用的出行方式。

这些应是 Google Maps Platform Routes API 出行方式的子集,请参阅:https://developers.google.com/maps/documentation/routes/reference/rest/v2/RouteTravelMode

注意:WALKING路线功能目前处于 Beta 版阶段,有时可能无法提供清晰的人行道或步道。对于应用中显示的所有步行路线,您都必须向用户显示此警告。

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

UnloadingPolicy

关于如何卸载车辆的政策。仅适用于同时具有取件和送件的运单。

其他配送可以独立于 unloading_policy 在路线上的任何位置进行。

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

VehicleFullness

VehicleFullness 是一个用于计算车辆满载程度的指标。每个 VehicleFullness 字段的值介于 0 到 1 之间,计算方式为:有上限的指标字段(例如 AggregatedMetrics.travel_distance_meters)与其相关车辆限制(例如 Vehicle.route_distance_limit,如果存在)之间的比率。否则,满载率将保持未设置状态。如果限制为 0,则该字段会设置为 1。注意:如果路线存在流量不可行性,某些原始满载率可能会超过 1.0,例如车辆可能会超出其距离限制。在这些情况下,我们会将满载度值限制为 1.0。

字段
max_fullness

double

此消息中所有其他字段的最大值。

distance

double

AggregatedMetrics.travel_distance_meters 与 Vehicle.route_distance_limit 之间的比率。如果未设置 Vehicle.route_distance_limit,则此字段将不设置。

travel_duration

double

[AggregatedMetrics.travel_duration_seconds][] 与 Vehicle.travel_duration_limit 之间的比率。如果未设置 Vehicle.travel_duration_limit,则此字段将不设置。

active_duration

double

[AggregatedMetrics.total_duration_seconds][] 与 Vehicle.route_duration_limit 之间的比率。如果未设置 Vehicle.route_duration_limit,则此字段将处于未设置状态。

max_load

double

所有类型的 [AggregatedMetrics.max_load][] 与其各自 Vehicle.load_limits 之间的最大比率。如果所有 Vehicle.load_limits 字段均未设置,则此字段将不会设置。

active_span

double

指定车辆的比率 (vehicle_end_time - vehicle_start_time) / (latest_vehicle_end_time - earliest_vehicle_start_time)。如果分母不存在,则改用 (ShipmentModel.global_end_time - ShipmentModel.global_start_time)。

航点

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

字段
side_of_road

bool

可选。表示此航点的位置旨在让车辆优先停靠在道路的特定一侧。设置此值后,路线将经过该位置,以便车辆可以在该位置偏向道路中心的一侧停车。此选项不适用于“WALKING”出行方式。

vehicle_stopover

bool

表示航点是供车辆停靠的,目的是接载或下客。此选项仅适用于“DRIVING”出行方式,且“location_type”为“location”。

实验性:此字段的行为或存在情况将来可能会发生变化。

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

Location

使用地理坐标指定的点,包括可选的航向。

place_id

string

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

使用地点 ID 指定 VisitRequest 的到达或出发地点时,请使用足够具体的地点 ID,以便确定用于导航到该地点的 LatLng 位置。例如,代表建筑物的地点 ID 是合适的,但不建议使用代表道路的地点 ID。