加载需求和限制

本指南介绍了 loadDemandsloadLimits,以及它们之间的关系 其他。

提货和送货时间范围限制中所述, OptimizeToursRequest 消息(RESTgRPC)包含许多 用于指定对要优化问题的限制条件的属性。若干 OptimizeToursRequest 属性表示加载限制

车辆和货物具有实体属性, 规划路线

  • 交通工具loadLimits 属性指定 请参阅 Vehicle 消息的(RESTgRPC) 文档。
  • 装运loadDemands 属性指定给定的负载 运费。请参阅 Shipment 消息的(RESTgRPC) 文档。

结合这两个约束条件,优化器可以 以最符合您需求的方式为车辆正确分配运单 车队容量和货运需求。

本文档的其余部分将详细介绍 loadLimitsloadDemands

加载需求和限制:类型

您可以用类型表示每个负载需求和限制限制条件。

您可以提供自己的一组加载类型,如以下示例所示:

  • 重量
  • 音量
  • 线性测量
  • 所运输物品或设备的名称

本指南使用 weightKg 作为示例类型。

Shipment.loadDemandsVehicle.loadLimits 都使用协议缓冲区 map 类型,其中 string 键表示负载类型。

Shipment.loadDemands 值使用 Load 消息(RESTgRPC)。 Load 消息具有单个 amount 属性,该属性表示容量 才能完成指定类型的配送。

Vehicle.loadLimits 值使用 LoadLimit 消息(RESTgRPC)。LoadLimit 消息具有多个属性,其中 maxLoad 表示车辆在指定类型的最大承载能力。

运单的 loadDemands 仅当满足以下条件时,才会消耗所分配车辆的 loadLimits 两者都有匹配的加载类型键。例如,某次运送 第 loadDemands 项,共:

"loadDemands": {
  "weightKg": {
    "amount": 50
  }
}

需要 50 个 weightKg 类型的加载单元,才能发货 已完成。一辆loadLimits属于以下车型的车辆:

"loadLimits": {
  "weightKg": {
    "maxLoad": 100
  }
}

可能能够完成装运,因为车辆的maxLoadweightKg类型大于或等于运单的 loadDemands weightKg 类型。但是,一辆 loadLimits 属于以下内容的车辆:

"loadLimits": {
  "equipmentRackStorage": {
    "maxLoad": 10
  }
}

由于缺少无限 weightKg 容量, weightKg 的负载限制,使车辆不受装运商的限制 权重需求。

加载货物和车辆之间的移交作业

由于货物由车辆取走并送达,因此货物的 loadDemand 在发货和车辆之间转移。您可以看到 在 OptimizeToursResponse 消息的 (RESTgRPCroutes.transitions 条目。序列为 如下:

  1. 运送所需的负载能力以 loadDemand 的形式指定。
  2. 货物由分配的车辆取件,车辆的 vehicleLoads发货金额增加 loadDemand。这个 在响应中,由正 visits.loadDemands 表示转移 消息。
  3. 车辆交付货物,且车辆的 vehicleLoads 降低 按已发货运单的loadDemand金额计算。此次转账 用响应消息中的 否定 visits.loadDemands 表示。

车辆的vehicleLoads在任何时候都不能超过其指定的loadLimits

包含负载需求和限制的完整示例

查看包含加载需求和 限制

{
  "populatePolylines": false,
  "populateTransitionPolylines": false,
  "model": {
    "globalStartTime": "2023-01-13T16:00:00Z",
    "globalEndTime": "2023-01-14T16:00:00Z",
    "shipments": [
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789456,
              "longitude": -122.390192
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 100.0,
        "loadDemands": {
          "weightKg": {
            "amount": 50
          }
        }
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.789116,
              "longitude": -122.395080
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 15.0,
        "loadDemands": {
          "weightKg": {
            "amount": 10
          }
        }
      },
      {
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 37.795242,
              "longitude": -122.399347
            },
            "duration": "250s"
          }
        ],
        "pickups": [
          {
            "arrivalLocation": {
              "latitude": 37.794465,
              "longitude": -122.394839
            },
            "duration": "150s"
          }
        ],
        "penaltyCost": 50.0,
        "loadDemands": {
          "weightKg": {
            "amount": 80
          }
        }
      }
    ],
    "vehicles": [
      {
        "endLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "startLocation": {
          "latitude": 37.794465,
          "longitude": -122.394839
        },
        "costPerHour": 40.0,
        "costPerKilometer": 10.0,
        "loadLimits": {
          "weightKg": {
            "maxLoad": 100
          }
        }
      }
    ]
  }
}
    

示例请求包含几个与加载相关的参数:

  • shipments[0] 的加载需求为 50 个 weightKg
  • shipments[1] 的加载需求为 10 weightKg
  • shipments[2] 的加载需求为 80 weightKg
  • vehicles[0] 的负载上限为 100 个 weightKg

查看对请求的响应,其中包含加载需求和 限制

{
  "routes": [
    {
      "vehicleStartTime": "2023-01-13T16:00:00Z",
      "vehicleEndTime": "2023-01-13T16:43:27Z",
      "visits": [
        {
          "isPickup": true,
          "startTime": "2023-01-13T16:00:00Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "shipmentIndex": 1,
          "isPickup": true,
          "startTime": "2023-01-13T16:02:30Z",
          "detour": "150s",
          "loadDemands": {
            "weightKg": {
              "amount": "10"
            }
          }
        },
        {
          "startTime": "2023-01-13T16:08:55Z",
          "detour": "150s",
          "loadDemands": {
            "weightKg": {
              "amount": "-50"
            }
          }
        },
        {
          "shipmentIndex": 1,
          "startTime": "2023-01-13T16:16:37Z",
          "detour": "343s",
          "loadDemands": {
            "weightKg": {
              "amount": "-10"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "isPickup": true,
          "startTime": "2023-01-13T16:27:07Z",
          "detour": "1627s",
          "loadDemands": {
            "weightKg": {
              "amount": "80"
            }
          }
        },
        {
          "shipmentIndex": 2,
          "startTime": "2023-01-13T16:36:26Z",
          "detour": "0s",
          "loadDemands": {
            "weightKg": {
              "amount": "-80"
            }
          }
        }
      ],
      "transitions": [
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T16:00:00Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        },
        {
          "travelDuration": "0s",
          "waitDuration": "0s",
          "totalDuration": "0s",
          "startTime": "2023-01-13T16:02:30Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "50"
            }
          }
        },
        {
          "travelDuration": "235s",
          "travelDistanceMeters": 795,
          "waitDuration": "0s",
          "totalDuration": "235s",
          "startTime": "2023-01-13T16:05:00Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "60"
            }
          }
        },
        {
          "travelDuration": "212s",
          "travelDistanceMeters": 791,
          "waitDuration": "0s",
          "totalDuration": "212s",
          "startTime": "2023-01-13T16:13:05Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "10"
            }
          }
        },
        {
          "travelDuration": "380s",
          "travelDistanceMeters": 1190,
          "waitDuration": "0s",
          "totalDuration": "380s",
          "startTime": "2023-01-13T16:20:47Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        },
        {
          "travelDuration": "409s",
          "travelDistanceMeters": 1371,
          "waitDuration": "0s",
          "totalDuration": "409s",
          "startTime": "2023-01-13T16:29:37Z",
          "vehicleLoads": {
            "weightKg": {
              "amount": "80"
            }
          }
        },
        {
          "travelDuration": "171s",
          "travelDistanceMeters": 665,
          "waitDuration": "0s",
          "totalDuration": "171s",
          "startTime": "2023-01-13T16:40:36Z",
          "vehicleLoads": {
            "weightKg": {}
          }
        }
      ],
      "metrics": {
        "performedShipmentCount": 3,
        "travelDuration": "1407s",
        "waitDuration": "0s",
        "delayDuration": "0s",
        "breakDuration": "0s",
        "visitDuration": "1200s",
        "totalDuration": "2607s",
        "travelDistanceMeters": 4812,
        "maxLoads": {
          "weightKg": {
            "amount": "80"
          }
        }
      },
      "routeCosts": {
        "model.vehicles.cost_per_kilometer": 48.12,
        "model.vehicles.cost_per_hour": 28.966666666666665
      },
      "routeTotalCost": 77.086666666666659
    }
  ],
  "metrics": {
    "aggregatedRouteMetrics": {
      "performedShipmentCount": 3,
      "travelDuration": "1407s",
      "waitDuration": "0s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1200s",
      "totalDuration": "2607s",
      "travelDistanceMeters": 4812,
      "maxLoads": {
        "weightKg": {
          "amount": "80"
        }
      }
    },
    "usedVehicleCount": 1,
    "earliestVehicleStartTime": "2023-01-13T16:00:00Z",
    "latestVehicleEndTime": "2023-01-13T16:43:27Z",
    "totalCost": 77.086666666666659,
    "costs": {
      "model.vehicles.cost_per_hour": 28.966666666666665,
      "model.vehicles.cost_per_kilometer": 48.12
    }
  }
}
    

添加的加载限制会影响 visits 的顺序:

  1. 已取走shipment[0]
  2. 已取走shipment[1]
  3. shipment[0]已送达
  4. shipment[1]已送达
  5. 已取走shipment[2]
  6. shipment[2]已送达

此订单表明以下时间的车辆无法完成 3 项发货: 因为其总loadDemands超过了车辆的 loadLimits

每个 visits 条目都包含因以下原因导致的车辆负载变化: Visit。正负载值表示当 负值表示货物卸载。

每个 transitions 条目都包含以下期间内的车辆总负载: Transition。例如,transitions[2]weightKg 负载为 60, 表示 shipment[0]shipment[1] 的总加载次数。

指标对象 routes[0].metricsmetrics.aggregatedRouteMetrics 包括 maxLoads 属性。类型 weightKg 的值为 80,表示 将shipments[2]传送到其 送货地点。

软负载限制限制条件

自提和送货时间范围中所述的时间范围相同 限制条件,负载限制限制条件有硬性变体和软性变体。通过 LoadLimit 消息的 maxLoad 属性表示了一个硬性约束: 车辆载重不得超过指定值 maxLoad 类型。属性 softMaxLoadcostPerUnitAboveSoftMax 表示柔和的 限制,每个超过 softMaxLoad 的单位都会产生 费用为 costPerUnitAboveSoftMax

软负载限制限制条件有多种用途,例如:

  • 均衡运输超过所需的最低数量的车辆 当这样做更具成本效益时
  • 表达驾驶员对舒适物品数量的偏好 在指定路线上自提和送餐
  • 将车辆装入低于其最大实际承载能力的车辆,以限制磨损和 降低维护成本

硬负载限制和软负载限制可结合使用。例如,硬性 载重限制可能表示车辆可安全携带的最大货物重量 一辆车中同时装有的物品数量上限,而 软负载限制可能是需缴税的最大重量或商品数量 让驾驶员能够将各种设备装在车内。