本指南將說明 loadDemands
和 loadLimits
,以及這兩者之間的關係
其他。
如上車和送達時間限制所述,OptimizeToursRequest
訊息 (REST、gRPC) 包含多個屬性,可指定要最佳化的問題的限制。數個
OptimizeToursRequest
屬性代表載入限制。
車輛和貨運具有實體屬性 來規劃路線
- 車輛:
loadLimits
屬性會明確指出車輛可處理的最大負載量。請參閱Vehicle
訊息 (REST、gRPC) 的說明文件。 - Shipments:
loadDemands
屬性會指定指定出貨項目會消耗多少負載。請參閱Shipment
訊息 (REST、gRPC) 的說明文件。
這兩項限制條件結合後,最佳化工具就能根據車隊容量和運送需求,適當地將貨物指派給車輛。
本文件其餘部分會深入探討 loadLimits
和 loadDemands
。
負載需求和限制:類型
您可以按照「類型」表達每個載入需求和限制。
您可以提供自己的一組載入類型,如以下範例所示:
- 重量
- 磁碟區
- 線性測量
- 運輸項目或設備的名稱
本指南使用 weightKg
做為示例類型。
Shipment.loadDemands
和 Vehicle.loadLimits
都使用 Protocol Buffers map
類型,其中 string
鍵代表負載類型。
Shipment.loadDemands
值會使用 Load
訊息 (REST、gRPC)。Load
訊息含有單一 amount
屬性,代表在指定類型中完成出貨所需的容量。
Vehicle.loadLimits
值使用 LoadLimit
訊息 (REST、
gRPC)。LoadLimit
訊息有多個屬性,其中包含 maxLoad
代表指定類型的車輛最大負荷容量。
只有在下列情況下,貨物的 loadDemands
才會耗用獲派車輛的 loadLimits
這兩者有相符的載入類型鍵例如,出貨項目的 loadDemands
為:
"loadDemands": {
"weightKg": {
"amount": 50
}
}
規定 weightKg
類型須有 50 個載入單元,才能進行出貨
已完成車輛的 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
數量。這項轉移作業會在回應訊息中以 positivevisits.loadDemands
表示。 - 車輛送貨,車輛
vehicleLoads
減少 實際乘載出貨的loadDemand
。這項轉移作業會在回應訊息中以 negativevisits.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]
的負載需求為 50weightKg
。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]
此訂單反映的車輛無法履行
同時,因為乘客的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
費用。
軟負載限制有以下幾種用途:
- 在成本效益可接受的情況下,將貨物分配給比必要數量更多的車輛
- 凸顯出駕駛人能舒適無比的物品數量 指定路線上自取和外送
- 載入車輛低於其實際容量上限的車輛,以減少佩戴和 降低維護成本
硬負載限制和軟負載限制可以搭配使用。舉例來說,硬負載限制可能會表示車輛可安全載運的最大貨物重量,或一次可放入車輛的最大物品數量,而軟負載限制則可能是駕駛員可將所有物品放入車輛的最大重量或數量。