부하 수요 및 한도

이 가이드에서는 loadDemandsloadLimits가 어떻게 연관되어 있는지 설명합니다.

수령 및 배송 시간 창 제약 조건에서 언급했듯이 OptimizeToursRequest 메시지 (REST, gRPC)에는 최적화되는 문제에 관한 제약 조건을 지정하는 여러 속성이 포함되어 있습니다. 여러 OptimizeToursRequest 속성은 로드 제약 조건을 나타냅니다.

차량과 운송의 경우 경로를 계획할 때 고려해야 하는 물리적 속성이 있습니다.

  • Vehicles: loadLimits 속성은 차량이 처리할 수 있는 최대 부하를 지정합니다. Vehicle 메시지 (REST, gRPC) 문서를 참조하세요.
  • 배송: loadDemands 속성은 특정 배송이 소비하는 부하를 지정합니다. Shipment 메시지 (REST, gRPC) 문서를 참조하세요.

이 두 가지 제약 조건을 사용하면 최적화 도구가 차량 용량 및 배송 수요에 가장 적합한 방식으로 차량에 배송을 적절하게 할당할 수 있습니다.

이 문서의 나머지 부분에서는 loadLimitsloadDemands에 대해 자세히 설명합니다.

로드 수요 및 한도: 유형

각 로드 수요 및 제한 제약조건을 유형의 관점에서 표현합니다.

다음 예와 같이 고유한 로드 유형 집합을 제공할 수 있습니다.

  • weight
  • 볼륨
  • 선형 측정
  • 운송하는 물품 또는 장비의 이름

이 가이드에서는 weightKg를 예시 유형으로 사용합니다.

Shipment.loadDemandsVehicle.loadLimits는 모두 로드 유형을 나타내는 string 키와 함께 프로토콜 버퍼 map 유형을 사용합니다.

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 유형에서 차량의 maxLoadweightKg 유형에 있는 배송의 loadDemands보다 크거나 같으므로 배송을 완료할 수 있습니다. 그러나 loadLimits가 다음과 같은 차량은 다음과 같습니다.

"loadLimits": {
  "equipmentRackStorage": {
    "maxLoad": 10
  }
}

weightKg 로드 제한이 없으므로 암시적으로 weightKg 용량이 무제한이므로 차량이 배송 중량 수요의 제약을 받지 않습니다.

배송과 차량 간 부하 이전

차량이 화물을 수령하고 배송함에 따라 화물의 loadDemand가 화물과 차량 간에 이전됩니다. 차량의 로드는 특정 차량의 OptimizeToursResponse 메시지 (REST, gRPC)routes.transitions 항목에서 확인할 수 있습니다. 순서는 다음과 같습니다.

  1. 배송에 필요한 적재 용량은 loadDemand로 정의됩니다.
  2. 할당된 차량이 배송을 수령하고 차량의 vehicleLoads는 배송 상품의 loadDemand 금액만큼 증가합니다. 이 전송은 응답 메시지에 양의 visits.loadDemands로 표시됩니다.
  3. 차량이 화물을 배송하고 차량의 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의 순서에 영향을 줍니다.

  1. shipment[0] 픽업되었습니다
  2. shipment[1] 픽업되었습니다
  3. shipment[0] 배송됨
  4. shipment[1] 배송됨
  5. shipment[2] 픽업되었습니다
  6. shipment[2] 배송됨

이 주문은 차량의 총 loadDemands가 차량의 loadLimits를 초과하므로 3건의 배송을 동시에 완료할 수 없음을 반영합니다.

visits 항목에는 Visit 완료로 인한 차량 부하의 변경사항이 포함됩니다. 양의 부하 값은 배송 로드를 나타내고, 음수 값은 배송 중량을 나타냅니다.

transitions 항목에는 Transition 중의 총 차량 수하물이 포함됩니다. 예를 들어 transitions[2]weightKg 로드는 60이며 이는 shipment[0]shipment[1]의 결합된 로드를 나타냅니다.

측정항목 객체 routes[0].metricsmetrics.aggregatedRouteMetrics에는 maxLoads 속성이 포함됩니다. 유형 weightKg의 값은 80이며 shipments[2]를 배송 위치로 이동한 차량 경로의 일부를 나타냅니다.

소프트 로드 한도 제약조건

수령 및 배송 시간 창 제약조건에 설명된 기간과 마찬가지로 부하 제한 제약조건에는 하드 및 소프트 변형이 있습니다. LoadLimit 메시지의 maxLoad 속성은 엄격한 제약 조건을 표현합니다. 즉, 차량은 지정된 유형에서 maxLoad 값을 초과하는 부하를 운반해서는 안 됩니다. 속성 softMaxLoadcostPerUnitAboveSoftMax는 유연한 제약조건을 표현하며, softMaxLoad를 초과하는 모든 단위에서는 costPerUnitAboveSoftMax 비용이 발생합니다.

소프트 로드 제한 제약조건은 다음과 같이 여러 용도로 사용할 수 있습니다.

  • 필요한 최소 수량보다 많은 차량 간에 배송비를 균형 있게 조정하는 것이 비용 효율적인 경우
  • 특정 경로에서 편안하게 픽업 및 배송할 수 있는 물품의 수에 대한 기사 선호도를 표현
  • 마모를 제한하고 유지보수 비용을 절감하기 위해 최대 물리적 용량 이하로 차량을 로드

하드 및 소프트 부하 제한 제약 조건을 함께 사용할 수 있습니다. 예를 들어 하드 적재 제한은 차량이 안전하게 운반할 수 있는 화물의 최대 중량 또는 한 번에 차량에 담을 수 있는 최대 화물 수를 나타낼 수 있는 반면, 소프트 적재 제한은 운전자가 차량에 담을 수 있는 물건을 수용하는 데 부과되는 최대 중량 또는 물건 수일 수 있습니다.