使用转换属性优先处理附近的访问

此示例展示了如何使用过渡属性来优先处理在同一时间段内由同一辆车执行附近取货和送货的路线。如需详细了解过渡属性,请参阅使用过渡属性对业务逻辑建模

在此示例中:

  • 货物 A、B 和 C 的送货地点彼此靠近,位于同一条道路上。
  • 其他送货地点位于道路的更远处。
  • 送货没有指定送货时间。
  • 无论访问时间表如何,车辆都需要在这条道路上行驶两次:一次是在早上从仓库出发的途中,另一次是在晚上返回的途中。
  • 无论何时执行 A、B 和 C,路线的总行驶距离和时长始终相同。

示例:在同一条道路上配送多批货物。有三批货物 A、B 和 C 正在从配送中心运往其他目的地。A 距离仓库 1000 米,B 距离仓库比 A 远 50 米,C 距离仓库比 B 远 30 米(方向相同)。还有其他货物距离 C 点 1000 米。

在这种情况下,对于仅使用每小时费用和每公里费用的请求,优化后的路线可能会在早上处理 A 和 B,在晚上处理 C,而解决方案的费用与同时处理这三项货物的费用相同。

具有阈值的每公里费用

如需将附近的访问分组,您首先需要选择一个阈值距离。这是您认为附近的两次访问之间的最大距离。此示例使用 100 米的阈值,大致相当于城市区域中的一个街区。您可以根据自己的业务需求和司机的偏好增加或减少阈值。

如需将彼此相距 100 米以内的附近访问分组,您可以为每次过渡的前 100 米设置较高的费用,并为过渡的任何额外米数设置较低的费用。由于前 100 米的费用最高,因此优化器通过使用短于 100 米阈值的过渡来节省最多的费用,即使这意味着延长路线的总长度也是如此。

如需设置费用,您可以向 ShipmentModel.transition_attributes 添加一个新条目,并使用以下属性:

{
  "model": {
    "transitionAttributes": [
      {
        "excluded_dst_tag": "UNUSED_TAG",
        "excluded_src_tag": "UNUSED_TAG",
        "distanceLimit": {
          "softMaxMeters": 100,
          "costPerKilometerBelowSoftMax": 50,
          "costPerKilometerAboveSoftMax": 1,
        }
      }
    ]
  }
}

任何货物或车辆都不得使用标记 #unused_tag# 来匹配所有可能的过渡。如需了解详情,请参阅如何匹配所有访问 请求

低于阈值的高费用如何运作

本部分展示了低于和高于阈值的费用如何影响示例场景的不同解决方案的总费用。

解决方案 1:在去程中执行 A 和 B,在返程中执行 C

在此解决方案中,货物被拆分为这条道路的两次遍历。 其中两项货物在第一次遍历中送达,剩余的一项货物在第二次遍历中送达。共有 5 次过渡:

转场 距离 低于阈值 高于阈值
距离 费用 距离 费用
仓库 →A 1000 米 100 米 5 900 米 0.9
A→B 50 米 50 米 2.5 0 米 0
B→其他 1030 米 100 米 5 930 米 0.93
其他→C 1000 米 100 米 5 900 米 0.9
C→仓库 1080 米 100 米 5 980 米 0.98
总计 450 米 22.5 3710 米 3.71

总费用是以下两项每公里费用的总和:

  • 低于阈值的每公里费用 (50) 乘以低于阈值的总行驶距离(450 米 = 0.45 公里),
  • 高于阈值的每公里费用 (1) 乘以高于阈值的总行驶距离(3710 米 = 3.71 公里)。

因此,总费用为 0.45 * 50 + 3.71 * 1 = 22.5 + 3.71 = 26.21。

解决方案 2:在去程中执行 A、B 和 C,在返程中不执行任何操作

在此解决方案中,与解决方案 1 不同,所有三项货物都在一次道路遍历中“成组”送达。在另一次遍历中,车辆不会停靠。同样,共有 5 次过渡,但其长度和组成不同:

转场 距离 低于阈值 高于阈值
距离 费用 距离 费用
仓库 →A 1000 米 100 米 5 900 米 0.9
A→B 50 米 50 米 2.5 0 米 0
B→C 30 米 30 米 1.5 0 米 0
C→其他 1000 米 100 米 5 900 米 0.9
其他→仓库 2080 米 100 米 5 1980 米 1.98
总计 380 米 19 3780 米 3.78

使用与解决方案 1 相同的计算方法,总费用为 0.38 * 50 + 3.78 * 1 = 19 + 3.78 = 22.78,并且在一个时间段内执行所有访问的费用低于分两组执行的费用。您可以通过 增加 DistanceLimit.cost_per_kilometer_below_soft_max来增强此效果。

为什么低于阈值的低每公里费用不起作用

由于您希望优先选择短过渡而不是长过渡,因此您可能会倾向于为长过渡设置较高的每公里费用,并为短过渡保留较低的每公里费用。但实际上,这会产生相反的效果:由于过渡的前 100 米最便宜,因此优化器会通过优先选择接近或超过 100 米的过渡,最大限度地利用这些“便宜”的米数。

您可以在这两个示例解决方案中看到这种效果。如果您交换低于和高于阈值的每公里费用,路线费用会发生变化:

高于阈值的高费用 低于阈值的高费用
解决方案 1 解决方案 2 解决方案 1 解决方案 2
低于阈值的公里数 0.45 0.38 0.45 0.38
低于阈值的每公里费用 1.00 1.00 50.00 50.00
高于阈值的公里数 3.71 3.78 3.71 3.78
高于阈值的每公里费用 50.00 50.00 1.00 1.00
总费用 185.95 189.38 26.21 22.78

对于每个版本,两个解决方案的总费用中较低者以粗体突出显示。您可以看到,当您使用高于阈值的高费用时,将访问分组的路线的总费用现在更高,这与您想要实现的目标相反。