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

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

准备工作

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

转换是将一个位置与下一个位置连接起来的路线段。

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

  • 路线的起点。
  • 进行自提或配送的停靠点。
  • 相应路线的终点。

您可以通过将转换属性添加到列表 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. 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 设置为模型中未使用的代码,以匹配所有代码。这将匹配不含此标记的所有营业地点,但由于您选择的标记未被任何营业地点使用,因此这些转换属性将与所有营业地点匹配。

深入阅读