Ten scenariusz optymalizuje kolejność przystanków przypisanych do pojazdu w prosty sposób parametrów kosztów. Jest to najprostszy tryb działania optymalizacji trasy. gwarantuje, że wszystkie przystanki zostaną odwiedzone w wybranym terminie.
Poniższy przykład ilustruje podstawowy scenariusz z jednym pojazdem i 3 pojazdami to wszystkie dostawy z jednej lokalizacji zwanej depotem.
Zobacz przykładowe żądanie
{ "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 } ] } }
Pola żądania optymalizacji tras
Jak wspomnieliśmy w sekcji Omówienie, najważniejsza prośba o optymalizację trasy
właściwości to vehicles
i shipments
.
Oprócz pojazdu i przesyłek prośba obejmuje też te dane: pola:
Linie łamane
populatePolylines
i populateTransitionPolylines
określają, czy trasa
Optymalizacja powinna zwrócić linie łamane.
Usługa koduje linie łamane za pomocą kodeka linii łamanych Maps JS, który reprezentuje
binarne dane łamane przy użyciu możliwych do wydrukowania znaków ASCII. Aby wizualizować ścieżki obliczone przez narzędzie Route Optimization, możesz użyć interfejsu narzędzia do kodowania ścieżek wielokątów. Przykład w tym przewodniku ustawia populatePolylines
i
populateTransitionPolylines
ma wartość prawda, ale inne przewodniki ustawiają je jako fałsz na
zmniejszyć rozmiar odpowiedzi.
Opis kodowania znajdziesz w sekcji Format algorytmu łamanego zakodowanego. .
Globalne ograniczenia czasowe
Funkcje model.globalStartTime
i model.globalEndTime
mają wartość dowolnego typu 24
w przedziale godzinnym. Ułatwia to interpretację sygnatur czasowych wyjściowych.
Odwiedź lokalizacje
W przykładowym żądaniu użyto tylko model.shipments[].pickups[].arrivalLocation
i
model.shipments[].deliveries[].arrivalLocation
Dostępna jest też
Właściwość departureLocation
w sytuacjach, gdy pojazd wyjeżdża z
znajduje się w innym miejscu niż to, w którym się dociera, np. do kompleksu parkingowego z wejściem
po jednej stronie budynku, a po drugiej stronie. W tym i kolejnych
punkty przylotu i wyjazdu są takie same.
W zamian do latLng
możesz też użyć wartości waypoint
.
Pola Waypoint
obsługują używanie identyfikatorów miejsc Google jako alternatywy dla LatLng
. Można też określić kierunek jazdy pojazdu. Zobacz dokumentację
(REST, gRPC).
Ograniczenia w przykładzie
Ten scenariusz ogranicza optymalizatora na kilka sposobów:
- Cała aktywność musi być wykonana między globalnym czasem rozpoczęcia a zakończeniem. W tym scenariuszu czasy rozpoczęcia i zakończenia są bardzo luźno określone ze względu na niewielką odległość między dostawami i szerokie okno czasowe na całym świecie.
- Wszystkie przesyłki muszą zostać zrealizowane. Jest to domyślne działanie, gdy koszty kary nie są określone w
shipments
. costPerKilometer
icostPerHour
są ustawione w pojeździe.
Koszty są określone w parametrach modelu kosztu.
Właściwości odpowiedzi na potrzeby optymalizacji trasy
Wyświetlanie odpowiedzi na przykładowe żądanie
{ "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 } } }
Odpowiedź optymalizacji trasy zawiera pole najwyższego poziomu routes
, które przedstawia proponowane trasy, po jednej na pojazd. W przykładzie
żądanie w tym przewodniku określa tylko jeden pojazd, routes
obejmuje jeden
ShipmentRoute
wiadomość.
ShipmentRoute
miejsca zakwaterowania
Dwie najważniejsze właściwości typu wiadomości ShipmentRoute
to
visits
i transitions
.
Każdy znak Visit
oznacza potwierdzenie odbioru lub dostawy z jednego z
VisitRequest
wiadomości z żądaniem. Wizyta jest skutecznie przypisywana do użytkownika
zostać wykonane przez pojazd w określonym miejscu i czasie.
Każdy element Transition
reprezentuje pojazd podróżujący z jednej lokalizacji do
co dalej. Przejścia mogą wystąpić między parą punktu początkowego pojazdu,
lokalizację i punkt końcowy pojazdu.
Aby zrekonstruować pełną trasę pojazdu visits
i ShipmentRoute
transitions
muszą być połączone. Kombinacja pól w postaci postępu
aktywność pojazdu wygląda tak:
request.vehicles[0].startLocation -> transitions[0] -> visits[0] ->
transitions[1] -> visits[1] -> transitions[2] -> ... -> visits[3] ->
transitions[4] -> request.vehicles[0].endLocation
Parametr ShipmentRoute
zawsze ma o 1 transitions
więcej niż visits
, ponieważ
pojazd musi dotrzeć od miejsca początkowego do pierwszej wizyty na początku
na trasie do ostatniego miejsca na koniec
. Jeśli pojazd nie ma lokalizacji początkowej lub końcowej, będzie ona podana.
więcej transitions
niż visits
, ponieważ lokalizacja pierwszej lub ostatniej wizyty to
używany jako lokalizacja początkowa lub końcowa pojazdu.
W tym przykładzie pierwsze 3 przejazdy mają przejścia między sobą z zerową odległością i czasem, ponieważ wszystkie 3 przejazdy mają tę samą lokalizację w żądaniu.
Więcej informacji znajdziesz w dokumentacji referencyjnej ShipmentRoute
(REST, gRPC).
.
Prosta optymalizacja kolejności punktów pośrednich
Jak widać w tym przykładzie, modele optymalizacji tras odwiedziny jako właściwości
przesyłek i nie ma pojęcia punktów pośrednich ani przystanków jako niezależnego
podmiotu zabezpieczeń. Można jednak przedstawić przystanki lub punkty na trasie jako przesyłki.
z dokładnie 1 usługą VisitRequest
w postaci odbioru lub dostawy. Pojazd musi nadal
mają przypisaną rolę costPerHour
lub costPerKilometer
, aby optymalizator mógł znaleźć
optymalnej trasy (w przeciwieństwie do szukania jakiejkolwiek możliwej trasy).