負載需求和限制

歐洲經濟區 (EEA) 開發人員

本指南說明 loadDemandsloadLimits,以及兩者之間的關係。

如「取貨和送貨時間範圍限制」一文所述,OptimizeToursRequest 訊息 (RESTgRPC) 包含多項屬性,可指定要最佳化問題的限制。多個 OptimizeToursRequest 屬性代表負載限制

規劃路線時,必須考量車輛和貨物的實體特性。

  • 車輛loadLimits 屬性會指定車輛可處理的最大負載。請參閱Vehicle訊息的 (RESTgRPC) 說明文件。
  • 出貨loadDemands 屬性會指定特定出貨量消耗的負載量。請參閱Shipment訊息的 (RESTgRPC) 說明文件。

這兩項限制條件可讓最佳化工具適當將貨件指派給車輛,以最符合車隊容量和貨件需求的方式進行。

本文件其餘部分會詳細討論 loadLimitsloadDemands

負載需求和限制:類型

您會以型別表示每個負載需求和限制條件。

您可以提供自己的載入類型組合,例如:

  • 重量
  • 磁碟區
  • 線性測量
  • 運送的物品或設備名稱

本指南以 weightKg 做為範例類型。

Shipment.loadDemandsVehicle.loadLimits 都使用 通訊協定緩衝區 map 類型,並以 string 鍵代表負載類型。

Shipment.loadDemands 值會使用 Load 訊息 (RESTgRPC)。Load 訊息具有單一 amount 屬性,代表完成指定類型出貨作業所需的容量。

值會使用 LoadLimit 訊息 (RESTgRPC)。Vehicle.loadLimitsLoadLimit 訊息有多個屬性,其中 maxLoad 代表指定類型車輛的最大載重能力。

只有在貨件和車輛的負載類型鍵相符時,貨件才會耗用指派車輛的loadLimitsloadDemandsloadLimits。舉例來說,如果出貨內容為:loadDemands

"loadDemands": {
  "weightKg": {
    "amount": 50
  }
}

需要 50 個裝載單位 (weightKg 類型) 才能完成運送。車輛:loadLimits

"loadLimits": {
  "weightKg": {
    "maxLoad": 100
  }
}

可能可以完成運送,因為車輛的 maxLoad weightKg 類型大於或等於運送的 loadDemands weightKg 類型。不過,如果車輛符合下列條件:loadLimits

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

由於沒有負載限制,因此隱含無限 weightKg容量,因此車輛不受貨物重量需求的限制。weightKg

在貨運和車輛之間轉移貨物

由於貨件是由車輛收取和運送,貨件的loadDemand會在貨件和車輛之間轉移。您可以在特定車輛的 OptimizeToursResponse 訊息 (RESTgRPC) 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] 的負載需求為 50 weightKg
  • shipments[1] 的負載需求為 10 weightKg
  • shipments[2] 的負載需求為 80 weightKg
  • vehicles[0] 的載入上限為 100 個 weightKg

查看要求的回應,瞭解負載需求和限制

{
  "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] 的負載為 60,代表 shipment[0]shipment[1] 的合併負載。weightKg

指標物件 routes[0].metricsmetrics.aggregatedRouteMetrics 包含 maxLoads 屬性。類型 weightKg 的值為 80,代表車輛將 shipments[2] 運送至交貨地點的路線部分。

軟性負載限制條件

如「取貨和送貨時間範圍限制」所述,載重限制條件也有硬性限制和軟性限制。LoadLimit 訊息的 maxLoad 屬性表示硬性限制:車輛的負載絕不可超過指定類型中的 maxLoad 值。屬性 softMaxLoadcostPerUnitAboveSoftMax 代表軟性限制,每超出 softMaxLoad 的單位都會產生 costPerUnitAboveSoftMax 費用。

軟性負載限制條件有多種用途,例如:

  • 在成本效益允許的情況下,將貨物分配到超過必要最低數量的車輛
  • 表達司機偏好在特定路線上輕鬆取貨和送貨的項目數量
  • 裝載車輛時,不要超過實體容量上限,以減少磨損並降低維護成本

硬性與軟性負載限制條件可以搭配使用。舉例來說,硬性載重限制可能表示車輛可安全運送的貨物最大重量,或車輛一次可容納的最大物品數量;軟性載重限制則可能表示會超出駕駛人能力範圍的物品最大重量或數量,導致無法將所有物品裝入車輛。