부하 수요 및 한도

유럽 경제 지역 (EEA) 개발자

이 가이드에서는 loadDemandsloadLimits와 서로의 관계를 설명합니다.

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

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

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

이 두 가지 제약 조건을 함께 사용하면 최적화 프로그램이 차량의 수송 능력과 배송 요구에 가장 적합한 방식으로 배송을 차량에 적절하게 할당할 수 있습니다.

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

부하 요구사항 및 제한사항: 유형

각 부하 요구사항과 제한 제약 조건을 유형으로 표현합니다.

다음 예와 같이 자체 부하 유형 집합을 제공할 수 있습니다.

  • 무게
  • 볼륨
  • 선형 측정
  • 운송되는 상품 또는 장비의 이름

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

Shipment.loadDemandsVehicle.loadLimits 모두 프로토콜 버퍼 map 유형을 사용하며, string 키는 로드 유형을 나타냅니다.

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 유형의 차량 maxLoad이(가) weightKg 유형의 배송 loadDemands보다 크거나 같으므로 배송을 완료할 수 있습니다. 하지만 loadLimits이 다음과 같은 차량은

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

weightKg 부하 제한이 없으므로 암시적으로 무제한 weightKg 용량이 있어 차량이 배송의 무게 요구사항에 의해 제한되지 않습니다.

배송과 차량 간의 부하 이전

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

  1. 필요한 적재 용량은 배송에 대해 loadDemand로 정의됩니다.
  2. 할당된 차량이 배송 상품을 수령하고 차량의 vehicleLoads이(가) 배송 상품의 loadDemand만큼 증가합니다. 이 전송은 응답 메시지에서 positive 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]의 로드 수요는 10 weightKg입니다.
  • shipments[2]의 로드 수요는 80 weightKg입니다.
  • vehicles[0]의 로드 제한은 100weightKg입니다.

부하 요구사항 및 한도가 포함된 요청에 대한 응답을 확인합니다.

{
  "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을 초과하므로 차량에서 동시에 세 개의 배송을 완료할 수 없음을 반영합니다.

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 비용이 발생합니다.

소프트 로드 제한 제약 조건은 다음과 같은 여러 용도로 사용됩니다.

  • 비용 효율적인 경우 필요한 최소 수보다 많은 차량에 배송을 분산
  • 특정 경로에서 편안하게 픽업하고 배송할 수 있는 상품 수에 대한 운전기사 선호도 표현
  • 마모를 제한하고 유지관리 비용을 줄이기 위해 최대 물리적 용량 미만으로 차량을 적재

하드 및 소프트 부하 제한 제약 조건을 함께 사용할 수 있습니다. 예를 들어 하드 적재 한도는 차량이 안전하게 운반할 수 있는 최대 화물 중량이나 차량에 한 번에 들어갈 수 있는 최대 상품 수를 나타낼 수 있고, 소프트 적재 한도는 운전자가 차량에 모든 것을 넣을 수 있는 능력을 고려한 최대 중량이나 상품 수를 나타낼 수 있습니다.