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)。系统会以用户指定的格式从 Cloud Storage 读取优化输入(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,这些 ShipmentRoute 是车辆执行的一组路线,可最大限度地降低总费用。

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 字段类型为 OptimizeToursLongRunningMetadata。如果成功,response 字段类型为 OptimizeToursUriResponse。

授权范围

需要以下 OAuth 范围:

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

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

  • routeoptimization.operations.create

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

AggregatedMetrics

ShipmentRoute(对于所有 Transition 和/或 Visit 的 OptimizeToursResponse,分别为所有 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。

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 小时的滑动时间窗口内,必须至少有一次至少 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 协议缓冲区文本格式。请参阅 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

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

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

如果为真:

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

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

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

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

注意:调用方必须确保每个 Vehicle.label(resp. 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

如果设置此值,则请求可以设置最长 60 分钟的截止期限(请参阅 https://grpc.io/blog/deadlines)。否则,最长期限只有 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

截断返回的验证错误数量。这些错误通常附加到 INVALID_ARGUMENT 错误载荷中,作为 BadRequest 错误详情 (https://cloud.google.com/apis/design/errors#error_details),除非 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 留空。

重要提示:此处不会返回所有不可行的配送方式,而只会返回在预处理期间被检测为不可行的配送方式。

OptimizeToursResponse

解决巡回优化问题后的响应,其中包含每辆车行驶的路线、已跳过的运输以及解决方案的总费用。

字段
routes[]

ShipmentRoute

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

request_label

string

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

skipped_shipments[]

SkippedShipment

所有已跳过的配送的列表。

validation_errors[]

OptimizeToursValidationError

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

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

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

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

OptimizeToursValidationError

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

字段
code

int32

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

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

MULTIPLE ERRORS:如果存在多个错误,验证流程会尝试输出其中的多个错误。与编译器类似,这并不是一个完美的流程。某些验证错误会是“严重”错误,这意味着它们会停止整个验证流程。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 之间是一对一的映射关系(当 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。

ShipmentModel

运输模型包含一组必须由一组车辆执行的运输,同时尽可能降低总费用,总费用是以下各项的总和:

  • 车辆路线规划费用(所有车辆的总时间费用、行驶时间费用和固定费用的总和)。
  • 未履行发货义务的处罚。
  • 运输全程的费用
字段
shipments[]

Shipment

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

vehicles[]

Vehicle

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

global_start_time

Timestamp

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

模型的时间跨度不得超过 1 年,即 global_end_time 和 global_start_time 之间的时间差必须不超过 31536000 秒。

使用 cost_per_*hour 字段时,您可能需要将此时间范围设置为更短的时间间隔,以提高性能(例如,如果您对单日进行建模,则应将全局时间限制设置为该日)。如果未设置,则默认使用 1970 年 1 月 1 日 00:00:00 UTC(即秒数: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。
  • 在 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.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)(resp. 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_type 组合(请参阅 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 匹配)。

所有矩阵都必须具有不同的 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

指示“第二个”事件是否为传送事件。

offset_duration

Duration

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

first_index

int32

“first”事件的配送指数。必须指定此字段。

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

此路线的时长、距离和载荷指标。系统会对所有 ShipmentRoute.transitions 或 ShipmentRoute.visits 中的 AggregatedMetrics 字段进行求和,具体取决于上下文。

route_costs

map<string, double>

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

route_total_cost

double

路线的总费用。费用图中所有费用的总和。

休息时间

表示执行 break 的数据。

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

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

根据 shipment_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

根据 shipment_type 指定不同配送方式之间的要求。具体要求由要求模式定义。

字段
required_shipment_type_alternatives[]

string

dependent_shipment_types 所需的备选配送类型列表。

dependent_shipment_types[]

string

对于 dependent_shipment_types 字段中类型为 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 模式下,所有“依赖”运输服务的运输订单在取件时都需要在车辆上装载至少 1 个“必需”运输服务的运输订单。

因此,“依赖”的商品自提必须具有以下任一属性:

  • 仅送货的“必需”运输服务,在以下时间之后或
  • 在同一路线上先前接收的“必需”运输包裹。如果“必需”运输包裹有送货服务,则此送货服务必须在“依赖”运输包裹被接收后执行。
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_time 和 end_time 用于强制执行事件的最早和最晚时间,例如 start_time <= event_time <= end_time。软时间范围下限 soft_start_time 表示希望事件在 soft_start_time 当天或之后发生,如果事件发生在 soft_start_time 之前,则会产生与事件发生在 soft_start_time 之前的时间长度成正比的费用。软时间范围上限 soft_end_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

用于定义要应用这些属性的一组 (src->dst) 转场效果的标记。

来源访问或车辆启动匹配的条件是:其 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。

md5_hash

string

仅限输出。资源内容的 MD5 哈希。用户无需提供哈希。该值由服务器计算,以便用户验证服务器返回的资源内容是否未经修改。请参阅 https://cloud.google.com/storage/docs/data-validation#integrity。

交通工具

模拟运输问题中的车辆。解决运输问题后,系统会为此车辆构建一条起点为 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,则会应用以下费用惩罚(每辆车仅应用一次):(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,则 min 必须小于等于 max。

max

int64

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

TravelMode

车辆可使用的出行方式。

这些应是 Google Maps Platform 路线首选 API 出行方式的子集,请参阅:https://developers.google.com/maps/documentation/routes_preferred/reference/rest/Shared.Types/RouteTravelMode。

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

UnloadingPolicy

有关如何卸车的政策。仅适用于同时包含自提和送货服务的配送。

其他运输可以随意在路线上的任何位置进行,不受 unloading_policy 的影响。

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

关键点

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

字段
side_of_road

bool

可选。指示此航点的位置是指示车辆在道路的特定侧停车的偏好设置。设置此值后,路线将穿过相应位置,以便车辆能够停靠在相应位置偏离道路中心的一侧。此选项不适用于“步行”出行方式。

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

Location

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

place_id

string

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