Hướng dẫn này mô tả loadDemands
và loadLimits
, cũng như mối quan hệ giữa các lớp này với nhau.
Như đã đề cập trong Giới hạn về cửa sổ thời gian nhận hàng và giao hàng, thông báo OptimizeToursRequest
(REST, gRPC) chứa một số thuộc tính chỉ định các điều kiện ràng buộc đối với vấn đề đang được tối ưu hoá. Một số thuộc tính OptimizeToursRequest
đại diện cho các quy tắc ràng buộc tải.
Xe và lô hàng có các thuộc tính vật lý mà bạn phải xem xét khi lên kế hoạch cho một tuyến đường.
- Xe: Thuộc tính
loadLimits
chỉ định tải trọng tối đa mà xe có thể xử lý. Xem tài liệu (REST, gRPC) của thông báoVehicle
. - Shipment (Gói): Thuộc tính
loadDemands
chỉ định lượng tải mà một gói nhất định tiêu thụ. Xem tài liệu về thông báoShipment
(REST, gRPC).
Hai quy tắc ràng buộc này cùng nhau giúp trình tối ưu hoá có thể chỉ định lô hàng cho xe một cách phù hợp theo cách phù hợp nhất với công suất của đội xe và nhu cầu vận chuyển.
Phần còn lại của tài liệu này sẽ thảo luận chi tiết về loadLimits
và loadDemands
.
Nhu cầu tải và giới hạn: loại
Bạn thể hiện từng yêu cầu tải và giới hạn ràng buộc theo loại.
Bạn có thể cung cấp bộ loại tải của riêng mình, như các ví dụ sau:
- cân nặng
- thể tích
- phép đo tuyến tính
- tên của mặt hàng hoặc thiết bị được vận chuyển
Hướng dẫn này sử dụng weightKg
làm loại ví dụ.
Cả Shipment.loadDemands
và Vehicle.loadLimits
đều sử dụng loại Vùng đệm giao thức map
, với các khoá string
đại diện cho các loại tải.
Các giá trị Shipment.loadDemands
sử dụng thông báo Load
(REST, gRPC).
Thông báo Load
có một thuộc tính amount
duy nhất thể hiện dung lượng cần thiết để hoàn tất lô hàng theo loại đã chỉ định.
Các giá trị Vehicle.loadLimits
sử dụng thông báo LoadLimit
(REST,
gRPC). Thông báo LoadLimit
có một số thuộc tính, trong đó maxLoad
đại diện cho tải trọng tối đa của xe trong loại được chỉ định.
loadDemands
của lô hàng chỉ sử dụng loadLimits
của xe được chỉ định nếu hai khoá này có khoá loại tải phù hợp. Ví dụ: một lô hàng có loadDemands
là:
"loadDemands": {
"weightKg": {
"amount": 50
}
}
cần có 50 đơn vị tải thuộc loại weightKg
thì mới có thể hoàn tất quá trình vận chuyển. Xe có loadLimits
là:
"loadLimits": {
"weightKg": {
"maxLoad": 100
}
}
có thể hoàn tất lô hàng, vì maxLoad
của xe trong loại weightKg
lớn hơn hoặc bằng loadDemands
của lô hàng trong loại weightKg
. Tuy nhiên, xe có loadLimits
:
"loadLimits": {
"equipmentRackStorage": {
"maxLoad": 10
}
}
ngầm ẩn có dung lượng weightKg
không giới hạn do không có giới hạn tải weightKg
, vì vậy, xe không bị ràng buộc bởi nhu cầu trọng lượng của lô hàng.
Chuyển tải giữa các lô hàng và xe
Khi hàng được vận chuyển bằng phương tiện vận chuyển, loadDemand
của lô hàng sẽ chuyển giữa phương tiện vận chuyển và phương tiện vận chuyển. Bạn có thể xem tải của xe trong mục nhập routes.transitions
của thông báo OptimizeToursResponse
(REST, gRPC) cho một xe nhất định. Trình tự như sau:
- Dung lượng tải bắt buộc được xác định cho lô hàng dưới dạng
loadDemand
. - Xe được chỉ định sẽ đến lấy hàng và
vehicleLoads
của xe sẽ tăng thêm số lượngloadDemand
của lô hàng. Quá trình chuyển này được biểu thị bằngvisits.loadDemands
dương trong thông báo phản hồi. - Xe vận chuyển lô hàng và
vehicleLoads
của xe giảm xuống bằng số lượngloadDemand
của lô hàng đã vận chuyển. Quá trình chuyển này được biểu thị bằngvisits.loadDemands
âm trong thông báo phản hồi.
vehicleLoads
của xe không được vượt quá loadLimits
đã chỉ định tại bất kỳ điểm nào trên tuyến đường.
Ví dụ đầy đủ về các yêu cầu và giới hạn tải
Xem một yêu cầu mẫu có các giới hạn và nhu cầu tải
{ "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 } } } ] } }
Yêu cầu mẫu chứa một số tham số liên quan đến tải:
shipments[0]
có nhu cầu tải là 50weightKg
.shipments[1]
có nhu cầu tải là 10weightKg
.shipments[2]
có nhu cầu tải là 80weightKg
.vehicles[0]
có giới hạn tải là 100weightKg
.
Xem phản hồi cho yêu cầu có nhu cầu tải và giới hạn
{ "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 } } }
Các quy tắc ràng buộc tải được thêm vào ảnh hưởng đến thứ tự của visits
:
shipment[0]
được nhận- Đã nhận
shipment[1]
shipment[0]
được phân phối- Đã giao
shipment[1]
shipment[2]
được nhậnshipment[2]
được phân phối
Đơn đặt hàng này cho thấy rằng xe không thể hoàn tất 3 lô hàng cùng một lúc vì tổng loadDemands
của các lô hàng này vượt quá loadLimits
của xe.
Mỗi mục nhập visits
bao gồm sự thay đổi về tải xe do việc hoàn tất Visit
. Giá trị tải dương biểu thị việc bốc hàng, còn giá trị âm biểu thị việc dỡ hàng.
Mỗi mục nhập transitions
bao gồm tổng tải trọng của xe trong Transition
. Ví dụ: transitions[2]
có tải weightKg
là 60, đại diện cho tải kết hợp của shipment[0]
và shipment[1]
.
Các đối tượng chỉ số routes[0].metrics
và metrics.aggregatedRouteMetrics
bao gồm thuộc tính maxLoads
. Giá trị cho loại weightKg
là 80, đại diện cho phần tuyến đường của xe đã vận chuyển shipments[2]
đến vị trí giao hàng.
Quy tắc ràng buộc giới hạn tải mềm
Cũng như các khoảng thời gian được mô tả trong phần Hạn chế về khoảng thời gian lấy hàng và giao hàng, các quy tắc hạn chế về tải có các biến thể cứng và mềm. Thuộc tính maxLoad
của thông báo LoadLimit
thể hiện một quy tắc ràng buộc cứng: xe không được chở tải vượt quá giá trị maxLoad
trong loại đã chỉ định. Thuộc tính softMaxLoad
và costPerUnitAboveSoftMax
thể hiện một quy tắc ràng buộc mềm, trong đó mỗi đơn vị vượt quá softMaxLoad
sẽ phải chịu chi phí costPerUnitAboveSoftMax
.
Quy tắc ràng buộc giới hạn tải mềm có một số cách sử dụng, chẳng hạn như:
- cân bằng các lô hàng trên nhiều xe hơn số lượng tối thiểu cần thiết khi tiết kiệm chi phí để thực hiện điều đó
- thể hiện mong muốn của người lái xe về số lượng mặt hàng mà họ có thể nhận hàng thoải mái và giao trên một tuyến đường nhất định
- tải xe dưới mức dung lượng vật lý tối đa để hạn chế hao mòn và giảm chi phí bảo dưỡng
Bạn có thể sử dụng cùng lúc các điều kiện ràng buộc giới hạn tải cứng và mềm. Ví dụ: giới hạn tải cứng có thể thể hiện trọng lượng tối đa của hàng hoá mà một xe có thể chở một cách an toàn hoặc số lượng mặt hàng tối đa có thể vừa với một xe cùng một lúc, trong khi giới hạn tải mềm có thể là trọng lượng hoặc số lượng mặt hàng tối đa sẽ làm giảm khả năng của người lái xe để vừa với mọi thứ trong xe.