OptimizeToursRequest
는 다음 항목에 제약 조건을 적용합니다.
- 배송(배송 수행 방식에 영향을 미치는 배송)
- 차량 경로 계산 방식에 영향을 미치는 차량
- 전 세계적으로 차량과 배송 모두에 영향을 미칩니다.
이 가이드에서는 필수적인 배송 제약 조건인 기간에 대해 중점적으로 설명합니다.
기간은
OptimizeToursRequest
메시지 (REST, gRPC)를 사용하여
배송 활동에 대한 시간 기반 한도 이러한 유형의 제약 조건은
배송이 가능한 시기 및 방법과 차량 할당
합니다. 이러한 제약조건을 토대로 최적화 도구는 배송의 시간 제약조건을 가장 잘 충족할 수 있는 차량을 우선시합니다.
배송 제약조건: 기간
Shipment.VisitRequest
에서 수령 또는 배달 가능 시간을 지정합니다.
메시지를 보냅니다.
기간 제약 조건이 있는 요청 예
이 예는 세 개의 서로 다른 배송을 보여주며 각각 자체
배송 기간입니다. 이 예에서는 편의상 deliveries
에 기간을 설정합니다.
기간은 승차 위치에도 적용할 수 있습니다. 기간이 여러 개인 경우
이 예에서는 전송 VisitRequest
당 하나만 사용합니다.
기간이 포함된 요청 예시 보기
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T19:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T18:30:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "endTime": "2023-01-13T18:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
기간 제약 조건이 있는 응답 예
응답 예에서 차량의 시작 및 종료 시간은 17:35:50이고
18:17:24입니다. 이 시간은 옵티마이저가 시간을 최소화하는 것을
요청에 costPerHour
로 지정된 차량을 작동하는 데 필요한
모든 기간 제약 조건을
충족해야 합니다 시작 시간으로 17:35:50 사용
차량이 대기할 필요가 없어지고
확인할 수 있습니다. 응답에 0 waitDuration
으로 표시됩니다.
값으로 사용됩니다.
다음 명령어로 예시 요청에 대한 응답을 확인합니다. 기간
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:35:50Z", "vehicleEndTime": "2023-01-13T18:17:24Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:35:50Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T17:38:20Z", "detour": "150s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:40:50Z", "detour": "300s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T17:50:09Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-13T18:00:00Z", "detour": "796s" }, { "startTime": "2023-01-13T18:07:35Z", "detour": "1520s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:35:50Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:38:20Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:40:50Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T17:43:20Z" }, { "travelDuration": "341s", "travelDistanceMeters": 1312, "waitDuration": "0s", "totalDuration": "341s", "startTime": "2023-01-13T17:54:19Z" }, { "travelDuration": "205s", "travelDistanceMeters": 636, "waitDuration": "0s", "totalDuration": "205s", "startTime": "2023-01-13T18:04:10Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-13T18:11:45Z" } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "1294s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2494s", "travelDistanceMeters": 4595 }, "routeCosts": { "model.vehicles.cost_per_hour": 27.711111111111112, "model.vehicles.cost_per_kilometer": 45.95 }, "routeTotalCost": 73.661111111111111 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1294s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2494s", "travelDistanceMeters": 4595 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:35:50Z", "latestVehicleEndTime": "2023-01-13T18:17:24Z", "totalCost": 73.661111111111111, "costs": { "model.vehicles.cost_per_hour": 27.711111111111112, "model.vehicles.cost_per_kilometer": 45.95 } } }
기간에서 차량의 visits
를 주문했으므로
가장 이른 시간 기간이 먼저
전송됩니다
shipments[2]
은 17:50에 배송됩니다.shipments[1]
배송 예정 시간: 18:00shipments[0]
이 18:07에 전송됨
요청 예에는 하드 기간 제약 조건이 지정되어 있으며,
배송을 완료해야 합니다. 시간 범위 내에 배송의 VisitRequests
를 완료하는 것이 실행 가능하지 않거나 비용 효율적이지 않은 경우 최적화 도구는 배송을 건너뜁니다. 배송에 penaltyCost
가 있는 경우 최적화 도구는 metrics
응답에 보고된 비용에 이를 추가합니다. 그렇지 않은 경우 skippedMandatoryShipmentCount
속성이
OptimizeToursResponse
메시지 (REST, gRPC)가 증가합니다.
shipment[1]
의 기간을 몇 시간씩 이동하여 기간을 변경하는 경우
18:00부터 21:00까지를 실행하는 경우 결과는
살펴보겠습니다
다음과 같은 기간이 포함된 요청 예를 참고하세요. 만족하기
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T19:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T21:00:00Z", "endTime": "2023-01-13T21:30:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "endTime": "2023-01-13T18:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
두 번째 예시 요청에 대한 응답을 확인합니다. 배송을 건너뛰는 기간
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:37:49Z", "vehicleEndTime": "2023-01-13T18:09:49Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:37:49Z", "detour": "0s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:40:19Z", "detour": "150s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T17:49:38Z", "detour": "0s" }, { "startTime": "2023-01-13T18:00:00Z", "detour": "946s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:37:49Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:40:19Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T17:42:49Z" }, { "travelDuration": "372s", "travelDistanceMeters": 1348, "waitDuration": "0s", "totalDuration": "372s", "startTime": "2023-01-13T17:53:48Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-13T18:04:10Z" } ], "metrics": { "performedShipmentCount": 2, "travelDuration": "1120s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1920s", "travelDistanceMeters": 3995 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 39.95, "model.vehicles.cost_per_hour": 21.333333333333332 }, "routeTotalCost": 61.283333333333331 } ], "skippedShipments": [ { "index": 1 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 2, "travelDuration": "1120s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1920s", "travelDistanceMeters": 3995 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:37:49Z", "latestVehicleEndTime": "2023-01-13T18:09:49Z", "totalCost": 81.283333333333331, "costs": { "model.shipments.penalty_cost": 20, "model.vehicles.cost_per_hour": 21.333333333333332, "model.vehicles.cost_per_kilometer": 39.95 } } }
이 예시에서는 이후 기간으로 인해 shipment[1]
를 건너뛰었습니다.
배송을 완료하는 데 필요한 추가 차량 운행 시간이
지정된 기간 내에 배송 건이 배송 위약금을 초과했습니다.
shipment[1]
의 패널티 비용은 metrics.costs
에 표시되고 색인값은 skippedShipments
에 표시됩니다.
유연한 시간 윈도우 제약조건
비용 모델 매개변수에서 간단히 언급했듯이 시간 창은 소프트 제약조건으로 적용할 수 있습니다. 유연한 제약 조건은 다음과 같이 엄격한 제약 조건과 다릅니다.
- 엄격한 제약조건: 위반할 수 없으며 최적화 도구는 배송 건너뛰기를 의미하더라도 제약조건을 위반하는 솔루션을 제공하지 않습니다.
- 소프트 제약 조건: 위반할 수 있습니다. 즉, 최적화 도구에서 유연한 제약 조건을 위반하는 솔루션을 제공합니다. 그러나 최적화 도구는 위반사항에 비용도 적용합니다. 이 비용을 일정 기간 동안 추가 속성, 일반적으로 활동이 발생하는 시간 범위 전후 1시간 간격
대신 softStartTime
또는 softEndTime
를 사용하여 기간을 낮춥니다.
각각 startTime
또는 endTime
,
costPerHourBeforeSoftStartTime
또는 costPerHourAfterSoftEndTime
수령 또는 배달이 발생해야 하는 경우 비고정 시간대 제약조건을 사용하세요. 배송 상품을 수령 또는 배송하는 경우 반드시 필요합니다 하드 및 소프트 기간 제약 조건을 함께 사용할 수 있습니다. 비즈니스 목표를 표현할 수 있습니다. 예를 들면 다음과 같습니다.
- 하드 타임 기간: 고객의 영업시간을 나타냅니다(예: 오전 9시부터 오후 5시까지입니다.
- 비공식 시간대: 특정 상품의 배송 또는 수령 시간을 나타냅니다. 고객에게 전송되는 알림과 일치합니다(예: 오전 9시~오후 1시).
이 예시에서는 시간이 지나 건너뛴 배송이 기간이 너무 늦게 시작된 경우 시작 시간 제한이 완화되었습니다. 다른 배송할 수 있습니다. 종료 시간도 부드럽게 됩니다
명확한 시간대와 유연한 시간대의 요청 예 보기
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "softEndTime": "2023-01-13T19:00:00Z", "costPerHourAfterSoftEndTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "softStartTime": "2023-01-13T21:00:00Z", "endTime": "2023-01-13T21:30:00Z", "costPerHourBeforeSoftStartTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "softEndTime": "2023-01-13T18:00:00Z", "costPerHourAfterSoftEndTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
하드 및 소프트 타임 기간
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:48:35Z", "vehicleEndTime": "2023-01-13T18:24:28Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:48:35Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T17:51:05Z", "detour": "150s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:53:35Z", "detour": "300s" }, { "startTime": "2023-01-13T18:00:00Z", "detour": "300s" }, { "shipmentIndex": 1, "startTime": "2023-01-13T18:07:42Z", "detour": "493s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T18:17:27Z", "detour": "873s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:48:35Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:51:05Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:53:35Z" }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-13T17:56:05Z" }, { "travelDuration": "212s", "travelDistanceMeters": 791, "waitDuration": "0s", "totalDuration": "212s", "startTime": "2023-01-13T18:04:10Z" }, { "travelDuration": "335s", "travelDistanceMeters": 1204, "waitDuration": "0s", "totalDuration": "335s", "startTime": "2023-01-13T18:11:52Z" }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-13T18:21:37Z" } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "953s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2153s", "travelDistanceMeters": 3455 }, "routeCosts": { "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667, "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332, "model.vehicles.cost_per_hour": 23.922222222222221, "model.vehicles.cost_per_kilometer": 34.55 }, "routeTotalCost": 64.797222222222217 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "953s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2153s", "travelDistanceMeters": 3455 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:48:35Z", "latestVehicleEndTime": "2023-01-13T18:24:28Z", "totalCost": 64.797222222222217, "costs": { "model.vehicles.cost_per_kilometer": 34.55, "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332, "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667, "model.vehicles.cost_per_hour": 23.922222222222221 } } }
하드 타임 기간 제약 조건만 있는 예시를 완전히 건너뛴 경우
shipment[1]
, 배송 기간을 완화하면 배송됩니다.
이전입니다. 마찬가지로
다른 배송 상품으로 인해 shipment[2]
상품을 해당 기간 이후 배송 가능
종료.
동시에 배송비와 총 배송량도 다음과 같이 변경되었습니다.
totalCost
: 81.283에서 64.797로 감소되었습니다.- 총 완료된 배송: 2에서 3으로 증가함
옵티마이저가 비용이 더 적게 드는 솔루션을 찾았습니다. 이전 예에 비해 제약이 완화되었습니다.
마지막으로 metrics.costs
속성에는
제약조건의 곱과
배송 기간을 놓친 시간입니다 이는 다음과 같은 의미입니다.
costPerHourBeforeSoftStartTime
/2.0 및- 기간의 시작 시간 사이의 시간을 나타냅니다. 2.83583시간
결과:
model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time
:
5.6716666666666669).
이러한 측정항목을 사용하면 비용 분석을 통해 하드 제약조건과 소프트 제약조건 간의 균형을 확인할 수 있으며, 이를 사용하여 특정 비즈니스 규칙에 더 적합하도록 제약조건을 조정할 수 있습니다. 이 경우 총비용은
미만입니다.shipment[1].penalty_cost
옵티마이저는 배송을 건너뛰는 것보다 배송을 일찍 처리하는 것이 비용 효율적이라고 판단했습니다.