이 가이드에서는 loadDemands
및 loadLimits
와 그 상호 관계에 대해 설명합니다.
수령 및 배송 시간 기간 제약 조건에서 언급했듯이
OptimizeToursRequest
메시지 (REST, gRPC)에는
최적화 중인 문제에 대한 제약조건을 지정하는 속성을 사용합니다. 여러 개
OptimizeToursRequest
속성은 로드 제약조건을 나타냅니다.
차량과 배송은 배송 시 고려해야 할 물리적 속성을 경로를 계획합니다.
- 차량:
loadLimits
속성은 처리할 수 있습니다.Vehicle
메시지(REST, gRPC) 문서를 참고하세요. - Shipments:
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
}
}
배송에 필요한 weightKg
유형의 적재 단위 50개
완료되었습니다. 다음 중 loadLimits
가 있는 차량:
"loadLimits": {
"weightKg": {
"maxLoad": 100
}
}
weightKg
유형의 차량 maxLoad
가 weightKg
유형의 배송 loadDemands
보다 크거나 같으므로 배송을 완료할 수 있음 단, loadLimits
이(가) 있는 차량은 다음과 같습니다.
"loadLimits": {
"equipmentRackStorage": {
"maxLoad": 10
}
}
Google Cloud Storage 버킷이 없으므로 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]
의 부하 수요는 50weightKg
입니다.shipments[1]
의 부하 수요는 10weightKg
입니다.shipments[2]
의 부하 수요는 80weightKg
입니다.vehicles[0]
의 로드 한도는weightKg
100개입니다.
로드 수요 및 한도
{ "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
비용이 발생하는 느슨한 제약 조건을 나타냅니다.
소프트 로드 제한 제약 조건은 다음과 같은 여러 용도로 사용됩니다.
- 필요한 최소 수보다 많은 차량에 걸쳐 배송 균형을 맞추는 경우 가장 효율적일 때
- 운전자가 특정 경로에서 편안하게 픽업하고 배송할 수 있는 상품 수에 대한 선호사항을 표현합니다.
- 마모를 제한하기 위해 최대 물리적 용량 이하로 적재하는 데 유지보수 비용 절감
하드 및 소프트 로드 제한 제약 조건을 함께 사용할 수 있습니다. 예를 들어 하드 화물 한도는 차량이 안전하게 운반할 수 있는 화물의 최대 중량을 나타낼 수 있습니다. 또는 한 번에 차량에 실을 수 있는 최대 품목 수를 계산할 수 있는 반면, 소프트 로드 한도는 세금이 부과되는 최대 중량 또는 상품의 개수일 수 있습니다. 차량에 모든 것을 장착할 수 있는 운전자의 능력에 따라 달라질 수 있습니다.