提出第一項 Route Optimization 要求... 帶著狗狗

歐洲經濟區 (EEA) 開發人員

本文將說明如何使用實際用途情境,向 Route Optimization API 提出第一個要求。

為求簡單,本範例使用 HTTP 和 JSON 示範 REST API。不過,在正式環境中,建議使用 gRPC,以提升效能。不過,gRPC 需要安裝一些項目。詳情請參閱「Route Optimization API 用戶端程式庫」。

情境

舊金山地圖,其中標示了科伊特塔、多洛雷斯公園和南日落遊樂場公園

您在舊金山經營狗狗托育服務,營業時間為上午 7 點到晚上 7 點。今天早上,您想從市內三個不同地點接走三隻狗,並帶到托育中心。

伯恩山犬和吉娃娃是常客,上週就預約了。德國牧羊犬是臨時新增的要求。你希望盡可能配合德國牧羊犬,但不想犧牲常客。

你有一輛貨車,司機時薪為 $27 美元。司機和廂型車在早上 7 點從托育中心出發,必須在中午前完成上午的接送行程,並返回托育中心休息。

今天是 2024 年 2 月 13 日。本情境中的所有時間均為舊金山當地時間,即 2 月的太平洋標準時間 (UTC-8)。驅動程式有下列工作:

  • 在柯伊特塔附近接伯恩山犬。業主希望在上午 8 點到 8 點 20 分之間取貨,時間相當緊湊。
  • 在南日落遊樂場公園接吉娃娃。店主提供更彈性的取貨時段,從上午 7:30 到 9:30。
  • 在蘭茲角接德國牧羊犬。業主也要求在上午 8 點到 8 點 20 分之間取貨。
  • 把狗狗送到多洛雷斯公園的托育中心。托育中心規定,家長必須在上午 9:30 到 11:30 之間送孩子到中心。

每次接送狗兒上下車需要 5 分鐘。

由於 Land's End 距離 Coit Tower 很遠,且取貨時段衝突,因此司機無法完成所有三項取貨作業。最佳化工具必須選擇要略過哪隻狗,盡可能降低總成本 (司機薪資和任何略過罰款)。

事前準備

如要執行這個範例情境中的程式碼,請先完成「設定 Route Optimization API」中的操作說明。

1. 選擇路線最佳化方法

Route Optimization API 提供多種方法,可根據最佳化問題的複雜程度選擇。

由於這個狗狗托育情境是小型且簡單的要求,因此請使用封鎖方法,例如 optimizeTours,可快速提供小型要求的結果。如要進一步瞭解 Route Optimization API 端點,請參閱「選擇端點」。

使用下列網址,向 optimizeTours 方法發出 HTTP POST 要求:

https://routeoptimization.googleapis.com/v1/projects/PROJECT_OR_ID:optimizeTours

您也需要將逾時和期限設定設為較短的時間,以減少不必要的等待時間。在這個狗狗托育情境中,最佳化工具不需要太多時間就能回應要求,因此請使用下列設定:

  • 將 timeout 參數設為 2 秒。
  • 將期限設定保留為預設值,也就是 REST 要求的 60 秒。

2. 建構要求訊息主體

選擇封鎖 optimizeTours 方法並定義逾時和期限設定後,下一步是建構要求訊息的主體。

在這個情境中,要求是 REST API 中編碼為 JSON 的 OptimizeToursRequest 訊息。

如要建構要求訊息,請按照下列步驟操作:

  1. 從基本要求結構開始,如下所示:

    {
      "timeout": ...,
      "model": {
        "shipments": [...],
        "vehicles": [...],
        "globalStartTime": "...",
        "globalEndTime": "..."
      }
    }
    

    如要進一步瞭解結構,請參閱基本結構 (ShipmentModel、Shipment 和 Vehicle) 的重要概念指南。

  2. 定義出貨。在 shipments 欄位中,為每隻需要在早上接送的狗狗新增 Shipment 訊息。您可以在這裡定義每位狗主人的偏好接送地點和時間,以及托育中心的送達地點和時間。

    1. 為每隻狗建立一個 VisitRequest 用於接送,另一個用於送達,在這個情境中稱為托育中心送達。

      • 在接送地點中,將 arrivalWaypoint 設為狗狗的接送地點 (伯恩山犬為柯伊特塔、吉娃娃為南日落遊樂場公園,德國牧羊犬為蘭茲角)。將 timeWindows 設為飼主要求的上車時間 (伯恩山犬和德國牧羊犬為上午 8 點至 8 點 20 分,吉娃娃為上午 7 點 30 分至 9 點 30 分)。

      • 在運送作業中,將 arrivalWaypoint 設為托兒中心,並將 timeWindows 設為所需的下車時間 (上午 9:30 至上午 11:30)。

      • 針對所有接送和運送作業,請將 duration 設為 5 分鐘 (300s),以便預留時間讓狗狗上下車。

      如要進一步瞭解時間範圍,請參閱「時間範圍」。

    2. 為了優先處理一般客戶,您將伯恩山犬和吉娃娃的 penaltyCost 設為 1000,德國牧羊犬則設為 100。設定罰款費用後,最佳化工具可以略過任何狗,但如果限制條件導致無法執行所有取件,則會先考慮略過德國牧羊犬 (罰款較低)。

    3. 您可以使用 label 欄位為每筆運送作業新增 ID,例如「伯恩山犬」、「吉娃娃」和「德國牧羊犬」。這有助於您在回應中識別運送。

    如要進一步瞭解如何定義運送,請參閱「運送」。

  3. 定義車輛。在 vehicles 欄位中,為一輛廂型車新增 Vehicle 訊息,並將托兒中心設為起點和終點,以及司機的薪資費用和廂型車的營業時間。

    1. 將貨車的 startWaypoint 和 endWaypoint 設為當天的起點和終點位置,也就是 Mission Dolores Park 附近的托兒中心。

    2. 如要盡可能降低營運成本,您必須定義業務的成本限制。將費用參數 costPerHour 設為 27,也就是您支付給司機駕駛狗狗托育車的費用。如要進一步瞭解費用參數,請參閱「費用模型」。

    3. 為確保最佳化工具在貨車的營業時間內建立路線,請定義車輛的營業時間範圍。這個時間範圍會設定路線的開始和結束時間限制。只要定義每個時間範圍的一半,最佳化工具就能彈性地延後開始路線或提早結束路線:

      • 在 startTimeWindows 中將 startTime 設為上午 7 點,表示司機最早可在上午 7 點開始值班。如果沒有清晨取貨,也可以晚點開始。

      • 在 endTimeWindows 中將 endTime 設為中午,表示司機必須在中午前結束班次。完成最後一筆訂單後,他們也可以立即結束班表。

      省略另一半的時間範圍,可盡量縮短司機的等待和繞道時間。如要進一步瞭解時間範圍,請參閱「時間範圍」。

    如要進一步瞭解如何定義車輛,請參閱「車輛」。

  4. 設定全域時間範圍。全域時間範圍代表貨車在一天中,可能為托兒所執行接送服務的時間範圍。在這個情境中,請將 2024 年 2 月 13 日的 globalStartTime 設為上午 7 點,globalEndTime 設為下午 7 點,代表狗狗托育中心的營業時間。

3. 傳送要求

以下是根據狗狗托育情境,使用封鎖 optimizeTours 方法的簡單 curl 要求。

傳送要求前,請將程式碼範例中的 PROJECT_NUMBER_OR_ID 替換為 Google Cloud 專案 ID。

curl -X POST 'https://routeoptimization.googleapis.com/v1/projects/PROJECT_NUMBER_OR_ID:optimizeTours' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
--data @- << EOM
{
  "timeout": "2s",
  "model": {
    "shipments": [
      {
        "pickups": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.802395,
                  "longitude": -122.405822
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T08:00:00-08:00",
                "endTime": "2024-02-13T08:20:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "deliveries": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.759719,
                  "longitude": -122.42798
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T09:30:00-08:00",
                "endTime": "2024-02-13T11:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "label": "Bernese mountain dog",
        "penaltyCost": 1000
      },
      {
        "pickups": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.738067,
                  "longitude": -122.498593
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T07:30:00-08:00",
                "endTime": "2024-02-13T09:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "deliveries": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.759719,
                  "longitude": -122.42798
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T09:30:00-08:00",
                "endTime": "2024-02-13T11:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "label": "Chihuahua",
        "penaltyCost": 1000
      },
      {
        "pickups": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.78018,
                  "longitude": -122.51194
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T08:00:00-08:00",
                "endTime": "2024-02-13T08:20:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "deliveries": [
          {
            "arrivalWaypoint": {
              "location": {
                "latLng": {
                  "latitude": 37.759719,
                  "longitude": -122.42798
                }
              }
            },
            "timeWindows": [
              {
                "startTime": "2024-02-13T09:30:00-08:00",
                "endTime": "2024-02-13T11:30:00-08:00"
              }
            ],
            "duration": "300s"
          }
        ],
        "label": "German shepherd",
        "penaltyCost": 100
      }
    ],
    "vehicles": [
      {
        "startWaypoint": {
          "location": {
            "latLng": {
              "latitude": 37.759719,
              "longitude": -122.42798
            }
          }
        },
        "endWaypoint": {
          "location": {
            "latLng": {
              "latitude": 37.759719,
              "longitude": -122.42798
            }
          }
        },
        "costPerHour": 27,
        "startTimeWindows": [
          {
            "startTime": "2024-02-13T07:00:00-08:00"
          }
        ],
        "endTimeWindows": [
          {
            "endTime": "2024-02-13T12:00:00-08:00"
          }
        ]
      }
    ],
    "globalStartTime": "2024-02-13T07:00:00-08:00",
    "globalEndTime": "2024-02-13T19:00:00-08:00"
  }
}
EOM

要求中使用的要求參數

下表說明範例情境的要求主體中使用的要求參數。您可以依父項或文字搜尋篩選內容。

父項 參數 資源類型 說明
OptimizeToursRequest model 物件 (ShipmentModel) 這是要求的核心。這是一個單一物件,您可以在其中定義整個問題,包括所有需要接送的狗 (shipments) 和車隊中的貨車 (vehicles)。您可以將其視為需要最佳化的問題的完整藍圖。
timeout 時間長度 這個參數會指定伺服器在傳回回應前,處理要求的時間上限。使用這個參數可縮短等待時間。如果是小型且快速的要求 (例如這個狗狗托育中心情境),請將這個值設為 2 秒。
ShipmentModel shipments[] 物件陣列 (Shipment) 這是一個物件陣列,每個物件代表一隻需要接送的狗。
vehicles[] 物件陣列 (Vehicle) 這是一個物件陣列,每個物件定義車隊中的一輛車。您可以在這裡描述資源,例如執行取貨和送貨作業的貨車。您必須定義至少一部車輛,才能取得最佳化路線。
globalStartTime 時間戳記 這是整個模型中任何事件可能發生的最早時間。這個參數會縮小最佳化問題的時間範圍,這對於準確計算車流量和路線至關重要。在這個狗狗托育情境中,請將此值設為司機當天可以駕駛廂型車的最早時間,也就是 2024 年 2 月 13 日上午 7 點。
globalEndTime 時間戳記 這是整個模型中任何事件可能發生的最晚時間。在這個狗狗托育情境中,請將此值設為廂型車預計結束營運的時間,也就是 2024 年 2 月 13 日晚上 7 點。
Shipment pickups[] 物件陣列 (VisitRequest) 這份清單列出所有可能的貨件取貨選項。最佳化工具會選擇最適合解決問題的演算法。在這個狗狗托育情境中,請列出每位飼主為每隻狗狗提供的接送地點和時間範圍。
deliveries[] 物件陣列 (VisitRequest) 這份清單列出運送貨物的所有可能卸貨選項。最佳化工具會選擇最適合解決問題的演算法。在這個狗狗托育情境中,請列出狗狗托育設施的位置,以及司機需要返回為每隻狗提供午餐的時間範圍。
label 字串 這是要求中特定運送項目的 ID。 您可以在要求中指定標籤,以便閱讀回應。在這個狗狗托育中心情境中,請使用「吉娃娃」、「伯恩山犬」或狗狗名字等描述性字串,在收到 API 回應時,將解決方案與輸入內容進行比對。
penaltyCost double 如果最佳化工具略過這項運送作業,就會產生這項罰則費用。根據預設,運送作業為必要,最佳化工具會優先盡量減少略過必要運送作業,只有在別無選擇時才會略過。設定罰款費用後,最佳化工具就能略過不可行或成本過高的運送作業,並讓您權衡運送作業之間的優先順序。在這個情境中,您為常客 (伯恩山犬和吉娃娃) 設定較高的罰款費用 (1000),並為臨時預約的德國牧羊犬設定較低的罰款費用 (100)。這會指示最佳化工具優先處理常客,因此當無法完成所有接送時,會先考慮略過德國牧羊犬。
VisitRequest arrivalWaypoint 物件 (Waypoint) 這是路線上特定造訪的地點。您可以使用經緯度座標、地點 ID 或航向來定義。在這個狗狗托育中心情境中,請將這項屬性設為飼主提供的 pickups 位置,以及托育中心的 deliveries 地址。
timeWindows[] 物件陣列 (TimeWindow) 這是一組物件陣列,用於定義取貨或送貨的時間限制。在這個情境中,請使用這個選項定義每隻狗的接送時間範圍,以及可將狗送至托育中心的時間範圍。
duration 時間長度 這個參數會指定造訪時間長度 (例如裝卸貨時間)。在這個情境中,您為所有取貨和送貨作業設定 5 分鐘的緩衝時間 (300s),以便司機裝卸狗狗。
Vehicle startWaypoint 物件 (Waypoint) 這是車輛路線的起點,以經緯度座標或地點 ID 定義。這個參數會告知最佳化工具車輛必須從何處開始路線。如未定義這個路線控點,最佳化工具會選擇其中一個取貨或送貨地點做為起始位置。在這個狗狗托育情境中,司機一早會從托育中心出發,因此請使用多洛雷斯公園的座標。
endWaypoint 物件 (Waypoint) 車輛路線的最終目的地,以經緯度座標或地點 ID 定義。這項參數會告知最佳化工具車輛必須在哪裡結束路線。如未定義這個路線控點,最佳化工具會選擇其中一個取貨或送貨地點做為路線終點。在這個狗狗托育情境中,司機必須在托育中心結束一天的行程,因此請使用 Mission Dolores Park 的座標。
costPerHour 數字 無論車輛行駛或停止,每小時都會產生這筆費用。在這個狗狗托育情境中,請使用這個項目建立司機時薪的模型。
startTimeWindows[] 物件陣列 (TimeWindow) 這是司機可以開始輪班的可接受時間範圍。在這個狗狗托育情境中,請將 startTime 定義為上午 7 點,但省略 endTime。如果第一次取貨時間在上午較晚時段,最佳化工具可延後班次開始時間。請注意,即使您未提供 startTimeWindows 的 endTime,開始時間仍會隱含受限於 endTimeWindows。車輛必須在路線結束前開始行駛。
endTimeWindows[] 物件陣列 (TimeWindow) 這是司機完成路線的可接受時間範圍。 在這個狗狗托育情境中,請將 endTime 定義為中午,但省略 startTime。這樣一來,司機就能在最後一位乘客下車後,立即返回托兒中心。

繼續

解讀回應