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

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

准备工作

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

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

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

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

您可以通过将所有过渡属性添加到列表 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_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 设置为模型中任何位置都未使用的代码,来匹配所有代码。这将匹配所有没有此代码的地点,但由于您有意选择了一个任何地点都不使用的代码,因此这些过渡属性将与所有地点匹配。

深入阅读