ShipmentModel

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

  • 车辆路线规划费用(所有车辆的总时间费用、行驶时间费用和固定费用的总和)。
  • 未履行发货义务的处罚。
  • 运输全程的费用
JSON 表示法
{
  "shipments": [
    {
      object (Shipment)
    }
  ],
  "vehicles": [
    {
      object (Vehicle)
    }
  ],
  "globalStartTime": string,
  "globalEndTime": string,
  "globalDurationCostPerHour": number,
  "durationDistanceMatrices": [
    {
      object (DurationDistanceMatrix)
    }
  ],
  "durationDistanceMatrixSrcTags": [
    string
  ],
  "durationDistanceMatrixDstTags": [
    string
  ],
  "transitionAttributes": [
    {
      object (TransitionAttributes)
    }
  ],
  "shipmentTypeIncompatibilities": [
    {
      object (ShipmentTypeIncompatibility)
    }
  ],
  "shipmentTypeRequirements": [
    {
      object (ShipmentTypeRequirement)
    }
  ],
  "precedenceRules": [
    {
      object (PrecedenceRule)
    }
  ],
  "maxActiveVehicles": integer
}
字段
shipments[]

object (Shipment)

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

vehicles[]

object (Vehicle)

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

globalStartTime

string (Timestamp format)

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

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

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

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

globalEndTime

string (Timestamp format)

如果未设置,系统会默认使用 1971 年 1 月 1 日 00:00:00 UTC(即秒数:31536000,纳秒数:0)。

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

globalDurationCostPerHour

number

整个方案的“总时长”是指所有车辆的最早有效开始时间与最晚有效结束时间之间的差值。例如,用户可以为该数量分配每小时费用,以便尽可能优化作业完成时间。此费用必须与 Shipment.penalty_cost 采用相同的单位。

durationDistanceMatrices[]

object (DurationDistanceMatrix)

指定模型中使用的时长和距离矩阵。如果此字段为空,系统将改用 Google 地图或大地距离,具体取决于 useGeodesicDistances 字段的值。如果不为空,useGeodesicDistances 不能为 true,并且 durationDistanceMatrixSrcTagsdurationDistanceMatrixDstTags 都不能为空。

用法示例:

  • 有两个位置:locA 和 locB。
  • 1 辆车辆,其路线的起点和终点均为 locA。
  • 在 locB 有 1 个自提服务访问请求。
model {
  vehicles { startTags: "locA"  endTags: "locA" }
  shipments { pickups { tags: "locB" } }
  durationDistanceMatrixSrcTags: "locA"
  durationDistanceMatrixSrcTags: "locB"
  durationDistanceMatrixDstTags: "locA"
  durationDistanceMatrixDstTags: "locB"
  durationDistanceMatrices {
    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 { startTags: "locA" endTags: "locB" startTags: "fast" }
  vehicles { startTags: "locB" endTags: "locB" startTags: "slow" }
  vehicles { startTags: "locB" endTags: "locB" startTags: "fast" }
  shipments { pickups { tags: "locC" } }
  durationDistanceMatrixSrcTags: "locA"
  durationDistanceMatrixSrcTags: "locB"
  durationDistanceMatrixSrcTags: "locC"
  durationDistanceMatrixDstTags: "locB"
  durationDistanceMatrixDstTags: "locC"
  durationDistanceMatrices {
    vehicleStartTag: "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
    }
  }
  durationDistanceMatrices {
    vehicleStartTag: "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
    }
  }
}
durationDistanceMatrixSrcTags[]

string

用于定义时长和距离矩阵来源的标记;durationDistanceMatrices(i).rows(j) 用于定义标记为 durationDistanceMatrixSrcTags(j) 的访问与矩阵 i 中的其他访问之间的时长和距离。

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

durationDistanceMatrixDstTags[]

string

用于定义时长和距离矩阵目的地的标记;durationDistanceMatrices(i).rows(j).durations(k)(resp. durationDistanceMatrices(i).rows(j).meters(k)) 用于定义矩阵 i 中标记为 durationDistanceMatrixSrcTags(j) 的访问到标记为 durationDistanceMatrixDstTags(k) 的访问之间的行程时长(或距离)。

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

transitionAttributes[]

object (TransitionAttributes)

添加到模型的转换属性。

shipmentTypeIncompatibilities[]

object (ShipmentTypeIncompatibility)

不兼容的 shipment_type 组合(请参阅 ShipmentTypeIncompatibility)。

shipmentTypeRequirements[]

object (ShipmentTypeRequirement)

一系列 shipmentType 要求(请参阅 ShipmentTypeRequirement)。

precedenceRules[]

object (PrecedenceRule)

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

maxActiveVehicles

integer

限制有效车辆的数量上限。如果车辆的路线至少执行了一次运输,则该车辆处于活跃状态。如果驾驶员数量少于车辆数量,并且车队是异构的,则可以使用此参数来限制路线数量。然后,优化功能会选择最佳的车辆子集。必须为严格正值。

发货

单个商品从取件到送达的运输过程。为了将运输作业视为已完成,唯一车辆必须先访问其某个取件地点(并相应地减少其空闲运力),然后稍后访问其某个送货地点(并相应地重新增加其空闲运力)。

JSON 表示法
{
  "displayName": string,
  "pickups": [
    {
      object (VisitRequest)
    }
  ],
  "deliveries": [
    {
      object (VisitRequest)
    }
  ],
  "loadDemands": {
    string: {
      object (Load)
    },
    ...
  },
  "allowedVehicleIndices": [
    integer
  ],
  "costsPerVehicle": [
    number
  ],
  "costsPerVehicleIndices": [
    integer
  ],
  "pickupToDeliveryAbsoluteDetourLimit": string,
  "pickupToDeliveryTimeLimit": string,
  "shipmentType": string,
  "label": string,
  "ignore": boolean,
  "penaltyCost": number,
  "pickupToDeliveryRelativeDetourLimit": number
}
字段
displayName

string

用户为运输订单定义的显示名称。此字符串不得超过 63 个字符,并且可以使用 UTF-8 字符。

pickups[]

object (VisitRequest)

与运输订单关联的一组取件选项。如果未指定,车辆只需访问与送货地点对应的地点即可。

deliveries[]

object (VisitRequest)

与运输订单关联的一组配送替代方案。如果未指定,车辆只需访问与上车点对应的地点即可。

loadDemands

map (key: string, value: object (Load))

运输的载荷需求(例如重量、体积、托盘数量等)。映射中的键应为描述相应负载类型的标识符,最好还包含单位。例如:“weight_kg”“volume_gallons”“pallet_count”等。如果给定键未出现在映射中,则相应的载荷会被视为 null。

allowedVehicleIndices[]

integer

可能执行此运输的车辆组。如果为空,则所有车辆都可以执行此操作。车辆由 ShipmentModelvehicles 列表中的编号指定。

costsPerVehicle[]

number

指定使用每辆车辆运送此运输时产生的费用。如果指定了,则必须具有以下任一属性:

  • costsPerVehicleIndices 具有相同数量的元素。costsPerVehicle[i] 对应于该型号的车辆 costsPerVehicleIndices[i]
  • 元素数量与模型中的车辆数量相同。第 i 个元素对应于该型号的车辆 #i。

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

costsPerVehicleIndices[]

integer

应用 costsPerVehicle 的车辆的索引。如果不为空,则必须与 costsPerVehicle 具有相同数量的元素。车辆编号不得重复指定。如果某辆车辆从 costsPerVehicleIndices 中排除,则其费用为零。

pickupToDeliveryAbsoluteDetourLimit

string (Duration format)

指定与从上车点到下车点的最短路线相比的绝对绕道时间上限。如果指定,则必须为非负数,并且运输必须至少包含一个上门取件和一个送货。

例如,设 t 为从所选的取件替代方案直接前往所选的送货替代方案所需的最短时间。然后,设置 pickupToDeliveryAbsoluteDetourLimit 会强制执行以下操作:

startTime(delivery) - startTime(pickup) <=
t + pickupToDeliveryAbsoluteDetourLimit

如果同一运输中同时指定了相对上限和绝对上限,系统会对每个可能的取件/送货对使用更严格的上限。自 2017 年 10 月起,只有在行程时长不依赖于车辆时,才支持绕道。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

pickupToDeliveryTimeLimit

string (Duration format)

指定从取件开始到送货开始的最长时长。如果指定,则必须为非负数,并且运输必须至少包含一个上门取件和一个送货。这不取决于为上门取件和送货选择了哪些替代方案,也不取决于车辆速度。此参数可与最大绕行限制一起指定:解决方案将遵循这两项规范。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

shipmentType

string

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

与仅针对单次访问指定的 visitTypes 不同:同一配送订单中的所有自提/送货服务共用相同的 shipmentType

label

string

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

ignore

boolean

如果为 true,则跳过此配送,但不应用 penaltyCost

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

允许忽略在 injectedFirstSolutionRoutesinjectedSolutionConstraint 中执行的运输;求解器会从执行路线中移除相关的取件/送货拜访。引用已忽略的配送的 precedenceRules 也会被忽略。

penaltyCost

number

如果未能完成运输,此处罚金将计入路线的总费用。如果客户选择了某个取件和送货选项,并已前往该选项的取件点或送货地址,则系统会将相应运单视为已完成。费用可以使用模型中所有其他与费用相关的字段所用的相同单位表示,并且必须为正值。

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

pickupToDeliveryRelativeDetourLimit

number

指定与从上车点到下车点的最短路径相比的最大相对绕路时间。如果指定,则必须为非负数,并且运输必须至少包含一个上门取件和一个送货。

例如,设 t 为从所选的取件替代方案直接前往所选的送货替代方案所需的最短时间。然后,设置 pickupToDeliveryRelativeDetourLimit 会强制执行以下操作:

startTime(delivery) - startTime(pickup) <=
std::ceil(t * (1.0 + pickupToDeliveryRelativeDetourLimit))

如果同一运输中同时指定了相对上限和绝对上限,系统会对每个可能的取件/送货对使用更严格的上限。自 2017 年 10 月起,只有在行程时长不依赖于车辆时,才支持绕道。

VisitRequest

请求由车辆完成的访问:它具有一个(或两个,见下文)地理位置、由时间范围表示的开业和打烊时间,以及服务时长(车辆到达取件或送货地点后所花的时间)。

JSON 表示法
{
  "arrivalLocation": {
    object (LatLng)
  },
  "arrivalWaypoint": {
    object (Waypoint)
  },
  "departureLocation": {
    object (LatLng)
  },
  "departureWaypoint": {
    object (Waypoint)
  },
  "tags": [
    string
  ],
  "timeWindows": [
    {
      object (TimeWindow)
    }
  ],
  "duration": string,
  "cost": number,
  "loadDemands": {
    string: {
      object (Load)
    },
    ...
  },
  "visitTypes": [
    string
  ],
  "label": string
}
字段
arrivalLocation

object (LatLng)

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

arrivalWaypoint

object (Waypoint)

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

departureLocation

object (LatLng)

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

departureWaypoint

object (Waypoint)

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

tags[]

string

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

timeWindows[]

object (TimeWindow)

用于约束到达时间的访问时间窗口。请注意,车辆可能会在到达时间范围之外出发,即到达时间 + 时长不必在时间范围内。如果车辆在 TimeWindow.start_time 之前到达,则可能会导致等待时间。

如果没有 TimeWindow,则表示车辆可以随时执行此访问。

时间窗口必须互不重叠,即任何时间窗口都不能与其他时间窗口重叠或相邻,并且必须按升序排列。

只有在只有一个时间窗口时,才能设置 costPerHourAfterSoftEndTimesoftEndTime

duration

string (Duration format)

访问时长,即车辆从到达到离开所用的时间(应与可能的等待时间相加;请参阅 timeWindows)。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

cost

number

在车辆路线上处理此访问请求的费用。您可以使用此账号为每笔包裹的每种备选自提或外卖服务支付不同的费用。此费用必须与 Shipment.penalty_cost 采用相同的单位,并且不得为负数。

loadDemands

map (key: string, value: object (Load))

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

visitTypes[]

string

指定访问类型。此值可用于分配车辆完成此访问所需的额外时间(请参阅 Vehicle.extra_visit_duration_for_visit_type)。

一种类型只能出现一次。

label

string

为此 VisitRequest 指定标签。此标签在响应中报告为相应 ShipmentRoute.Visit 中的 visitLabel

LatLng

表示纬度/经度对的对象。该对象以一对双精度数表示,分别代表纬度度数和经度度数。除非另有说明,否则该对象必须符合 WGS84 标准。值必须介于标准化范围内。

JSON 表示法
{
  "latitude": number,
  "longitude": number
}
字段
latitude

number

纬度(以度为单位)。它必须在 [-90.0, +90.0] 范围内。

longitude

number

经度(以度为单位)。它必须在 [-180.0, +180.0] 范围内。

关键点

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

JSON 表示法
{
  "sideOfRoad": boolean,

  // Union field location_type can be only one of the following:
  "location": {
    object (Location)
  },
  "placeId": string
  // End of list of possible types for union field location_type.
}
字段
sideOfRoad

boolean

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

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

object (Location)

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

placeId

string

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

位置

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

JSON 表示法
{
  "latLng": {
    object (LatLng)
  },
  "heading": integer
}
字段
latLng

object (LatLng)

航点的地理坐标。

heading

integer

与交通流方向相关联的罗盘方向。此值用于指定上车点和下车点所在的道路边。航向值介于 0 到 360 之间,其中 0 指定正北,90 指定正东,依此类推。

TimeWindow

时间范围用于约束事件的时间,例如到达时间或车辆的开始时间和结束时间。

硬性时间范围边界 startTimeendTime 用于强制执行事件的最早和最晚时间,例如 startTime <= event_time <= endTime。软时间范围下限 softStartTime 表示希望事件在 softStartTime 或之后发生,通过使事件发生在 softStartTime 之前的时间与代价成正比来实现这一点。软时间范围上限 softEndTime 表示希望事件在 softEndTime 当天或之前发生,如果事件发生在 softEndTime 之后,则会产生与事件发生在 softEndTime 之后的时长成正比的代价。startTimeendTimesoftStartTimesoftEndTime 应在全球时间限制范围内(请参阅 ShipmentModel.global_start_timeShipmentModel.global_end_time),并且应遵循以下要求:

  0 <= `startTime` <= `endTime` and
  0 <= `startTime` <= `softStartTime` and
  0 <= `softEndTime` <= `endTime`.
JSON 表示法
{
  "startTime": string,
  "endTime": string,
  "softStartTime": string,
  "softEndTime": string,
  "costPerHourBeforeSoftStartTime": number,
  "costPerHourAfterSoftEndTime": number
}
字段
startTime

string (Timestamp format)

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

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

endTime

string (Timestamp format)

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

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

softStartTime

string (Timestamp format)

时间段的软开始时间。

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

softEndTime

string (Timestamp format)

时间范围的非强制性结束时间。

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

costPerHourBeforeSoftStartTime

number

如果事件发生在 softStartTime 之前,则向模型中的其他费用添加每小时费用,计算方式如下:

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

此费用必须为正数,并且只有在设置了 softStartTime 后才能设置此字段。

costPerHourAfterSoftEndTime

number

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

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

此费用必须为正数,并且只有在设置了 softEndTime 后才能设置此字段。

交通工具

模拟运输问题中的车辆。解决运输问题后,系统会为此车辆构建一条起点为 startLocation、终点为 endLocation 的路线。路线是一系列到访记录(请参阅 ShipmentRoute)。

JSON 表示法
{
  "displayName": string,
  "travelMode": enum (TravelMode),
  "routeModifiers": {
    object (RouteModifiers)
  },
  "startLocation": {
    object (LatLng)
  },
  "startWaypoint": {
    object (Waypoint)
  },
  "endLocation": {
    object (LatLng)
  },
  "endWaypoint": {
    object (Waypoint)
  },
  "startTags": [
    string
  ],
  "endTags": [
    string
  ],
  "startTimeWindows": [
    {
      object (TimeWindow)
    }
  ],
  "endTimeWindows": [
    {
      object (TimeWindow)
    }
  ],
  "unloadingPolicy": enum (UnloadingPolicy),
  "loadLimits": {
    string: {
      object (LoadLimit)
    },
    ...
  },
  "costPerHour": number,
  "costPerTraveledHour": number,
  "costPerKilometer": number,
  "fixedCost": number,
  "usedIfRouteIsEmpty": boolean,
  "routeDurationLimit": {
    object (DurationLimit)
  },
  "travelDurationLimit": {
    object (DurationLimit)
  },
  "routeDistanceLimit": {
    object (DistanceLimit)
  },
  "extraVisitDurationForVisitType": {
    string: string,
    ...
  },
  "breakRule": {
    object (BreakRule)
  },
  "label": string,
  "ignore": boolean,
  "travelDurationMultiple": number
}
字段
displayName

string

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

travelMode

enum (TravelMode)

行驶模式,会影响车辆可使用的道路和速度。另请参阅 travelDurationMultiple

routeModifiers

object (RouteModifiers)

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

startLocation

object (LatLng)

车辆在接收任何运输件之前的起始地理位置。如果未指定,则车辆从首次上车开始计算。如果运输模型具有时长和距离矩阵,则不得指定 startLocation

startWaypoint

object (Waypoint)

表示车辆在接收任何运输件之前的起始地理位置的航点。如果未指定 startWaypointstartLocation,则车辆从首次上车开始计费。如果运输模型具有时长和距离矩阵,则不得指定 startWaypoint

endLocation

object (LatLng)

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

endWaypoint

object (Waypoint)

路点,表示车辆完成最后一次 VisitRequest 后到达的地理位置。如果未指定 endWaypointendLocation,则车辆的 ShipmentRoute 会在完成最后一次 VisitRequest 后立即结束。如果运输模型具有时长和距离矩阵,则不得指定 endWaypoint

startTags[]

string

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

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

endTags[]

string

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

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

startTimeWindows[]

object (TimeWindow)

车辆可以从起始位置出发的时间范围。它们必须在全球时限范围内(请参阅 ShipmentModel.global_* 字段)。如果未指定,则除了上述全球时限外,没有其他限制。

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

只有在只有一个时间窗口时,才能设置 costPerHourAfterSoftEndTimesoftEndTime

endTimeWindows[]

object (TimeWindow)

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

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

只有在只有一个时间窗口时,才能设置 costPerHourAfterSoftEndTimesoftEndTime

unloadingPolicy

enum (UnloadingPolicy)

对车辆强制执行的卸载政策。

loadLimits

map (key: string, value: object (LoadLimit))

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

costPerHour

number

车辆费用:所有费用相加,且必须与 Shipment.penalty_cost 采用相同的单位。

车辆路线的每小时费用。此费用适用于相应路线所花费的总时间,包括行驶时间、等待时间和访问时间。使用 costPerHour(而不仅仅是 costPerTraveledHour)可能会导致延迟时间增加。

costPerTraveledHour

number

车辆路线每小时的费用。此费用仅适用于路线所需的旅行时间(即 ShipmentRoute.transitions 中报告的时间),不包括等待时间和访问时间。

costPerKilometer

number

车辆路线的每公里费用。此费用适用于 ShipmentRoute.transitions 中报告的距离,而不适用于单个 VisitRequestarrivalLocationdepartureLocation 的隐式行驶距离。

fixedCost

number

如果此车辆用于处理运输,则应用的固定费用。

usedIfRouteIsEmpty

boolean

此字段仅适用于其路线未配送任何运输的车辆。它指示在这种情况下,车辆是否应被视为二手车。

如果为 true,则车辆会从起始位置前往终点位置(即使没有运送任何运输),并且系统会考虑从起始位置到终点位置的旅行时间和距离费用。

否则,车辆不会从起始位置前往终点位置,并且系统不会为此车辆安排 breakRule 或延迟时间(从 TransitionAttributes 开始)。在本例中,车辆的 ShipmentRoute 除了车辆编号和标签之外,不包含任何信息。

routeDurationLimit

object (DurationLimit)

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

travelDurationLimit

object (DurationLimit)

对车辆路线的旅行时长施加的限制。在给定 OptimizeToursResponse 中,路线行程时长为其所有 transitions.travel_duration 的总和。

routeDistanceLimit

object (DistanceLimit)

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

extraVisitDurationForVisitType

map (key: string, value: string (Duration format))

指定从 visitTypes 字符串到时长的映射。时长是指在使用指定 visitTypes 进行访问时,除了 VisitRequest.duration 之外要花费的时间。如果指定了 costPerHour,则此额外的访问时长会增加费用。键(即 visitTypes)不能是空字符串。

如果访问请求具有多种类型,系统会在映射中为每种类型添加时长。

breakRule

object (BreakRule)

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

label

string

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

ignore

boolean

如果为 true,则 usedIfRouteIsEmpty 必须为 false,并且此车辆将保持未使用状态。

如果运输由 injectedFirstSolutionRoutes 中的已忽略车辆执行,则第一个解决方案会跳过该运输,但可以自由地在响应中执行该运输。

如果运输由 injectedSolutionConstraint 中的被忽略车辆执行,并且任何相关的接货/送货都被限制为保留在车辆上(即未放宽到级别 RELAX_ALL_AFTER_THRESHOLD),则系统会在响应中跳过相应运输。如果运输中有非空的 allowedVehicleIndices 字段,并且系统忽略了所有允许的车辆,则系统会在响应中跳过该运输。

travelDurationMultiple

number

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

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

另请参阅下面的 extraVisitDurationForVisitType

TravelMode

车辆可使用的出行方式。

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

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

RouteModifiers

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

JSON 表示法
{
  "avoidTolls": boolean,
  "avoidHighways": boolean,
  "avoidFerries": boolean,
  "avoidIndoor": boolean
}
字段
avoidTolls

boolean

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

avoidHighways

boolean

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

avoidFerries

boolean

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

avoidIndoor

boolean

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

UnloadingPolicy

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

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

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

LoadLimit

定义适用于车辆的载重限制,例如“此卡车载重不得超过 3500 千克”。请参阅 loadLimits

JSON 表示法
{
  "softMaxLoad": string,
  "costPerUnitAboveSoftMax": number,
  "startLoadInterval": {
    object (Interval)
  },
  "endLoadInterval": {
    object (Interval)
  },
  "maxLoad": string
}
字段
softMaxLoad

string (int64 format)

负载的软上限。请参阅 costPerUnitAboveSoftMax

costPerUnitAboveSoftMax

number

如果此车辆的路线上的载荷超出 softMaxLoad,则会应用以下费用惩罚(每辆车仅应用一次):(load - softMaxLoad) * costPerUnitAboveSoftMax。所有费用相加,并且必须与 Shipment.penalty_cost 采用相同的单位。

startLoadInterval

object (Interval)

车辆在路线起点处的可接受载荷间隔。

endLoadInterval

object (Interval)

车辆在路线结束时可接受的载荷间隔。

maxLoad

string (int64 format)

可接受的最大负载量。

间隔

可接受的加载量间隔。

JSON 表示法
{
  "min": string,
  "max": string
}
字段
min

string (int64 format)

可接受的最低负载。必须大于等于 0。如果同时指定了 minmax,则 min 必须小于等于 max

max

string (int64 format)

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

DurationLimit

用于定义车辆路线时长的上限。它可以是硬的,也可以是软的。

定义软上限字段时,必须同时定义软上限阈值及其相关费用。

JSON 表示法
{
  "maxDuration": string,
  "softMaxDuration": string,
  "quadraticSoftMaxDuration": string,
  "costPerHourAfterSoftMax": number,
  "costPerSquareHourAfterQuadraticSoftMax": number
}
字段
maxDuration

string (Duration format)

硬限制,用于限制时长不得超过 maxDuration。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

softMaxDuration

string (Duration format)

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

如果已定义,softMaxDuration 必须为非负数。如果还定义了 maxDuration,则 softMaxDuration 必须小于 maxDuration。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

quadraticSoftMaxDuration

string (Duration format)

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

如果已定义,quadraticSoftMaxDuration 必须为非负数。如果还定义了 maxDuration,则 quadraticSoftMaxDuration 必须小于 maxDuration,并且差值不得超过一天:

maxDuration - quadraticSoftMaxDuration <= 86400 seconds

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

costPerHourAfterSoftMax

number

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

  costPerHourAfterSoftMax * (duration - softMaxDuration)

费用必须为非负数。

costPerSquareHourAfterQuadraticSoftMax

number

如果违反 quadraticSoftMaxDuration 阈值,则每平方小时产生的费用。

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

  costPerSquareHourAfterQuadraticSoftMax *
  (duration - quadraticSoftMaxDuration)^2

费用必须为非负数。

DistanceLimit

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

如果定义了软上限,则必须定义 softMaxMeterscostPerKilometerAboveSoftMax,并且它们必须为非负值。

JSON 表示法
{
  "maxMeters": string,
  "softMaxMeters": string,
  "costPerKilometerBelowSoftMax": number,
  "costPerKilometerAboveSoftMax": number
}
字段
maxMeters

string (int64 format)

一个硬限制,用于限制距离不得超过 maxMeters。上限必须是非负数。

softMaxMeters

string (int64 format)

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

如果已定义 softMaxMeters,则其值必须小于 maxMeters 且必须为非负数。

costPerKilometerBelowSoftMax

number

每公里费用(最高可达 softMaxMeters),公式如下:

  min(distanceMeters, softMaxMeters) / 1000.0 *
  costPerKilometerBelowSoftMax.

routeDistanceLimit 不支持此费用。

costPerKilometerAboveSoftMax

number

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

  (distanceMeters - softMaxMeters) / 1000.0 *
  costPerKilometerAboveSoftMax.

费用必须为非负数。

BreakRule

用于为车辆生成时间休息时段(例如午餐休息时段)的规则。休息时间是指车辆在其当前位置保持空闲状态且无法执行任何访问的连续时间段。中断可能会发生在以下情况下:

  • 在两次访问之间的行程中(包括访问前后的时间,但不包括访问期间),在这种情况下,它会延长两次访问之间的相应转接时间;
  • 或在车辆启动之前(车辆可能不会在休息期间启动),在这种情况下,它不会影响车辆启动时间。
  • 或在车辆结束时间之后(同上,使用车辆结束时间)。
JSON 表示法
{
  "breakRequests": [
    {
      object (BreakRequest)
    }
  ],
  "frequencyConstraints": [
    {
      object (FrequencyConstraint)
    }
  ]
}
字段
breakRequests[]

object (BreakRequest)

休息时间序列。查看 BreakRequest 消息。

frequencyConstraints[]

object (FrequencyConstraint)

可能有多个 FrequencyConstraint 适用。此 BreakRuleBreakRequest 必须满足所有这些条件。请参阅 FrequencyConstraint

BreakRequest

必须事先知道适用于每辆车的休息点序列(即数量和顺序)。重复的 BreakRequest 定义了该序列,并按其必须出现的顺序排列。它们的时间范围 (earliestStartTime / latestStartTime) 可能会重叠,但必须与订单兼容(系统会进行检查)。

JSON 表示法
{
  "earliestStartTime": string,
  "latestStartTime": string,
  "minDuration": string
}
字段
earliestStartTime

string (Timestamp format)

必需。休息时间开始的下限(包括该时间)。

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

latestStartTime

string (Timestamp format)

必需。休息时间开始的上限(包括该时间)。

时间戳采用 RFC3339 世界协调时间(UTC,即“祖鲁时”)格式,精确到纳秒,最多九个小数位。示例:"2014-10-02T15:01:23Z""2014-10-02T15:01:23.045123456Z"

minDuration

string (Duration format)

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

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

FrequencyConstraint

您可以通过强制执行最短休息频率(例如“每 12 小时必须至少休息 1 小时”)来进一步约束上述休息时间的频率和时长。假设这可以解释为“在任何 12 小时的滑动时间窗口内,必须至少有一次至少 1 小时的休息时间”,那么该示例将转换为以下 FrequencyConstraint

{
   minBreakDuration { seconds: 3600 }         # 1 hour.
   maxInterBreakDuration { 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
JSON 表示法
{
  "minBreakDuration": string,
  "maxInterBreakDuration": string
}
字段
minBreakDuration

string (Duration format)

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

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

maxInterBreakDuration

string (Duration format)

必需。路线中任何时间间隔(不包含至少部分 duration >= minBreakDuration 休息时间)的允许时长上限。必须为正值。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

DurationDistanceMatrix

指定从到访地点和车辆起始位置到到访地点和车辆终止位置的持续时间和距离矩阵。

JSON 表示法
{
  "rows": [
    {
      object (Row)
    }
  ],
  "vehicleStartTag": string
}
字段
rows[]

object (Row)

指定时长和距离矩阵的行。其元素数量必须与 ShipmentModel.duration_distance_matrix_src_tags 相同。

vehicleStartTag

string

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

每项车辆启动都必须与一个矩阵完全匹配,即其中只有一个 startTags 字段必须与矩阵的 vehicleStartTag 匹配(且仅与该矩阵的 vehicleStartTag 匹配)。

所有矩阵都必须具有不同的 vehicleStartTag

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

JSON 表示法
{
  "durations": [
    string
  ],
  "meters": [
    number
  ]
}
字段
durations[]

string (Duration format)

指定行的时长值。其元素数量必须与 ShipmentModel.duration_distance_matrix_dst_tags 相同。

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

meters[]

number

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

TransitionAttributes

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

JSON 表示法
{
  "srcTag": string,
  "excludedSrcTag": string,
  "dstTag": string,
  "excludedDstTag": string,
  "cost": number,
  "costPerKilometer": number,
  "distanceLimit": {
    object (DistanceLimit)
  },
  "delay": string
}
字段
srcTag

string

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

来源访问或车辆启动匹配的条件是:其 VisitRequest.tagsVehicle.start_tags 包含 srcTag 或不包含 excludedSrcTag(具体取决于这两个字段中哪个字段不为空)。

excludedSrcTag

string

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

dstTag

string

只有当目的地到访或车辆结束的 VisitRequest.tagsVehicle.end_tags 包含 dstTag 或不包含 excludedDstTag(取决于这两个字段中哪个字段不为空)时,才会匹配。

excludedDstTag

string

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

cost

number

指定执行此转换的费用。此值应与模型中的所有其他费用采用相同的单位,且不得为负值。此费用需在所有其他现有费用的基础上支付。

costPerKilometer

number

指定在执行此过渡期间对行驶距离应用的每公里费用。它与车辆上指定的任何 Vehicle.cost_per_kilometer 相加。

distanceLimit

object (DistanceLimit)

指定执行此过渡时行进的距离上限。

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

delay

string (Duration format)

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

此延迟始终发生在完成来源访问之后,并在开始目的地访问之前

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

ShipmentTypeIncompatibility

根据 shipmentType 指定发货之间的不兼容性。系统会根据不兼容模式限制同一路线上不兼容的配送信息的显示。

JSON 表示法
{
  "types": [
    string
  ],
  "incompatibilityMode": enum (IncompatibilityMode)
}
字段
types[]

string

不兼容的类型列表。如果两个发货中列出的 shipment_types 不同,则表示这两个发货“不兼容”。

incompatibilityMode

enum (IncompatibilityMode)

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

IncompatibilityMode

用于定义如何限制同一路线上不兼容的配送方式的显示方式的模式。

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

对于两种类型不兼容且采用 NOT_IN_SAME_VEHICLE_SIMULTANEOUSLY 不兼容模式的运输,

  • 如果这两项都是仅接客(无送客)或仅送客(无接客),则它们绝不能共用同一辆车。
  • 如果其中一个运输服务是送货,另一个是取货,那么这两个运输服务可以共用同一辆车,前提是前者在后者取货前送达。

ShipmentTypeRequirement

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

JSON 表示法
{
  "requiredShipmentTypeAlternatives": [
    string
  ],
  "dependentShipmentTypes": [
    string
  ],
  "requirementMode": enum (RequirementMode)
}
字段
requiredShipmentTypeAlternatives[]

string

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

dependentShipmentTypes[]

string

对于 dependentShipmentTypes 字段中类型为 dependentShipmentTypes 的所有运输,都要求在同一路线上至少访问一个类型为 requiredShipmentTypeAlternatives 的运输。

注意:不允许出现 shipmentType 依赖于自身的一系列要求。

requirementMode

enum (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 与之前相同,但“依赖”运输服务的运输订单在送达时需要在车辆上装载“必需”运输服务的运输订单。

PrecedenceRule

两项事件(每项事件都是商品的取件或送达)之间的优先级规则:“第二”事件必须在“第一”事件开始后至少 offsetDuration 才会开始。

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

此外,优先级仅在同时发货时才适用,否则会被忽略。

JSON 表示法
{
  "firstIsDelivery": boolean,
  "secondIsDelivery": boolean,
  "offsetDuration": string,
  "firstIndex": integer,
  "secondIndex": integer
}
字段
firstIsDelivery

boolean

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

secondIsDelivery

boolean

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

offsetDuration

string (Duration format)

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

该时长以秒为单位,最多包含九个小数位,以“s”结尾。示例:"3.5s"

firstIndex

integer

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

secondIndex

integer

“第二个”事件的配送编号。必须指定此字段。