このドキュメントでは、実際のユースケース シナリオを使用して、Route Optimization API に最初のリクエストを送信する方法について説明します。
わかりやすくするために、この例では HTTP と JSON を使用して REST API を示しています。ただし、本番環境では、パフォーマンス上のメリットがあるため、gRPC を使用することをおすすめします。ただし、gRPC ではインストールが必要になります。詳細については、Route Optimization API クライアント ライブラリをご覧ください。
シナリオ
サンフランシスコで午前 7 時から午後 7 時まで犬のデイケア サービスを運営しているとします。今朝は、市内の異なる場所から 3 匹の犬をピックアップして、デイケア センターに連れて行く必要があります。
バーニーズ マウンテン ドッグとチワワは、先週予約した常連のお客様です。ジャーマン シェパードは、直前に急遽追加されたリクエストです。可能であればジャーマン シェパードを受け入れたいと考えていますが、常連客を犠牲にすることはできません。
この作業に使用できるバンは 1 台で、ドライバーには 1 時間あたり $27 を支払います。ドライバーとバンは、午前 7 時に保育園を出発し、昼食休憩のために正午までに朝の送迎から戻る必要があります。
今日は 2024 年 2 月 13 日です。このシナリオの時刻はすべてサンフランシスコの現地時間です。2 月の太平洋標準時(UTC-8)です。ドライバには次のタスクがあります。
- コイトタワーの近くでバーニーズ マウンテン ドッグを乗せます。オーナーは、午前 8 時から午前 8 時 20 分までの短い集荷時間をリクエストしました。
- サウス サンセット プレイグラウンド パークでチワワを拾います。オーナーは、午前 7 時 30 分から午前 9 時 30 分までのより柔軟な集荷時間を提供しました。
- ランズエンドでジャーマン シェパードを拾います。また、オーナーは午前 8 時から午前 8 時 20 分までの短い集荷時間枠をリクエストしました。
- ミッション ドロレス パークのデイケア センターで犬を降ろします。保育園では、午前 9 時 30 分から午前 11 時 30 分の間に送迎する必要があります。
乗車場所と降車場所での犬の乗降には、それぞれ 5 分かかります。
ランズエンドはコイトタワーから遠く、集荷時間枠が競合するため、ドライバーは 3 つの集荷をすべて行うことはできません。オプティマイザーは、合計費用(ドライバーの賃金とスキップペナルティ)を最小限に抑えるために、スキップする犬を選択する必要があります。
始める前に
このサンプル シナリオのコードを実行するには、まず Route Optimization API を設定するの手順を完了する必要があります。
1. ルート最適化のアプローチを選択する
Route Optimization API には、最適化問題の複雑さに応じて選択できる複数のメソッドが用意されています。
この犬のデイケアのシナリオは、小さく単純なリクエストであるため、optimizeTours などのブロッキング メソッドを使用します。このメソッドは、小さなリクエストの結果を迅速に返します。Route Optimization API エンドポイントの詳細については、エンドポイントを選択するをご覧ください。
次の URL を使用して、optimizeTours メソッドに HTTP POST リクエストを送信します。
https://routeoptimization.googleapis.com/v1/projects/PROJECT_OR_ID:optimizeTours
また、不要な待機時間を短縮するために、タイムアウトと期限の設定を短くする必要があります。この犬のデイケアのシナリオでは、オプティマイザーがリクエストに応答するのに多くの時間を必要としないため、次の設定を使用します。
timeoutパラメータを 2 秒に設定します。- 期限の設定はデフォルトのままにします。REST リクエストの場合は 60 秒です。
2. リクエスト メッセージ本文を作成する
ブロッキング optimizeTours メソッドを選択し、タイムアウトと期限の設定を定義したら、次のステップはリクエスト メッセージの本文を作成することです。
このシナリオでは、リクエストは REST API で JSON としてエンコードされた OptimizeToursRequest メッセージです。
リクエスト メッセージを作成する手順は次のとおりです。
基本的なリクエスト構造から始めます。構造は次のとおりです。
{ "timeout": ..., "model": { "shipments": [...], "vehicles": [...], "globalStartTime": "...", "globalEndTime": "..." } }構造の詳細については、基本構造(ShipmentModel、Shipment、Vehicle)の主なコンセプト ガイドをご覧ください。
配送を定義する。[
shipments] フィールドに、午前中に送迎が必要な犬ごとにShipmentメッセージを追加します。ここでは、犬の飼い主が希望する引き取り場所と時間、デイケア センターの場所と犬を預ける時間を定義します。各犬について、集荷用の
VisitRequestと、配送用の を作成します。このシナリオでは、配送をデイケアへのドロップオフと呼びます。集荷場所で、
arrivalWaypointを犬の集荷場所(バーニーズ マウンテン ドッグの場合はコイトタワー、チワワの場合はサウス サンセット プレイグラウンド パーク、ジャーマン シェパードの場合はランズエンド)に設定します。timeWindowsを、オーナーが希望する迎車時間(バーニーズ マウンテン ドッグとジャーマン シェパードは午前 8 時~午前 8 時 20 分、チワワは午前 7 時 30 分~午前 9 時 30 分)に設定します。配達では、
arrivalWaypointを保育園に設定し、timeWindowsを必要な到着時間(午前 9 時 30 分~午前 11 時 30 分)に設定します。すべての集荷と配達で、犬の乗せ降ろしを考慮して
durationを 5 分(300s)に設定します。
時間枠の詳細については、時間枠をご覧ください。
通常のクライアントを優先するには、バーニーズ マウンテン ドッグとチワワの
penaltyCostを1000に設定し、ジャーマン シェパードを100に設定します。ペナルティ費用が設定されている場合、オプティマイザーはどの犬もスキップできますが、制約によりすべての集荷を実行できない場合は、まずジャーマン シェパード(ペナルティが低い)をスキップすることを検討します。labelフィールドを使用して、各配送に「バーニーズ マウンテン ドッグ」、「チワワ」、「ジャーマン シェパード」などの識別子を追加できます。これにより、レスポンス内の配送を特定できます。
配送の定義の詳細については、配送をご覧ください。
車両を定義する。[
vehicles] フィールドに、1 台のバンのVehicleメッセージを追加します。このメッセージには、保育園を始点と終点として、運転手の賃金とバンの営業時間を指定します。バンの
startWaypointとendWaypointを、その日の開始場所と終了場所(ミッション ドロレス パーク近くの保育園)に設定します。運用コストを最小限に抑えるには、ビジネスのコスト制約を定義する必要があります。費用パラメータ
costPerHourを27に設定します。これは、犬のデイケアバンの運転に対してドライバーに支払う金額です。費用パラメータの詳細については、費用モデルをご覧ください。オプティマイザーがバンの営業時間内にルートを作成するように、車両の運行時間枠を定義します。この時間枠は、ルートの開始時間と終了時間の制約を設定します。各時間枠の半分のみを定義することで、オプティマイザーはルートを遅く開始したり、早く終了したりする柔軟性を得ることができます。
startTimeWindowsのstartTimeを午前 7 時に設定すると、ドライバーは午前 7 時にシフトを開始できます。早朝の集荷がない場合は、それより遅く開始することもできます。endTimeWindowsでendTimeを正午に設定すると、ドライバーは正午までにシフトを終了する必要があります。最後の配達が完了するとすぐに シフトを終了することもできます
ウィンドウの残りの半分を省略すると、ドライバーの待ち時間と迂回時間が最小限に抑えられます。時間枠の詳細については、時間枠をご覧ください。
車両の定義について詳しくは、車両をご覧ください。
グローバルな時間枠を設定する。グローバル タイム ウィンドウは、バンが 1 日を通して保育園の集荷と配達を行う時間枠を表します。このシナリオでは、2024 年 2 月 13 日の
globalStartTimeを午前 7 時に、globalEndTimeを午後 7 時に設定します。これは、犬のデイケアの営業時間を表します。
3. リクエストを送信する
以下は、犬のデイケア シナリオに基づく単純な curl リクエストで、ブロッキング optimizeTours メソッドを使用しています。
リクエストを送信する前に、サンプルコードの 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) |
これはオブジェクトの配列で、各オブジェクトはフリート内の車両を定義します。ここで、集荷と配達を行うバンなどのリソースを記述します。最適化されたルートを取得するには、少なくとも 1 台の車両を定義する必要があります。 | |
globalStartTime |
タイムスタンプ | これは、モデル全体でイベントが発生する最も早い時刻です。このパラメータは、最適化問題を時間的に絞り込みます。これは、正確なトラフィックとルートの計算に不可欠です。この犬のデイケアのシナリオでは、ドライバーがその日にバンを運転できる最も早い時間(2024 年 2 月 13 日の午前 7 時)に設定します。 | |
globalEndTime |
タイムスタンプ | これは、モデル全体で発生する可能性のあるイベントの最新の時刻です。この犬のデイケアのシナリオでは、これをバンの運行が終了する予定時刻(2024 年 2 月 13 日の午後 7 時)に設定します。 | |
Shipment |
pickups[] |
オブジェクトの配列(VisitRequest) |
これは、配送で利用可能なすべての受け取りオプションのリストです。オプティマイザーは、問題を解決するために最適なものを選択します。この犬のデイケアのシナリオでは、各飼い主が各犬に指定した集荷場所と時間枠をリストします。 |
deliveries[] |
オブジェクトの配列(VisitRequest) |
これは、配送に使用できるすべての持ち込みオプションのリストです。オプティマイザーは、問題を解決するために最適なものを選択します。この犬のデイケアのシナリオでは、犬のデイケア施設の場所と、各犬の昼食のためにドライバーが戻る必要がある時間枠をリストします。 | |
label |
文字列 | これは、リクエスト内の特定の配送の識別子です。 リクエストでラベルを指定すると、レスポンスを読みやすくできます。この犬のデイケアのシナリオでは、API レスポンスを受け取ったときにソリューションを入力に一致させるために、「チワワ」、「バーニーズ マウンテン ドッグ」、犬の名前などのわかりやすい文字列を使用します。 | |
penaltyCost |
double | これは、オプティマイザーがこの配送をスキップした場合に発生するペナルティ費用です。デフォルトでは、配送は必須です。オプティマイザーは、スキップされる必須の配送を最小限に抑えることを優先し、他に選択肢がない場合にのみスキップします。ペナルティ費用を設定すると、オプティマイザーは、実行が不可能またはコストが高すぎる場合に配送をスキップし、配送間の優先度を比較できます。このシナリオでは、通常のクライアント(バーニーズ マウンテン ドッグとチワワ)には高いペナルティ費用(1000)を設定し、直前のジャーマン シェパードのリクエストには低いペナルティ費用(100)を設定します。これにより、オプティマイザーは常連の顧客を優先するよう指示されるため、すべての集荷を実行できない場合は、まずジャーマン シェパードのスキップを検討します。 |
|
VisitRequest |
arrivalWaypoint |
オブジェクト(Waypoint) |
これは、ルート上の特定の訪問の場所です。これは、緯度と経度の座標、プレイス ID、または角度を使用して定義できます。この犬のデイケアのシナリオでは、pickups にはオーナーが指定した場所を設定し、deliveries にはデイケア センターの住所を設定します。 |
timeWindows[] |
オブジェクトの配列(TimeWindow) |
これは、集荷または配達の時間制約を定義するオブジェクトの配列です。このシナリオでは、これを使用して、各犬の集荷時間枠と、犬をデイケア センターに預けることができる時間枠を定義します。 | |
duration |
所要時間 | このパラメータは、訪問の所要時間(積み込みや積み下ろしの時間など)を指定します。このシナリオでは、ドライバーが犬を乗せたり降ろしたりする時間を考慮して、すべての集荷と配達に 5 分のバッファ(300s)を設定します。 |
|
Vehicle |
startWaypoint |
オブジェクト(Waypoint) |
これは、緯度と経度の座標またはプレイス ID で定義された、車両のルートの開始位置です。このパラメータは、車両がルートを開始する場所をオプティマイザーに指示します。このウェイポイントを定義しない場合、オプティマイザーは集荷または配達のいずれかを開始地点として選択します。この犬のデイケアのシナリオでは、ドライバーはデイケア施設で 1 日を始めるため、ミッション ドロレス パークの座標を使用します。 |
endWaypoint |
オブジェクト(Waypoint) |
車両のルートの最終目的地。緯度と経度の座標またはプレイス ID で定義されます。このパラメータは、車両がルートを終了する必要がある場所をオプティマイザーに指示します。このウェイポイントを定義しない場合、オプティマイザーは集荷または配達のいずれかをルートの終点として選択します。この犬のデイケアのシナリオでは、ドライバーはデイケア施設で 1 日を終える必要があるため、ミッション ドロレス パークの座標を使用します。 | |
costPerHour |
数値 | これは、車両が走行中か停止中かにかかわらず、車両が使用される 1 時間ごとに発生する費用です。この犬のデイケアのシナリオでは、これを使用してドライバーの時給をモデル化します。 | |
startTimeWindows[] |
オブジェクトの配列(TimeWindow) |
これは、ドライバーがシフトを開始できる許容時間枠です。この犬のデイケアのシナリオでは、startTime を午前 7 時に定義しますが、endTime は省略します。これにより、オプティマイザーは、最初の集荷が午前中の遅い時間である場合に、シフトの開始を遅らせることができます。startTimeWindows に endTime を指定しない場合でも、開始時間は endTimeWindows によって暗黙的に制限されます。車両は、ルートが終了する前にルートを開始する必要があります。 |
|
endTimeWindows[] |
オブジェクトの配列(TimeWindow) |
これは、ドライバーがルートを完了するのに許容される時間枠です。
この犬のデイケアのシナリオでは、endTime を正午として定義しますが、startTime は省略します。これにより、ドライバーは最後の降車地点からすぐに保育園に戻ることができます。 |