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

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

准备工作

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

转换 是指将一个地点连接到下一个地点的路线段。

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

  • 路线的出发地。
  • 取货或送货的停靠点。
  • 路线的终点。

您可以通过将所有转换属性添加到列表 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 如果车辆在此停车位结束其路线,则为 `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. 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_tagTransitionAttributes.excluded_src_tag 中的一个,以及 TransitionAttributes.dst_tagTransitionAttributes.excluded_dst_tag中的一个。

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

深入阅读