수령 및 배달에 관한 기본적인 주문 중단 주문 최적화

이 시나리오에서는 간단한 비용 매개변수를 사용하여 차량에 할당된 정류장 순서를 최적화합니다. 이는 가장 간단한 경로 최적화 작업 모드이며, 지정된 시간 내에 모든 정류장을 방문하도록 보장합니다.

다음 예는 차량 1대와 배송 3건이 모두 창고라고 하는 단일 위치에서 출발하는 기본 시나리오를 보여줍니다.

요청 예시 보기

      {
        "populatePolylines": true,
        "populateTransitionPolylines": true,
        "model": {
          "globalStartTime": "2023-01-13T16:00:00-08:00",
          "globalEndTime": "2023-01-14T16:00:00-08:00",
          "shipments": [
            {
              "deliveries": [
                {
                  "arrivalLocation": {
                    "latitude": 37.789456,
                    "longitude": -122.390192
                  },
                  "duration": "250s"
                }
              ],
              "pickups": [
                {
                  "arrivalLocation": {
                    "latitude": 37.794465,
                    "longitude": -122.394839
                  },
                  "duration": "150s"
                }
              ]
            },
            {
              "deliveries": [
                {
                  "arrivalLocation": {
                    "latitude": 37.789116,
                    "longitude": -122.395080
                  },
                  "duration": "250s"
                }
              ],
              "pickups": [
                {
                  "arrivalLocation": {
                    "latitude": 37.794465,
                    "longitude": -122.394839
                  },
                  "duration": "150s"
                }
              ]
            },
            {
              "deliveries": [
                {
                  "arrivalLocation": {
                    "latitude": 37.795242,
                    "longitude": -122.399347
                  },
                  "duration": "250s"
                }
              ],
              "pickups": [
                {
                  "arrivalLocation": {
                    "latitude": 37.794465,
                    "longitude": -122.394839
                  },
                  "duration": "150s"
                }
              ]
            }
          ],
          "vehicles": [
            {
              "endLocation": {
                "latitude": 37.794465,
                "longitude": -122.394839
              },
              "startLocation": {
                "latitude": 37.794465,
                "longitude": -122.394839
              },
              "costPerKilometer": 10.0,
              "costPerHour": 40.0
            }
          ]
        }
      }
    

경로 최적화 요청 필드

개요에서 언급했듯이 가장 중요한 경로 최적화 요청 속성은 vehiclesshipments입니다.

요청에는 차량 및 배송 외에도 다음 필드가 포함됩니다.

다중선

populatePolylinespopulateTransitionPolylines는 경로 최적화에서 다중선을 반환해야 하는지 여부를 지정합니다.

이 서비스는 Maps JS 다중선 코덱을 사용하여 다중선을 인코딩합니다. 코덱은 인쇄 가능한 ASCII 문자를 사용하여 바이너리 다중선 데이터를 나타냅니다. 대화형 다중선 인코더 유틸리티를 사용하여 경로 최적화로 계산된 경로를 시각화할 수 있습니다. 이 가이드의 예에서는 populatePolylinespopulateTransitionPolylines를 true로 설정하지만 다른 가이드에서는 응답 크기를 줄이기 위해 이를 false로 설정합니다.

인코딩 형식에 대한 설명은 인코딩된 다중선 알고리즘 형식을 참고하세요.

전 세계 시간 제한

model.globalStartTimemodel.globalEndTime는 임의의 24시간 기간으로 설정됩니다. 이렇게 하면 출력 타임스탬프를 더 쉽게 해석할 수 있습니다.

위치 방문

요청 예시에서는 model.shipments[].pickups[].arrivalLocationmodel.shipments[].deliveries[].arrivalLocation만 사용합니다. 또한 건물 한 쪽에는 입구가 있고 다른 쪽에는 출구가 있는 주차장 단지와 같이 차량이 도착하는 지점과 다른 지점에서 출발하는 상황을 위한 departureLocation 속성도 있습니다. 이 가이드와 이후 가이드에서는 도착 지점과 출발 지점이 동일한 것으로 간주됩니다.

도착 및 출발 waypoint을(를) latLng 대신 사용할 수도 있습니다. Waypoint 필드는 LatLng 대신 Google 장소 ID를 사용할 수 있도록 지원하며 차량 방향을 지정할 수도 있습니다. 자세한 내용은 참조 문서(REST, gRPC)를 확인하세요.

예시의 제약조건

이 시나리오는 다음과 같은 몇 가지 방법으로 옵티마이저를 제한합니다.

  1. 모든 활동은 전역 시작 시간 및 종료 시간 사이에 완료되어야 합니다. 이 시나리오에서는 배송이 가깝고 전역 기간이 넓다는 점을 고려할 때 시작 시간과 종료 시간이 매우 느슨합니다.
  2. 모든 배송을 완료해야 합니다. 이는 페널티 비용이 shipments에 지정되지 않은 경우의 기본 동작입니다.
  3. costPerKilometercostPerHour가 차량에 설정되어 있습니다.

비용은 비용 모델 매개변수에서 다룹니다.

경로 최적화 응답 속성

예시 요청에 대한 응답 보기

    {
      "routes": [
        {
          "vehicleStartTime": "2023-01-14T00:00:00Z",
          "vehicleEndTime": "2023-01-14T00:36:41Z",
          "visits": [
            {
              "shipmentIndex": 2,
              "isPickup": true,
              "startTime": "2023-01-14T00:00:00Z",
              "detour": "0s"
            },
            {
              "shipmentIndex": 1,
              "isPickup": true,
              "startTime": "2023-01-14T00:02:30Z",
              "detour": "150s"
            },
            {
              "isPickup": true,
              "startTime": "2023-01-14T00:05:00Z",
              "detour": "300s"
            },
            {
              "startTime": "2023-01-14T00:11:25Z",
              "detour": "0s"
            },
            {
              "shipmentIndex": 1,
              "startTime": "2023-01-14T00:19:29Z",
              "detour": "503s"
            },
            {
              "shipmentIndex": 2,
              "startTime": "2023-01-14T00:29:02Z",
              "detour": "1324s"
            }
          ],
          "transitions": [
            {
              "travelDuration": "0s",
              "waitDuration": "0s",
              "totalDuration": "0s",
              "startTime": "2023-01-14T00:00:00Z",
              "routePolyline": {}
            },
            {
              "travelDuration": "0s",
              "waitDuration": "0s",
              "totalDuration": "0s",
              "startTime": "2023-01-14T00:02:30Z",
              "routePolyline": {}
            },
            {
              "travelDuration": "0s",
              "waitDuration": "0s",
              "totalDuration": "0s",
              "startTime": "2023-01-14T00:05:00Z",
              "routePolyline": {}
            },
            {
              "travelDuration": "235s",
              "travelDistanceMeters": 795,
              "waitDuration": "0s",
              "totalDuration": "235s",
              "startTime": "2023-01-14T00:07:30Z",
              "routePolyline": {
                "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@"
              }
            },
            {
              "travelDuration": "234s",
              "travelDistanceMeters": 793,
              "waitDuration": "0s",
              "totalDuration": "234s",
              "startTime": "2023-01-14T00:15:35Z",
              "routePolyline": {
                "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@"
              }
            },
            {
              "travelDuration": "323s",
              "travelDistanceMeters": 1204,
              "waitDuration": "0s",
              "totalDuration": "323s",
              "startTime": "2023-01-14T00:23:39Z",
              "routePolyline": {
                "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@"
              }
            },
            {
              "travelDuration": "209s",
              "travelDistanceMeters": 665,
              "waitDuration": "0s",
              "totalDuration": "209s",
              "startTime": "2023-01-14T00:33:12Z",
              "routePolyline": {
                "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A"
              }
            }
          ],
          "routePolyline": {
            "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@RWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@STY@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A"
          },
          "metrics": {
            "performedShipmentCount": 3,
            "travelDuration": "1001s",
            "waitDuration": "0s",
            "delayDuration": "0s",
            "breakDuration": "0s",
            "visitDuration": "1200s",
            "totalDuration": "2201s",
            "travelDistanceMeters": 3457
          },
          "travelSteps": [
            {
              "duration": "0s",
              "routePolyline": {}
            },
            {
              "duration": "0s",
              "routePolyline": {}
            },
            {
              "duration": "0s",
              "routePolyline": {}
            },
            {
              "duration": "227s",
              "distanceMeters": 794,
              "routePolyline": {
                "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@"
              }
            },
            {
              "duration": "233s",
              "distanceMeters": 791,
              "routePolyline": {
                "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@"
              }
            },
            {
              "duration": "322s",
              "distanceMeters": 1205,
              "routePolyline": {
                "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@"
              }
            },
            {
              "duration": "208s",
              "distanceMeters": 666,
              "routePolyline": {
                "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A"
              }
            }
          ],
          "vehicleDetour": "2201s",
          "routeCosts": {
            "model.vehicles.cost_per_hour": 24.455555555555556,
            "model.vehicles.cost_per_kilometer": 34.57
          },
          "routeTotalCost": 59.025555555555556
        }
      ],
      "totalCost": 59.025555555555556,
      "metrics": {
        "aggregatedRouteMetrics": {
          "performedShipmentCount": 3,
          "travelDuration": "1001s",
          "waitDuration": "0s",
          "delayDuration": "0s",
          "breakDuration": "0s",
          "visitDuration": "1200s",
          "totalDuration": "2201s",
          "travelDistanceMeters": 3457
        },
        "usedVehicleCount": 1,
        "earliestVehicleStartTime": "2023-01-14T00:00:00Z",
        "latestVehicleEndTime": "2023-01-14T00:36:41Z",
        "totalCost": 59.025555555555556,
        "costs": {
          "model.vehicles.cost_per_kilometer": 34.57,
          "model.vehicles.cost_per_hour": 24.455555555555556
        }
      }
    }
    

경로 최적화 응답에는 제안된 경로를 나타내는 최상위 routes 필드가 포함되며 차량당 하나의 경로가 포함됩니다. 이 가이드의 요청 예시에서는 하나의 차량만 지정하므로 routes에는 ShipmentRoute 메시지가 한 개 포함됩니다.

숙박 시설 ShipmentRoute

ShipmentRoute 메시지 유형의 가장 중요한 두 가지 속성은 visitstransitions입니다.

Visit는 요청 메시지의 VisitRequest 중 하나에서 수령 또는 배달 완료를 나타냅니다. 방문은 특정 장소 및 시간에 차량이 완료해야 하는 작업을 효과적으로 할당합니다.

Transition는 한 위치에서 다음 위치로 이동하는 차량을 나타냅니다. 차량의 출발점, 방문 위치, 차량의 엔드포인트 간에 전환이 발생할 수 있습니다.

차량의 전체 경로를 재구성하려면 ShipmentRoutevisitstransitions를 결합해야 합니다. 차량 활동의 진행으로 필드를 조합하는 방식은 다음과 같습니다.

request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation

ShipmentRoute에는 항상 visits보다 transitions가 하나 더 있습니다. 이는 차량이 경로 시작 시 첫 번째 방문에서 그리고 마지막 방문에서 경로 끝의 종료 위치로 이동해야 하기 때문입니다. 차량에 시작 또는 종료 위치가 없는 경우 첫 번째 또는 마지막 방문 위치가 각각 차량의 시작 또는 종료 위치로 사용되므로 visits보다 transitions가 여전히 하나 더 있습니다.

이 예에서 처음 세 개의 승차 방문은 요청에서 거리와 시간이 0인 전환이 발생합니다. 3개의 승차가 모두 요청에서 동일한 위치를 공유하기 때문입니다.

자세한 내용은 ShipmentRoute 참조 문서 (REST, gRPC)를 확인하세요.

간단한 경유지 순서 최적화

이 예에서 알 수 있듯이 경로 최적화에서는 방문을 배송 속성으로 모델링하며 경유지나 정류장을 독립적인 항목으로 개념하지 않습니다. 하지만 정류장이나 경유지를 픽업 또는 배달로 VisitRequest가 정확히 1개 있는 배송 화물로 표시할 수도 있습니다. 최적화 도구에서 최적 경로를 찾으려면 차량에 여전히 costPerHour 또는 costPerKilometer를 할당해야 합니다 (가능한 모든 경로를 찾는 것이 아님).