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

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

다음 예는 모두 창고라는 단일 위치에서 출발하는 차량 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인 전환이 있습니다.

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

간단한 경유지 순서 최적화

이 예에서 볼 수 있듯이 경로 최적화 모델은 방문을 배송의 속성으로 모델링하며 독립된 항목으로 중간 지점 또는 정류장 개념을 갖고 있지 않습니다. 하지만 VisitRequest을 픽업 또는 배송으로 정확히 하나만 사용하여 중간 정류장 또는 중간 지점을 배송으로 나타낼 수 있습니다. 최적화 도구가 실행 가능한 경로를 찾는 것이 아니라 최적의 경로를 찾으려면 차량에 여전히 costPerHour 또는 costPerKilometer가 할당되어야 합니다.