本指南介绍了 loadDemands
和 loadLimits
,以及它们之间的关系
其他。
如提货和送货时间范围限制中所述,
OptimizeToursRequest
消息(REST、gRPC)包含许多
属性,用于指定针对要优化的问题的限制条件。若干
OptimizeToursRequest
属性表示加载限制。
车辆和货物具有实体属性, 规划路线
- 交通工具:
loadLimits
属性指定 请参阅Vehicle
消息的(REST、gRPC) 文档。 - 装运:
loadDemands
属性指定给定的负载 运费。请参阅Shipment
消息的(REST、gRPC) 文档。
结合这两个约束条件,优化器可以 以最符合您需求的方式为车辆正确分配运单 车队容量和货运需求。
本文档的其余部分将详细介绍 loadLimits
和 loadDemands
。
加载需求和限制:类型
您可以用类型表示每个负载需求和限制限制条件。
您可以提供自己的一组加载类型,如以下示例所示:
- 重量
- 音量
- 线性测量
- 所运输物品或设备的名称
本指南使用 weightKg
作为示例类型。
Shipment.loadDemands
和 Vehicle.loadLimits
都使用协议缓冲区
map
类型,其中 string
键表示负载类型。
Shipment.loadDemands
值使用 Load
消息(REST、gRPC)。
Load
消息具有单个 amount
属性,该属性表示容量
才能完成指定类型的配送。
Vehicle.loadLimits
值使用 LoadLimit
消息(REST、
gRPC)。LoadLimit
消息具有多个属性,其中 maxLoad
表示车辆在指定类型的最大承载能力。
运单的 loadDemands
仅当满足以下条件时,才会消耗所分配车辆的 loadLimits
两者都有匹配的加载类型键。例如,某次运送
第 loadDemands
项,共:
"loadDemands": {
"weightKg": {
"amount": 50
}
}
需要 50 个 weightKg
类型的加载单元,才能发货
已完成。一辆loadLimits
属于以下车型的车辆:
"loadLimits": {
"weightKg": {
"maxLoad": 100
}
}
可能能够完成装运,因为车辆的maxLoad
在
weightKg
类型大于或等于运单的 loadDemands
weightKg
类型。但是,一辆 loadLimits
属于以下内容的车辆:
"loadLimits": {
"equipmentRackStorage": {
"maxLoad": 10
}
}
由于缺少无限 weightKg
容量,
weightKg
的负载限制,使车辆不受装运商的限制
权重需求。
加载货物和车辆之间的移交作业
由于货物由车辆取走并送达,因此货物的
loadDemand
在发货和车辆之间转移。您可以看到
在 OptimizeToursResponse
消息的 (REST、
gRPC)routes.transitions
条目。序列为
如下:
- 运送所需的负载能力以
loadDemand
的形式指定。 - 货物由分配的车辆取件,车辆的
vehicleLoads
发货金额增加loadDemand
。这个 在响应中,由正visits.loadDemands
表示转移 消息。 - 车辆交付货物,且车辆的
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]
的加载需求为 10weightKg
。shipments[2]
的加载需求为 80weightKg
。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
的顺序:
- 已取走
shipment[0]
- 已取走
shipment[1]
shipment[0]
已送达shipment[1]
已送达- 已取走
shipment[2]
shipment[2]
已送达
此订单表明以下时间的车辆无法完成 3 项发货:
因为其总loadDemands
超过了车辆的
loadLimits
。
每个 visits
条目都包含因以下原因导致的车辆负载变化:
Visit
。正负载值表示当
负值表示货物卸载。
每个 transitions
条目都包含以下期间内的车辆总负载:
Transition
。例如,transitions[2]
的 weightKg
负载为 60,
表示 shipment[0]
和 shipment[1]
的总加载次数。
指标对象 routes[0].metrics
和 metrics.aggregatedRouteMetrics
包括
maxLoads
属性。类型 weightKg
的值为 80,表示
将shipments[2]
传送到其
送货地点。
软负载限制限制条件
与自提和送货时间范围中所述的时间范围相同
限制条件,负载限制限制条件有硬性变体和软性变体。通过
LoadLimit
消息的 maxLoad
属性表示了一个硬性约束:
车辆载重不得超过指定值 maxLoad
类型。属性 softMaxLoad
和 costPerUnitAboveSoftMax
表示柔和的
限制,每个超过 softMaxLoad
的单位都会产生
费用为 costPerUnitAboveSoftMax
。
软负载限制限制条件有多种用途,例如:
- 均衡车辆数量,确保车辆数量超过所需的最低数量 当这样做更具成本效益时
- 表达驾驶员对舒适物品数量的偏好 在指定路线上自提和送餐
- 将车辆装入低于其最大物理容量的车辆,以减少磨损和 降低维护成本
硬负载限制和软负载限制可结合使用。例如,硬性 载重限制可能表示车辆可安全携带的最大货物重量 一辆车中同时装有的物品数量上限,而 软负载限制可能是需缴税的最大重量或商品数量 让驾驶员能够将各种设备装在车内。