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