OptimizeToursRequest
wendet Einschränkungen auf Folgendes an:
- Sendungen, die sich auf die Ausführung von Sendungen auswirken
- Fahrzeuge, die sich auf die Berechnung von Fahrzeugrouten auswirken
- Weltweit, was sowohl Fahrzeuge als auch Sendungen betrifft.
Dieser Leitfaden konzentriert sich auf eine wesentliche Einschränkung beim Versand: Zeitfenster.
Zeitfenster sind eine Art von Beschränkung, die Sie in den
OptimizeToursRequest
-Nachricht (REST, gRPC) zum Angeben
zeitgebundene Beschränkungen für Versandaktivitäten. Diese Art der Einschränkung wirkt sich
wann und wie ein Versand durchgeführt werden kann
für die Lieferung. Bei diesen Einschränkungen gibt das Optimierungstool
die den zeitlichen Rahmen der Sendung
am besten erfüllen können.
Versandeinschränkungen: Zeitfenster
Du legst in der Shipment.VisitRequest
fest, wann eine Abholung oder Lieferung stattfinden kann
wie folgt angezeigt:
- Das Attribut
timeWindows
in der Nachricht verwenden (REST, gRPC) - Geben Sie die Start- und Endzeit in der
TimeWindow
-Nachricht an (REST, gRPC) ausführen.
Beispielanfrage mit Zeitfenstereinschränkungen
Das Beispiel zeigt drei verschiedene Lieferungen mit jeweils einer eigenen
Lieferfenster. Der Einfachheit halber werden in diesem Beispiel Zeitfenster für deliveries
festgelegt
aber Zeitfenster können auch auf Abholungen angewendet werden. Mehrere Zeitfenster
angegeben werden, auch wenn in diesem Beispiel nur ein Wert pro VisitRequest
-Übermittlung verwendet wird.
Beispielanfrage mit Zeitfenstern 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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T19:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T18:30:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "endTime": "2023-01-13T18:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
Beispielantwort mit Zeitfenstereinschränkungen
In der Beispielantwort sind Start- und Endzeit des Fahrzeugs 17:35:50 und
18:17:24. Diese Zeiten spiegeln die Zeitersparnis wider,
erforderlich, um das in der Anfrage als costPerHour
angegebene Fahrzeug zu betreiben, während
alle Zeitfensterbeschränkungen erfüllt. 17:35:50 als Startzeit verwenden
macht es dem Fahrzeug nicht mehr notwendig, an einem Besuchsort zu warten, bis der
beginnt das Zeitfenster des Besuchs. In der Antwort erscheint dies als null waitDuration
.
Werte.
Eine Antwort auf die Beispielanfrage sehen Sie mit Zeitfenster
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:35:50Z", "vehicleEndTime": "2023-01-13T18:17:24Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:35:50Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T17:38:20Z", "detour": "150s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:40:50Z", "detour": "300s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T17:50:09Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-13T18:00:00Z", "detour": "796s" }, { "startTime": "2023-01-13T18:07:35Z", "detour": "1520s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:35:50Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:38:20Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:40:50Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T17:43:20Z" }, { "travelDuration": "341s", "travelDistanceMeters": 1312, "waitDuration": "0s", "totalDuration": "341s", "startTime": "2023-01-13T17:54:19Z" }, { "travelDuration": "205s", "travelDistanceMeters": 636, "waitDuration": "0s", "totalDuration": "205s", "startTime": "2023-01-13T18:04:10Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-13T18:11:45Z" } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "1294s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2494s", "travelDistanceMeters": 4595 }, "routeCosts": { "model.vehicles.cost_per_hour": 27.711111111111112, "model.vehicles.cost_per_kilometer": 45.95 }, "routeTotalCost": 73.661111111111111 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1294s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2494s", "travelDistanceMeters": 4595 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:35:50Z", "latestVehicleEndTime": "2023-01-13T18:17:24Z", "totalCost": 73.661111111111111, "costs": { "model.vehicles.cost_per_hour": 27.711111111111112, "model.vehicles.cost_per_kilometer": 45.95 } } }
Die visits
des Fahrzeugs wurde in den Zeitfenstern bestellt, sodass die Lieferungen mit der
früheste Zeitfenster werden
zuerst geliefert.
shipments[2]
wird um 17:50 Uhr geliefertshipments[1]
wird um 18:00 Uhr geliefertshipments[0]
wird um 18:07 Uhr geliefert
Die Beispielanfrage gibt harte Zeitfenstereinschränkungen an, die Folgendes erfordern:
Lieferungen innerhalb dieser Zeitfenster
abgeschlossen werden können. Wenn Sie die
VisitRequests
innerhalb eines seiner Zeitfensters ist nicht realisierbar oder
kosteneffizient, überspringt das Optimierer die Lieferung. Enthält die Sendung
penaltyCost
, wird sie vom Optimierungstool zu den als Antwort gemeldeten Kosten hinzugefügt.
metrics
. Andernfalls wird das Attribut skippedMandatoryShipmentCount
des
OptimizeToursResponse
-Nachrichten (REST, gRPC) erhöhen sich.
Wenn Sie die Zeitfenster ändern, indem Sie das Fenster von shipment[1]
um mehrere Stunden verschieben
(bis 21:00 Uhr von 18:00 Uhr) angezeigt werden, unterscheiden sich die Ergebnisse, wie in den
folgenden Beispielen.
Beispielanfrage mit Zeitfenstern, die nicht zufrieden sein
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "endTime": "2023-01-13T19:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T21:00:00Z", "endTime": "2023-01-13T21:30:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "endTime": "2023-01-13T18:00:00Z" } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
Hier sehen Sie eine Antwort auf die zweite Beispielanfrage mit Zeitfenster, in denen eine Sendung übersprungen wird
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:37:49Z", "vehicleEndTime": "2023-01-13T18:09:49Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:37:49Z", "detour": "0s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:40:19Z", "detour": "150s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T17:49:38Z", "detour": "0s" }, { "startTime": "2023-01-13T18:00:00Z", "detour": "946s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:37:49Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:40:19Z" }, { "travelDuration": "409s", "travelDistanceMeters": 1371, "waitDuration": "0s", "totalDuration": "409s", "startTime": "2023-01-13T17:42:49Z" }, { "travelDuration": "372s", "travelDistanceMeters": 1348, "waitDuration": "0s", "totalDuration": "372s", "startTime": "2023-01-13T17:53:48Z" }, { "travelDuration": "339s", "travelDistanceMeters": 1276, "waitDuration": "0s", "totalDuration": "339s", "startTime": "2023-01-13T18:04:10Z" } ], "metrics": { "performedShipmentCount": 2, "travelDuration": "1120s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1920s", "travelDistanceMeters": 3995 }, "routeCosts": { "model.vehicles.cost_per_kilometer": 39.95, "model.vehicles.cost_per_hour": 21.333333333333332 }, "routeTotalCost": 61.283333333333331 } ], "skippedShipments": [ { "index": 1 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 2, "travelDuration": "1120s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "800s", "totalDuration": "1920s", "travelDistanceMeters": 3995 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:37:49Z", "latestVehicleEndTime": "2023-01-13T18:09:49Z", "totalCost": 81.283333333333331, "costs": { "model.shipments.penalty_cost": 20, "model.vehicles.cost_per_hour": 21.333333333333332, "model.vehicles.cost_per_kilometer": 39.95 } } }
In diesem Beispiel wurde shipment[1]
aufgrund des späteren Zeitfensters übersprungen.
da die zusätzliche Betriebszeit des Fahrzeugs erforderlich ist,
Lieferung innerhalb des angegebenen Zeitfensters die Strafkosten für die Lieferung überschritten hat.
Die Strafkosten für shipment[1]
werden in metrics.costs
und im Index angezeigt
erscheint in skippedShipments
.
Weiche Zeitfensterbeschränkungen
Wie unter Kostenmodellparameter bereits erwähnt, können Zeitfenster als weiche Einschränkungen. Weiche Einschränkungen unterscheiden sich folgendermaßen von harten Einschränkungen:
- Harte Einschränkungen: Es darf nicht verletzt werden und das Optimierungstool bietet kein die gegen die Einschränkung verstößt, auch wenn dies bedeutet, Lieferung.
- Weiche Einschränkungen: Können verletzt werden, was bedeutet, dass das Optimierungstool möglicherweise nicht verwendet wird. eine Lösung bereitstellen, die gegen eine weiche Einschränkung verstößt. Das Optimierungstool Außerdem werden für jeden Verstoß Kosten berechnet. Sie stellen diese Kosten als im Zeitfenster, in der Regel als Kosten pro Stunde für und zwar jede Stunde vor oder nach dem Zeitfenster, in dem die Aktivität stattfindet.
Zeitfenster werden durch die Verwendung von softStartTime
oder softEndTime
anstelle von
startTime
bzw. endTime
und durch Festlegen
costPerHourBeforeSoftStartTime
oder costPerHourAfterSoftEndTime
.
Weiche Zeitfensterbeschränkungen verwenden, wenn Abholungen oder Lieferungen soll Zeitfenster innerhalb eines bestimmten Zeitfensters. Eine Abholung oder Lieferung innerhalb dieses Zeitfensters unbedingt erforderlich. Sie können feste und weiche Zeitfensterbeschränkungen zusammen verwenden um Geschäftsziele festzulegen. Beispiel:
- Schwieriges Zeitfenster: Gibt die Öffnungszeiten eines Kunden an, z. B. vom 09:00 bis 17:00 Uhr.
- „Weiches Zeitfenster“: Gibt den Zeitraum für die Lieferung oder Abholung an, stimmt mit der an den Kunden gesendeten Benachrichtigung überein, z. B. von 09:00 bis 13:00 Uhr.
In diesem Beispiel wurde die Sendung übersprungen, Durch ein zu spät begonnenes Zeitfenster wird die Startzeitbeschränkung aufgehoben. Die andere Lieferungen hatten ihr Zeitfenster“ auch die Endzeiten abschwächen.
Beispielanfrage mit harter und weicher Zeit ansehen Fenster
{ "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", "timeWindows": [ { "startTime": "2023-01-13T18:00:00Z", "softEndTime": "2023-01-13T19:00:00Z", "costPerHourAfterSoftEndTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 100.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s", "timeWindows": [ { "softStartTime": "2023-01-13T21:00:00Z", "endTime": "2023-01-13T21:30:00Z", "costPerHourBeforeSoftStartTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 20.0 }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s", "timeWindows": [ { "startTime": "2023-01-13T17:30:00Z", "softEndTime": "2023-01-13T18:00:00Z", "costPerHourAfterSoftEndTime": 2.0 } ] } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ], "penaltyCost": 50.0 } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerHour": 40.0, "costPerKilometer": 10.0 } ] } }
Eine Antwort auf die Beispielanfrage weiche Zeitfenster
{ "routes": [ { "vehicleStartTime": "2023-01-13T17:48:35Z", "vehicleEndTime": "2023-01-13T18:24:28Z", "visits": [ { "isPickup": true, "startTime": "2023-01-13T17:48:35Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-13T17:51:05Z", "detour": "150s" }, { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-13T17:53:35Z", "detour": "300s" }, { "startTime": "2023-01-13T18:00:00Z", "detour": "300s" }, { "shipmentIndex": 1, "startTime": "2023-01-13T18:07:42Z", "detour": "493s" }, { "shipmentIndex": 2, "startTime": "2023-01-13T18:17:27Z", "detour": "873s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:48:35Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:51:05Z" }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-13T17:53:35Z" }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-13T17:56:05Z" }, { "travelDuration": "212s", "travelDistanceMeters": 791, "waitDuration": "0s", "totalDuration": "212s", "startTime": "2023-01-13T18:04:10Z" }, { "travelDuration": "335s", "travelDistanceMeters": 1204, "waitDuration": "0s", "totalDuration": "335s", "startTime": "2023-01-13T18:11:52Z" }, { "travelDuration": "171s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "171s", "startTime": "2023-01-13T18:21:37Z" } ], "metrics": { "performedShipmentCount": 3, "travelDuration": "953s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2153s", "travelDistanceMeters": 3455 }, "routeCosts": { "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667, "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332, "model.vehicles.cost_per_hour": 23.922222222222221, "model.vehicles.cost_per_kilometer": 34.55 }, "routeTotalCost": 64.797222222222217 } ], "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "953s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2153s", "travelDistanceMeters": 3455 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-13T17:48:35Z", "latestVehicleEndTime": "2023-01-13T18:24:28Z", "totalCost": 64.797222222222217, "costs": { "model.vehicles.cost_per_kilometer": 34.55, "model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time": 5.7433333333333332, "model.shipments.deliveries.time_windows.cost_per_hour_after_soft_end_time": 0.58166666666666667, "model.vehicles.cost_per_hour": 23.922222222222221 } } }
Das Beispiel mit nur festgelegten Zeitfenstern wurde
shipment[1]
– durch eine entsprechend angepasste Lieferdauer wird die Anzeige ausgeliefert
vor dem Beginn des Zeitfensters. Die Abweichung der Endzeiten des
andere Sendungen konnten shipment[2]
nach diesem Zeitfenster liefern
endet.
Gleichzeitig haben sich sowohl die Kosten als auch die Gesamtlieferungen geändert:
totalCost
: verringert von 81.283 auf 64.797- Gesamtzahl der abgeschlossenen Sendungen: erhöht von 2 auf 3
Das Optimierungstool hat eine kostengünstigere Lösung gefunden, da das Zeitfenster wurden die Einschränkungen im Vergleich zum vorherigen Beispiel gelockert.
Schließlich enthält das Attribut metrics.costs
auch einen neuen Schlüssel zur Angabe der
die tatsächlich angefallenen Kosten basierend auf dem Produkt der Beschränkung und der Länge der
wann das Lieferfenster verpasst wurde. Das bedeutet:
costPerHourBeforeSoftStartTime
von 2,0 und- die Zeit zwischen der tatsächlichen Lieferung und dem Beginn des Zeitfensters: 2,83583 Stunden
Ergebnis:
model.shipments.deliveries.time_windows.cost_per_hour_before_soft_start_time
:
5,6716666666666669.
Anhand dieser Kennzahlen können Sie eine Kostenanalyse durchführen, um den Kompromiss zwischen schwierigen
und weiche Einschränkungen, mit denen Sie Ihre Einschränkungen auf
Geschäftsregeln besser zu verstehen. In diesem Fall betragen die Gesamtkosten
weniger als shipment[1].penalty_cost
von 20,0. Das Optimierungstool hat
dass es kostengünstiger ist, die Lieferung frühzeitig zu liefern, als dies tatsächlich der Fall ist.
die Lieferung überspringen.