使用转换属性对业务逻辑进行建模

本指南介绍了过渡属性的可能用途。它将通过两个示例教您如何对真实场景进行建模:将车辆停放时间纳入优化路线,并确保每条路线都以访问特定位置结束。

准备工作

您可以使用转换属性为优化路线中的特定转换添加模型专属费用和延迟时间。这些费用和延迟时间会添加到根据所用车辆的参数从地图数据计算出的过渡时长和费用中。

过渡是连接一个地点与下一个地点的路线段。

位置是指车辆路线中的以下任一地点:

  • 路线的起点。
  • 进行取件或送件的停靠点。
  • 路线的终点。

您可以通过将模型的所有转换属性添加到列表 ShipmentModel.transition_attributes 中来定义这些属性。列表中的每个元素都定义了一组过渡属性,并使用过渡的起始位置和结束位置上的标记与路线中的过渡进行匹配。如需详细了解过渡属性,请参阅 TransitionAttributes 的参考文档。

对真实场景进行建模

本部分通过两个小示例展示了如何使用转换属性实现实际业务限制。

预留停车时间

在这种情况下,司机需要先停车,然后才能前往地点 A。地点 B 就在附近,司机可以在两次访问中使用同一个停车位。如果司机在 A 之后立即访问 B,则可以节省时间,因为他们无需离开停车位并再次停车。在 Route Optimization API 中,您可以使用过渡属性来增加额外时间,以便仅在司机从一个停车位移至另一个停车位时停车。

如果您将停车时间与到访时长分开建模,则可以缩短将使用同一停车位的到访分组的路线。这样可以提高模型的精确度,并使优化器更倾向于选择将这些访问分组在一起的路线。

如需在 Route Optimization API 请求中执行此操作,请按以下步骤操作:

  1. 仅在执行访问所需的时间内使用 VisitRequest.duration。例如,将包裹交给客户并让客户签收。

  2. 对于模型中使用的每个不同的停车位,请使用模型中未用于其他任何用途的新标记,例如 PARKING_123。

  3. 将此代码添加到以下位置:

    1. VisitRequest.tags 在所有使用此停车位的访问请求中。

    2. Vehicle.start_tags(如果车辆从此停车位开始其路线)。

    3. Vehicle.end_tags 如果车辆在此停车位开始或结束其路线。

  4. 对于每个新的停车标记,请向 ShipmentModel.transition_attributes 添加一个条目,以便在从其他停车位驶来时增加停车延迟,具体操作如下:

    1. 将 TransitionAttributes.excluded_src_tag 和 TransitionAttributes.dst_tag 设置为 PARKING_123。

    2. 将 TransitionAttributes.delay 设置为停放车辆所需的时间。

    例如,如果某个位置的标记为 PARKING_123,并且停放车辆需要 150 秒,则您需要向 ShipmentModel.transition_attributes 添加以下条目:

    {
      "excluded_src_tag": "PARKING_123",
      "dst_tag": "PARKING_123",
      "delay": "150s"
    }
    

在路线终点进行强制清洁

在这种情况下,车辆需要在路线结束时进行清洁,并满足以下额外限制:

  • 车辆在返回车库之前,会在专门的清洁设施中进行清洁。优化后的路线会根据清洁设施的位置以及车辆接送和送货的位置,使用最佳清洁设施。
  • 清洁后,车辆不得执行任何额外的取件或送货。
  • 开车前往该地点和清洁车辆的时间会计入司机的工作时间,并且必须在路线的最长时长内完成。

您可以通过仅允许空路线或最后一次访问是清洁设施的路线来对此要求进行建模。在 Route Optimization API 中,您可以通过禁止从除清洁设施或路线起点以外的任何位置过渡到路线的终点航点来实现此目的:

  1. 选择模型中未使用的两个新标记,例如 CLEANED 和 ROUTE_END。前者适用于车辆干净或变干净的位置,后者适用于路线终点。
  2. 对于每辆车,添加一个新的仅送货行程,表示前往清洁设施,并具有以下属性:
    1. 每个清洁设施地点都应表示为此运单的送货访问请求。
    2. 将 CLEANED 添加到清洁设施配送的每个访问请求的 VisitRequest.tags。这表示离开此位置的车辆是干净的。模型中的其他访问请求不应使用此标记,以便在离开这些访问请求时,车辆被视为“不干净”。
    3. 通过将 penalty_cost 设置为较小的数字,允许优化器在车辆未被使用时跳过此运单。
  3. 对于每辆车,将 CLEANED 添加到 Vehicle.start_tags。这用于在车辆执行任何接送或配送任务之前将其标记为干净(假设车辆在上一个工作日结束时已清洁),并允许其从起始航点直接前往结束航点。即使此类路线在实际中不会发生,允许这种情况也有助于优化器更高效地搜索优化路线。

  4. 对于每辆车,将 ROUTE_END 添加到 Vehicle.end_tags。

  5. 向 ShipmentModel.transition_attributes 添加一个新条目,以禁止车辆在不干净时到达车辆终点航点,并具有以下属性:

    1. 将 TransitionAttributes.excluded_src_tag 设置为 CLEANED。

    2. 将 TransitionAttributes.dst_tag 设置为 ROUTE_END。

    3. 将 TransitionAttributes.delay 设置为较大的值。如果将延迟时间设置为大于最长路线时长,则实际上会禁止优化器在路线中使用此过渡。

    例如,如果模型的时间尺度为一个工作日,您可以使用 24 小时(86400 秒)的延迟时间,禁止从除清洁设施和路线起点以外的任何位置过渡到路线终点:

    {
      "excluded_src_tag": "CLEANED",
      "dst_tag": "ROUTE_END",
      "delay": "86400s"
    }
    

如何在延迟时间和费用之间进行选择

在延迟时间和费用之间进行选择取决于所实现的业务逻辑和限制条件的性质。设置 TransitionAttributes.delay 最适合实现硬性限制条件或表示在所用时间方面的权衡。TransitionAttributes.cost 更适合实现软偏好或以额外费用表示的权衡。如果同时考虑所用时间和费用,您可以任意组合延迟时间和费用。

车辆清洁示例使用了非常长的延迟时间,因为在路线结束时清洁车辆是一项硬性要求,而较长的延迟时间可防止优化器忽略该要求。如果您仅设置费用,优化器可能会选择跳过清洁,前提是它找到了一种方法来弥补其他地方的费用,例如在不清洁车辆的情况下“节省”的时间内交付更多货物。

停车示例使用较短的延迟时间,该延迟时间对应于停放车辆所需的额外时间。如果司机在付费停车场停车,您还可以将费用与延迟时间结合使用。

如何添加与所有访问请求匹配的转换属性

上述示例使用的转换属性与具有给定标记的位置或不具有该标记的位置相匹配。但如果您需要添加适用于所有转场的转场属性,该怎么办?

您不能直接省略这些标记,因为每条 TransitionAttributes 消息都必须包含 TransitionAttributes.src_tag 和 TransitionAttributes.excluded_src_tag 中的一个,以及 TransitionAttributes.dst_tag 和 TransitionAttributes.excluded_dst_tag 中的一个。

不过,您可以通过将 TransitionAttributes.excluded_src_tag 或 TransitionAttributes.excluded_dst_tag 设置为模型中任何位置都未使用的标记,来匹配所有标记。这将匹配所有不具有此标记的位置,但由于您有意选择了一个未被任何位置使用的标记,因此这些过渡属性将匹配所有位置。

深入阅读