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 derVehicle
-Nachricht (REST, gRPC). - Shipments (Lieferungen): Die Eigenschaft
loadDemands
gibt an, wie viel Ladung eine bestimmte Sendung verbraucht. Weitere Informationen finden Sie in der Dokumentation derShipment
-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:
- Die erforderliche Ladekapazität wird für die Sendung als
loadDemand
definiert. - Die Sendung wird von dem zugewiesenen Fahrzeug abgeholt und der
vehicleLoads
des Fahrzeugs erhöht sich um denloadDemand
der Sendung. Diese Übertragung wird in der Antwortnachricht durch einen positivenvisits.loadDemands
dargestellt. - Das Fahrzeug liefert die Sendung aus und der
vehicleLoads
-Wert des Fahrzeugs verringert sich um denloadDemand
der zugestellten Sendung. Diese Übertragung wird durch negativevisits.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 50weightKg
. - „
shipments[1]
“ hat einen Ladebedarf von 10weightKg
. - „
shipments[2]
“ hat einen Ladebedarf von 80weightKg
. vehicles[0]
hat ein Ladelimit von 100weightKg
.
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:
shipment[0]
wurde abgeholtshipment[1]
wurde abgeholtshipment[0]
wurde zugestelltshipment[1]
wurde zugestelltshipment[2]
wurde abgeholtshipment[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.