Ladeanforderungen und -limits

In diesem Leitfaden werden loadDemands und loadLimits und ihre Beziehung zueinander beschrieben.

Wie unter Einschränkungen für Abhol- und Lieferzeitfenster erwähnt, enthält die OptimizeToursRequest-Nachricht (REST, gRPC) eine Reihe von Eigenschaften, die Einschränkungen für das zu optimierende Problem angeben. Mehrere OptimizeToursRequest-Attribute stellen Lasteinschränkungen dar.

Fahrzeuge und Sendungen haben physische Eigenschaften, die bei der Planung einer Route berücksichtigt werden müssen.

  • Fahrzeuge: Die Eigenschaft loadLimits gibt die maximale Last an, die das Fahrzeug bewältigen kann. Weitere Informationen finden Sie in der Dokumentation der Vehicle-Nachricht (REST, gRPC).
  • Shipments (Lieferungen): Die Eigenschaft loadDemands gibt an, wie viel Ladung eine bestimmte Sendung verbraucht. Weitere Informationen finden Sie in der Dokumentation der Shipment-Nachricht (REST, gRPC).

Zusammen ermöglichen diese beiden Einschränkungen dem Optimierer, Lieferungen den Fahrzeugen in einer Weise zuzuordnen, die Ihren Flottenkapazitäts- und Versandanforderungen am besten entspricht.

Im weiteren Verlauf dieses Dokuments werden loadLimits und loadDemands ausführlich behandelt.

Lastanforderungen und -limits: Typen

Sie geben jede Lastnachfrage und Limitbeschränkung in Form eines Typs aus.

Sie können Ihre eigenen Ladetypen angeben, wie in den folgenden Beispielen gezeigt:

  • Gewicht
  • Volume
  • lineare Messungen
  • Namen der transportierten Gegenstände oder Geräte

In dieser Anleitung wird weightKg als Beispieltyp verwendet.

Sowohl Shipment.loadDemands als auch Vehicle.loadLimits verwenden den Protokollzwischenspeicher-Typ map mit string-Schlüsseln, die die Ladetypen darstellen.

Shipment.loadDemands-Werte verwenden die Load-Nachricht (REST, gRPC). Die Load-Nachricht hat eine einzelne amount-Eigenschaft, die angibt, wie viel Kapazität für die Sendung im angegebenen Typ erforderlich ist.

Vehicle.loadLimits-Werte verwenden die LoadLimit-Nachricht (REST, gRPC). Die LoadLimit-Nachricht hat mehrere Eigenschaften, wobei maxLoad die maximale Ladekapazität des Fahrzeugs im angegebenen Typ darstellt.

Die loadDemands einer Sendung verbraucht nur dann die loadLimits des zugewiesenen Fahrzeugs, wenn die beiden übereinstimmende Ladetypschlüssel haben. Beispiel für eine Sendung mit loadDemands von:

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

erfordert 50 Ladeeinheiten vom Typ weightKg, damit der Versand abgeschlossen werden kann. Ein Fahrzeug mit loadLimits von:

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

möglicherweise die Lieferung abschließen können, da der maxLoad-Wert des Fahrzeugs im Typ weightKg größer oder gleich dem loadDemands der Sendung im Typ weightKg ist. Ein Fahrzeug mit loadLimits von:

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

hat implizit unbegrenzte weightKg-Kapazität, da kein weightKg-Ladelimit vorhanden ist, sodass das Fahrzeug nicht durch das Gewicht der Sendung eingeschränkt wird.

Ladungstransfer zwischen Lieferungen und Fahrzeugen

Wenn Sendungen von Fahrzeugen abgeholt und zugestellt werden, wird die loadDemand der Sendung zwischen der Sendung und dem Fahrzeug übertragen. Die Ladevorgänge des Fahrzeugs können Sie im Eintrag REST, gRPC)routes.transitions für ein bestimmtes Fahrzeug in der OptimizeToursResponse-Nachricht sehen. Die Reihenfolge sieht so aus:

  1. Die erforderliche Ladekapazität wird für die Sendung als loadDemand definiert.
  2. Die Sendung wird von dem zugewiesenen Fahrzeug abgeholt und der vehicleLoads des Fahrzeugs erhöht sich um den loadDemand der Sendung. Diese Übertragung wird in der Antwortnachricht durch einen positiven visits.loadDemands dargestellt.
  3. Das Fahrzeug liefert die Sendung aus und der vehicleLoads-Wert des Fahrzeugs verringert sich um den loadDemand der zugestellten Sendung. Diese Übertragung wird durch negative visits.loadDemands in der Antwortnachricht dargestellt.

Die vehicleLoads eines Fahrzeugs darf den angegebenen Wert für loadLimits zu keinem Zeitpunkt auf seiner Route überschreiten.

Ein vollständiges Beispiel mit Lastanforderungen und -limits

Beispielanfrage mit Lastanforderungen und ‐limits ansehen

{
  "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
          }
        }
      }
    ]
  }
}
    

Die Beispielanfrage enthält mehrere auf Auslastung bezogene Parameter:

  • shipments[0]“ hat eine Lastanforderung von 50 weightKg.
  • shipments[1]“ hat einen Ladebedarf von 10 weightKg.
  • shipments[2]“ hat einen Ladebedarf von 80 weightKg.
  • vehicles[0] hat ein Ladelimit von 100 weightKg.

Antwort mit Lastanforderungen und -limits auf die Anfrage ansehen

{
  "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
    }
  }
}
    

Die hinzugefügten Lasteinschränkungen wirken sich auf die Reihenfolge von visits aus:

  1. shipment[0] wurde abgeholt
  2. shipment[1] wurde abgeholt
  3. shipment[0] wurde zugestellt
  4. shipment[1] wurde zugestellt
  5. shipment[2] wurde abgeholt
  6. shipment[2] wurde zugestellt

Diese Bestellung geht davon aus, dass drei Sendungen vom Fahrzeug nicht gleichzeitig abgeschlossen werden können, weil ihre Gesamt-loadDemands den loadLimits des Fahrzeugs überschreiten.

Jeder visits-Eintrag enthält die Änderung der Fahrzeugauslastung, die sich aus dem Abschluss von Visit ergibt. Positive Lastwerte stehen für das Laden der Sendung, negative Werte für das Entladen der Sendung.

Jeder transitions-Eintrag enthält die Gesamtladung des Fahrzeugs während des Transition. transitions[2] hat beispielsweise eine weightKg-Last von 60, was die kombinierten Lasten von shipment[0] und shipment[1] darstellt.

Die Messwertobjekte routes[0].metrics und metrics.aggregatedRouteMetrics enthalten das Attribut maxLoads. Der Wert für den Typ weightKg beträgt 80 und stellt den Teil der Route des Fahrzeugs dar, über den shipments[2] zum Lieferort transportiert wurde.

Beschränkungen für das Limit beim weichen Laden

Wie bei den unter Einschränkungen für Abhol- und Lieferzeitfenstern beschriebenen Zeitfenstern gibt es bei den Einschränkungen für Lastlimits harte und weiche Varianten. Das Attribut maxLoad der LoadLimit-Nachricht drückt eine harte Einschränkung aus: Das Fahrzeug darf keine Last tragen, die den Wert maxLoad im angegebenen Typ überschreitet. Für die Attribute softMaxLoad und costPerUnitAboveSoftMax gilt eine weiche Einschränkung, wobei für jede Einheit, die softMaxLoad überschreitet, Kosten für costPerUnitAboveSoftMax anfallen.

Einschränkungen für das Limit beim weichen Laden werden auf vielfältige Weise genutzt, z. B.:

  • Lieferungen über mehr Fahrzeuge verteilen als erforderlich, wenn dies kostengünstig ist.
  • Der Fahrer drückt aus, wie viele Artikel er auf einer Route ganz bequem abholen und liefern kann.
  • das Laden von Fahrzeugen unterhalb ihrer maximalen physischen Kapazität, um den Verschleiß zu reduzieren und die Wartungskosten zu senken

Beschränkungen für das harte und das weiche Laden können zusammen verwendet werden. Ein hartes Lastlimit kann z. B. das Höchstgewicht der Ladung, die ein Fahrzeug sicher tragen kann, oder die maximale Anzahl von Gegenständen ausdrücken, die gleichzeitig in ein Fahrzeug passen, während eine weiche Last das Höchstgewicht oder die Anzahl von Gegenständen sein könnte, die die Fähigkeit des Fahrers beeinträchtigen würden, alles im Fahrzeug unterzubringen.