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

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

다음 예에서는 depot이라는 단일 위치에서 시작되는 차량 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는 경로 최적화가 폴리라인을 반환해야 하는지 여부를 지정합니다.

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

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

글로벌 시간 제약

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

위치 방문

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

도착 및 출발 waypointlatLng의 대안으로 사용할 수 있습니다. 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이고 기간이 0인 전환이 있습니다.

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

간단한 경유지 순서 최적화

이 예에서 볼 수 있듯이 경로 최적화 모델은 방문을 배송의 속성으로 모델링하며 독립적인 엔티티로서의 경유지 또는 정류장 개념이 없습니다. 하지만 정류장이나 경유지를 픽업 또는 배송으로 VisitRequest가 정확히 하나인 배송으로 나타낼 수 있습니다. 최적화 프로그램이 가능한 경로가 아닌 최적의 경로를 찾으려면 차량에 costPerHour 또는 costPerKilometer가 할당되어 있어야 합니다.