In diesem Szenario wird die Reihenfolge der Haltestellen optimiert, die einem Fahrzeug mit einfachen Kostenparametern zugewiesen werden. Dies ist der einfachste Modus der Routenoptimierung. Er sorgt dafür, dass alle Haltestellen innerhalb des angegebenen Zeitraums angefahren werden.
Das folgende Beispiel veranschaulicht ein grundlegendes Szenario mit einem Fahrzeug und drei Sendungen, die alle von einem einzigen Standort, dem sogenannten Depot, stammen.
Beispielanfrage ansehen
{ "populatePolylines": true, "populateTransitionPolylines": true, "model": { "globalStartTime": "2023-01-13T16:00:00-08:00", "globalEndTime": "2023-01-14T16:00:00-08:00", "shipments": [ { "deliveries": [ { "arrivalLocation": { "latitude": 37.789456, "longitude": -122.390192 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.789116, "longitude": -122.395080 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] }, { "deliveries": [ { "arrivalLocation": { "latitude": 37.795242, "longitude": -122.399347 }, "duration": "250s" } ], "pickups": [ { "arrivalLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "duration": "150s" } ] } ], "vehicles": [ { "endLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "startLocation": { "latitude": 37.794465, "longitude": -122.394839 }, "costPerKilometer": 10.0, "costPerHour": 40.0 } ] } }
Anfragefelder für Routenoptimierung
Wie in der Übersicht erwähnt, sind die wichtigsten Attribute der Anfrage zur Routenoptimierung vehicles
und shipments
.
Neben einem Fahrzeug und Sendungen enthält die Anfrage die folgenden Felder:
Polylinien
Mit populatePolylines
und populateTransitionPolylines
wird angegeben, ob bei der Routenoptimierung Polylinien zurückgegeben werden sollen.
Der Dienst codiert Polylinien mithilfe des Maps JS-Polylinien-Codecs, der binäre Polyliniendaten mit druckbaren ASCII-Zeichen darstellt. Mit dem interaktiven Dienstprogramm für die Codierung von Polylinien können Sie die von der Routenoptimierung berechneten Pfade visualisieren. Im Beispiel in diesem Leitfaden werden populatePolylines
und populateTransitionPolylines
auf „true“ gesetzt, aber andere Führungslinien setzen sie auf „false“, um die Antwortgröße zu reduzieren.
Eine Beschreibung des Codierungsformats finden Sie unter Algorithmus für das Format codierter Polylinien.
Globale Zeitbeschränkungen
model.globalStartTime
und model.globalEndTime
sind auf einen beliebigen 24-Stunden-Zeitraum festgelegt. Dadurch sind Ausgabezeitstempel leichter zu interpretieren.
Orte besuchen
In der Beispielanfrage werden nur model.shipments[].pickups[].arrivalLocation
und model.shipments[].deliveries[].arrivalLocation
verwendet. Es gibt auch die Property departureLocation
für Situationen, in denen das Fahrzeug an einem anderen Punkt abfährt als an der Ankunftspunkt, z. B. bei einem Parkplatz mit einem Eingang auf einer Seite des Gebäudes und einem Ausgang auf einer anderen Seite. Bei dieser und den nachfolgenden Reiseführern wird davon ausgegangen, dass die Ankunfts- und Startpunkte identisch sind.
Die Ankunfts- und Abfahrtszeiten „waypoint
“ sind auch als Alternative zu latLng
verfügbar.
Waypoint
-Felder unterstützen die Verwendung von Google Place-IDs als Alternative zu LatLng
und können auch Fahrzeugrichtungen angeben. Weitere Informationen finden Sie in der Referenzdokumentation (REST, gRPC).
Einschränkungen im Beispiel
In diesem Szenario wird das Optimierungstool auf mehrere Arten eingeschränkt:
- Alle Aktivitäten müssen zwischen der globalen Start- und Endzeit abgeschlossen sein. In diesem Szenario sind die Start- und Endzeiten angesichts der Nähe der Lieferungen und des weiten globalen Zeitfensters eine sehr laxe Einschränkung.
- Alle Sendungen müssen abgeschlossen sein. Dies ist das Standardverhalten, wenn in
shipments
keine Strafkosten angegeben sind. costPerKilometer
undcostPerHour
sind am Fahrzeug eingestellt.
Kosten werden unter Kostenmodellparameter behandelt.
Antwortattribute für die Routenoptimierung
Antwort auf die Beispielanfrage ansehen
{ "routes": [ { "vehicleStartTime": "2023-01-14T00:00:00Z", "vehicleEndTime": "2023-01-14T00:36:41Z", "visits": [ { "shipmentIndex": 2, "isPickup": true, "startTime": "2023-01-14T00:00:00Z", "detour": "0s" }, { "shipmentIndex": 1, "isPickup": true, "startTime": "2023-01-14T00:02:30Z", "detour": "150s" }, { "isPickup": true, "startTime": "2023-01-14T00:05:00Z", "detour": "300s" }, { "startTime": "2023-01-14T00:11:25Z", "detour": "0s" }, { "shipmentIndex": 1, "startTime": "2023-01-14T00:19:29Z", "detour": "503s" }, { "shipmentIndex": 2, "startTime": "2023-01-14T00:29:02Z", "detour": "1324s" } ], "transitions": [ { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:00:00Z", "routePolyline": {} }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:02:30Z", "routePolyline": {} }, { "travelDuration": "0s", "waitDuration": "0s", "totalDuration": "0s", "startTime": "2023-01-14T00:05:00Z", "routePolyline": {} }, { "travelDuration": "235s", "travelDistanceMeters": 795, "waitDuration": "0s", "totalDuration": "235s", "startTime": "2023-01-14T00:07:30Z", "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@" } }, { "travelDuration": "234s", "travelDistanceMeters": 793, "waitDuration": "0s", "totalDuration": "234s", "startTime": "2023-01-14T00:15:35Z", "routePolyline": { "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@" } }, { "travelDuration": "323s", "travelDistanceMeters": 1204, "waitDuration": "0s", "totalDuration": "323s", "startTime": "2023-01-14T00:23:39Z", "routePolyline": { "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@" } }, { "travelDuration": "209s", "travelDistanceMeters": 665, "waitDuration": "0s", "totalDuration": "209s", "startTime": "2023-01-14T00:33:12Z", "routePolyline": { "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" } } ], "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@RWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@STY@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" }, "metrics": { "performedShipmentCount": 3, "travelDuration": "1001s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2201s", "travelDistanceMeters": 3457 }, "travelSteps": [ { "duration": "0s", "routePolyline": {} }, { "duration": "0s", "routePolyline": {} }, { "duration": "0s", "routePolyline": {} }, { "duration": "227s", "distanceMeters": 794, "routePolyline": { "points": "kvteFtfjVAA?C?C@C?A?C@AFMj@s@JKb@k@Zc@LSjA}ARWDGdAxAdAvAXa@@k@AsA\\c@FKp@_A\\c@Ze@fA{ALSFGd@o@rAgBB{BZc@" } }, { "duration": "233s", "distanceMeters": 791, "routePolyline": { "points": "cwseFti_jVRWj@w@x@eAHLNRHJbApAHLX\\V^?@hA~AT\\PVFFDHDFJNp@~@NRLNNTFFUZIJY^Y^g@p@[`@KP{@fAEFSXe@l@c@h@WZY\\?BELk@v@MNa@l@" } }, { "duration": "322s", "distanceMeters": 1205, "routePolyline": { "points": "cuseFhjVSTY`@Yb@GHEDIJEF]f@IJi@r@oAbBeCfDKLaApAKNQVIPKPCDQJIBIBM@iAJeALqBVC@C?A?QBYDI@C?_@Dc@FO@a@FDp@HfAHvABVDl@Dj@PpCQDiALsALAQASKwAOgBEe@COCYEa@Es@Eg@" } }, { "duration": "208s", "distanceMeters": 666, "routePolyline": { "points": "{zteFxbajV?CAYEc@AMC_@AOAK?E?CCWAOAKCe@CY?WScDEm@d@EFA\\ENCB?XEVC^E`@EhBUVCNEB?@?\\Er@IMUe@k@k@w@AAMQa@i@SWQWMQi@u@AC?A" } } ], "vehicleDetour": "2201s", "routeCosts": { "model.vehicles.cost_per_hour": 24.455555555555556, "model.vehicles.cost_per_kilometer": 34.57 }, "routeTotalCost": 59.025555555555556 } ], "totalCost": 59.025555555555556, "metrics": { "aggregatedRouteMetrics": { "performedShipmentCount": 3, "travelDuration": "1001s", "waitDuration": "0s", "delayDuration": "0s", "breakDuration": "0s", "visitDuration": "1200s", "totalDuration": "2201s", "travelDistanceMeters": 3457 }, "usedVehicleCount": 1, "earliestVehicleStartTime": "2023-01-14T00:00:00Z", "latestVehicleEndTime": "2023-01-14T00:36:41Z", "totalCost": 59.025555555555556, "costs": { "model.vehicles.cost_per_kilometer": 34.57, "model.vehicles.cost_per_hour": 24.455555555555556 } } }
Die Antwort der Routenoptimierung enthält ein übergeordnetes Feld routes
, das die vorgeschlagenen Routen mit einer Route pro Fahrzeug darstellt. Da in der Beispielanfrage in diesem Leitfaden nur ein Fahrzeug angegeben ist, enthält routes
eine ShipmentRoute
-Nachricht.
ShipmentRoute
Unterkünfte
Die beiden wichtigsten Attribute für den Nachrichtentyp ShipmentRoute
sind visits
und transitions
.
Jedes Visit
steht für den Abschluss einer Abholung oder Zustellung aus einer der VisitRequest
s der Anfragenachricht. Einem Besuch wird effektiv Arbeit zugewiesen, die an einem bestimmten Ort und zu einer bestimmten Zeit von einem Fahrzeug erledigt werden muss.
Jedes Transition
steht für das Fahrzeug, das von einem Standort zum nächsten fährt. Übergänge können zwischen zwei Startpunkten, einem Besuchsort und dem Endpunkt des Fahrzeugs erfolgen.
Um die vollständige Route des Fahrzeugs zu rekonstruieren, müssen die visits
und die transitions
der ShipmentRoute
kombiniert werden. Die Kombination von Feldern in einem Verlauf der Fahrzeugaktivität sieht so aus:
request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation
Ein ShipmentRoute
hat immer einen transitions
mehr als visits
, da das Fahrzeug von seinem Startort bis zu seinem ersten Besuch am Anfang der Route und von seinem letzten Besuch bis zum Ziel am Ende der Route fahren muss. Wenn das Fahrzeug keinen Start- oder Zielpunkt hat, ist immer noch eine transitions
als visits
vorhanden, da der Standort des ersten oder letzten Besuchs als Start- bzw. Zielpunkt des Fahrzeugs verwendet wird.
In diesem Beispiel haben die ersten drei Abholbesuche Übergänge ohne Entfernung und Dauer, da alle drei Abholorte denselben Ort in der Anfrage haben.
Weitere Informationen finden Sie in der Referenzdokumentation zu ShipmentRoute
(REST, gRPC).
Einfache Optimierung der Wegpunktreihenfolge
Wie in diesem Beispiel gezeigt, modelliert die Routenoptimierung Besuche als Attribute von Lieferungen. Wegpunkte oder Haltestellen werden nicht als unabhängige Entität definiert. Es ist jedoch möglich, Haltestellen oder Wegpunkte als Sendungen mit genau einer VisitRequest
als Abhol- oder Lieferadresse darzustellen. Dem Fahrzeug muss immer noch eine costPerHour
oder costPerKilometer
zugewiesen werden, damit das Optimierungstool eine optimale Route findet (anstatt eine praktikable Route zu finden).