Podstawowa optymalizacja obsługi zamówień z odbiorem i dostawą

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:

  1. 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.
  2. Wszystkie przesyłki muszą zostać zrealizowane. Jest to domyślne działanie, gdy koszty kary nie są określone w shipments.
  3. costPerKilometer i costPerHour 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).