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

本指南展示了过渡属性的可能用途。本教程将通过两个示例,教您如何对现实世界中的场景进行建模:将停车时间纳入优化后的路线,以及确保每条路线都以访问特定位置结束。

准备工作

您可以使用过渡属性,为优化路线中的某些过渡添加特定于模型的费用和延迟时间。这些费用和延迟时间是在根据所用车辆的参数从地图数据计算出的过渡时长和费用的基础上添加的。

过渡是指路线中连接一个位置与下一个位置的路段。

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

  • 路线的起点。
  • 取货或送货的停靠点。
  • 路线的终点。

您可以通过将所有过渡属性添加到列表 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_tagTransitionAttributes.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. 选择两个在模型中任何位置都未使用的全新标记,例如 CLEANEDROUTE_END。前者适用于车辆处于或变为清洁状态的位置,后者适用于路线的终点。
  2. 对于每辆车,请添加一个新的仅送货型运输,以表示前往清洁设施的行程,并包含以下属性:
    1. 每个清洁设施位置都应表示为相应货件的送货访问请求。
    2. 向清洁设施货件的每次访问请求的 VisitRequest.tags 添加 CLEANED。表示离开此位置的车辆是清洁的。模型中的其他访问请求不应使用此标记,以便在离开这些访问请求时将车辆视为“未清洁”。
    3. 通过将车辆的 penalty_cost 设置为较小的数字,允许优化器在车辆未被使用时跳过相应配送。
  3. 对于每辆车,将 CLEANED 添加到 Vehicle.start_tags。这用于在车辆执行任何取货或送货任务之前将其标记为清洁,前提是车辆已在上一个工作日结束时清洁完毕,并允许车辆从起始途经点直接前往其结束途经点。即使在实际中不会出现此类路线,允许这种情形也有助于优化器更高效地搜索优化路线。

  4. 为每辆车添加 ROUTE_ENDVehicle.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 在实现以额外费用表示的软偏好或权衡时,效果更佳。如果同时考虑时间和费用,您可以随意组合延迟和费用。

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

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

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

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

您不能只是省略这些标记,因为每个 TransitionAttributes 消息都必须包含 TransitionAttributes.src_tagTransitionAttributes.excluded_src_tag 之一,以及 TransitionAttributes.dst_tagTransitionAttributes.excluded_dst_tag 之一。

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

深入阅读