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 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 trasy

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. Za pomocą Interactive Polyline Encoder Utility do wizualizacji ścieżek obliczonych przez Optymalizacja trasy. 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.

Przyjazd i wylot waypoint jest również alternatywą dla latLng. Pola Waypoint obsługują identyfikatory Miejsc Google jako alternatywę dla pola LatLng. a także określać nagłówki pojazdów. 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 nieprecyzyjnym ograniczeniem, blisko dostawy i szerokiego globalnego przedziału czasu.
  2. Wszystkie przesyłki muszą zostać zrealizowane. Jest to domyślne działanie, gdy koszty kar nie zostały określone w dniu 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ź na optymalizację trasy zawiera pole routes najwyższego poziomu, które przedstawia proponowane trasy, z jedną trasą dla każdego pojazdu. 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 zadania 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 3 pierwsze wizyty związane z odbiorem występują między nimi z zerową odległością i czasem trwania, ponieważ wszystkie 3 odbicia udostępniać w prośbie tę samą lokalizację.

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).