グループにジョブを割り当てる
HERE Tour Planning APIのジョブグルーピングは、特に効率的なルート計画とリソース割り当てが極めて重要なシナリオで、物流業務を最適化するためのさまざまなソリューションを提供します。都市内のさまざまな目的地に商品を輸送する配達サービスを考えてみましょう。ジョブグルーピングを利用することで、配送会社は地理的近接性、配達時間帯、商品タイプなどの特定の基準に基づいて配達を戦略的に管理できます。
ジョブグルーピングの適用例
以下の例は、ジョブグルーピングにより業務効率が高まり、物流プロセスを合理化できるさまざまな実用的なシナリオを示したものです。
-
郵便配達:郵便配達員は特定の地域に対応する住居の鍵一式を携帯していることがよくあります。各セットはそれぞれ異なる配達ゾーンを表しています。そのため、通常は1つのエリア内ですべての配達を完了してから次のエリアに移動することで、ルート効率を最適化します。
-
制限されたアクセスエリア:ドライバーが特定のエリアにアクセスするためにゲートでの登録が必要となるシナリオでは、ジョブグルーピングが不可欠になります。一旦エリア内に入ると、ドライバーはサインアウトする前にすべての配達を完了しようとするため効率が最大化され、出入りを繰り返すことによる混乱を最小限に抑えます。
-
都市部での配達におけるドライバーの効率性:都市環境では、ドライバーは特定の都市区画内で配達を完了することを優先し、各区画を別個のエンティティとして扱います。近隣区画のジョブを1つ処理するなど、ルートを最適化できる可能性があったとしても、多くのドライバーはこの構造化されたアプローチを選択することで、一貫性を維持し、混乱を最小限に抑え、配達業務の効率性を維持しようとします。
ジョブのグループ化の仕組み
HERE Tour Planning APIでは、オプションのgroupIdパラメーターを使ってジョブをグループ化できます。問題内の一連のジョブに同じgroupIdを割り当てることで、最適化アルゴリズムに対し、そのグループ内のすべてのジョブに1台の車両が訪問できるルーティングソリューションを生成するように指示します。このとき、グループ内の各ジョブは1台の車両にのみ割り当てられます (つまり、1台の車両が複数のグループを担当することはできますが、別の車両とグループを分担することはできません)。
ジョブのグループ化に次のいずれかのモードを選択して、必要に応じてグループ化メカニズムを調整できます。
-
strict(デフォルト):同じグループのすべてのジョブを完了しないと、他のジョブまたは別のグループのジョブを開始できません。このモードでは、最適化アルゴリズムはスタンドアロンジョブとグループの割り当てを混在させないようにしますが、スタンドアロンジョブを連続するグループ割り当ての間に割り込ませることができます。このモードでは、アルゴリズムは特定の場所での再積載や休憩などの業務は、特定の場所がない休憩を除き、グループジョブとは別に保持されます。つまり、特定の場所での休憩や再積載は車両が特定のグループ内のすべての割り当てを完了した後または完了する前にのみスケジュールできます。
実用的なデモについては、「ユースケース:エリア別に配達ジョブをグループ化する」を参照してください。
-
flexible:このモードでは、ツアーの進行に合わせてグループIDが異なるジョブを混在させることができ、可能な限り最も効率的なルートを見つけることに重点が置かれます。このモードでは、最適化アルゴリズムは、ツアー内の任意の場所での休憩 (場所の有無にかかわらず) や再積載をスケジュールできるようにすることで、効率を優先します。
実用的なデモについては、「ユースケース:生徒を学校に安全に送迎する」を参照してください。
ジョブグループではジョブクラスタリングは許可されますが、異なるグループのジョブが一緒にクラスター化されないという制約があります。さらに、このアルゴリズムではグループでのツアー順序をグローバルに使用できます。グループジョブに優先順位を割り当てることができ、優先順位の低いタスクの割り当てを解除できる柔軟性を備えています。
ユースケース:エリア別に配達ジョブをグループ化する
個別の配達エリアに応じてジョブをグループ化し、業務を合理化しようとしている配送会社について考えてみましょう。このシナリオでは、各エリアは指定された一連の配達タスクを表しており、タスクは次のエリアに移動する前に完了する必要があります。たとえば、現在のエリア内の配達タスクがすべて完了した場合にのみ、車両は新しいエリアに移動できます。
問題
次の問題は、米国のある都市の近隣地域の名前を表す個別のGroupId値がある一連のジョブで構成されています。1つのジョブにはGroupIdが割り当てられていません。
Click to expand/collapse the sample JSON
{
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {
"fixed": 2,
"distance": 0.0001,
"time": 0.0005
},
"shifts": [
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
},
"end": {
"time": "2021-10-23T21:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
}
}
],
"capacity": [
10
],
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car"
}
]
},
"plan": {
"jobs": [
{
"id": "Job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_5",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_6",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_7",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"duration": 1500
}
],
"demand": [
1
]
}
]
}
}
]
}
}ソリューション
次のスニペットは、前述の問題に基づいて、最適化アルゴリズムが提供したソリューションを示しています。
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 8.8008,
"distance": 9823,
"duration": 11637,
"times": {
"driving": 1137,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
7
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:03:01Z",
"departure": "2021-10-23T08:28:01Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job_1",
"type": "delivery",
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"time": {
"start": "2021-10-23T08:03:01Z",
"end": "2021-10-23T08:28:01Z"
}
}
],
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"distance": 1614
},
{
"time": {
"arrival": "2021-10-23T08:31:02Z",
"departure": "2021-10-23T08:56:02Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job_2",
"type": "delivery",
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"time": {
"start": "2021-10-23T08:31:02Z",
"end": "2021-10-23T08:56:02Z"
}
}
],
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"distance": 2865
},
{
"time": {
"arrival": "2021-10-23T08:57:33Z",
"departure": "2021-10-23T09:22:33Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_3",
"type": "delivery",
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"time": {
"start": "2021-10-23T08:57:33Z",
"end": "2021-10-23T09:22:33Z"
}
}
],
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"distance": 3516
},
{
"time": {
"arrival": "2021-10-23T09:25:40Z",
"departure": "2021-10-23T09:50:40Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_7",
"type": "delivery",
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"time": {
"start": "2021-10-23T09:25:40Z",
"end": "2021-10-23T09:50:40Z"
}
}
],
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"distance": 5774
},
{
"time": {
"arrival": "2021-10-23T09:52:50Z",
"departure": "2021-10-23T10:17:50Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_5",
"type": "delivery",
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"time": {
"start": "2021-10-23T09:52:50Z",
"end": "2021-10-23T10:17:50Z"
}
}
],
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"distance": 6778
},
{
"time": {
"arrival": "2021-10-23T10:18:51Z",
"departure": "2021-10-23T10:43:51Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_6",
"type": "delivery",
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"time": {
"start": "2021-10-23T10:18:51Z",
"end": "2021-10-23T10:43:51Z"
}
}
],
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"distance": 7239
},
{
"time": {
"arrival": "2021-10-23T10:45:33Z",
"departure": "2021-10-23T11:10:33Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_4",
"type": "delivery",
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"time": {
"start": "2021-10-23T10:45:33Z",
"end": "2021-10-23T11:10:33Z"
}
}
],
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"distance": 7861
},
{
"time": {
"arrival": "2021-10-23T11:13:57Z",
"departure": "2021-10-23T11:13:57Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T11:13:57Z",
"end": "2021-10-23T11:13:57Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 9823
}
],
"statistic": {
"cost": 8.8008,
"distance": 9823,
"duration": 11637,
"times": {
"driving": 1137,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}このソリューションが示すように、最適化アルゴリズムにより、同じGroupIDパラメーターを持つジョブが次の一連の停車地でグループ化されるようになりました。
GroupId:Bradley-Job_1(停車地1)、Job_2(停車地2)、Job_3(停車地3)- グループなし:
Job_7(停車地4) GroupId:Audubon-Job_4(停車地5)、Job_5(停車地6)、Job_6(停車地7)
注
グループジョブに関する問題のソリューションを最適化するとき、アルゴリズムはグループタスクまたは個々のタスクのさまざまなシーケンスを選択することがあります。ただし、アルゴリズムは、特定のグループのジョブがすべて完了する前に単独のジョブを挟まないよう設計されています。
次の図は、前述のソリューションの一連の停車地を色分けして示したものです。この図は、特定の近隣地域に関連するジョブが、GroupId (存在する場合) に基づいてどのように順番に計画されるかを示したものです。
注
前の例では、説明のために単純化した問題を示しています。一方、次の図ではより現実に即したユースケースとして、80個のジョブが4つのグループに分割され、各グループに同数のジョブが含まれるジョブグループを示しています。
この例では、特にタスクの割り当てや作業負荷の分散などの場面において、ジョブをグループに編成することでジョブをより効率的に管理するのにどのように役立つかをさらに詳しく示しています。
対照的に、次のスニペットでは前述のサンプル問題でジョブのグループ割り当てを解除した場合のソリューションを提供しています。
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 8.7913,
"distance": 9823,
"duration": 11618,
"times": {
"driving": 1118,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
7
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:04:35Z",
"departure": "2021-10-23T08:29:35Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job_2",
"type": "delivery",
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"time": {
"start": "2021-10-23T08:04:35Z",
"end": "2021-10-23T08:29:35Z"
}
}
],
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"distance": 2407
},
{
"time": {
"arrival": "2021-10-23T08:31:06Z",
"departure": "2021-10-23T08:56:06Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job_3",
"type": "delivery",
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"time": {
"start": "2021-10-23T08:31:06Z",
"end": "2021-10-23T08:56:06Z"
}
}
],
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"distance": 3058
},
{
"time": {
"arrival": "2021-10-23T08:59:13Z",
"departure": "2021-10-23T09:24:13Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_7",
"type": "delivery",
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"time": {
"start": "2021-10-23T08:59:13Z",
"end": "2021-10-23T09:24:13Z"
}
}
],
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"distance": 5316
},
{
"time": {
"arrival": "2021-10-23T09:26:23Z",
"departure": "2021-10-23T09:51:23Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_5",
"type": "delivery",
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"time": {
"start": "2021-10-23T09:26:23Z",
"end": "2021-10-23T09:51:23Z"
}
}
],
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"distance": 6320
},
{
"time": {
"arrival": "2021-10-23T09:52:24Z",
"departure": "2021-10-23T10:17:24Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_6",
"type": "delivery",
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"time": {
"start": "2021-10-23T09:52:24Z",
"end": "2021-10-23T10:17:24Z"
}
}
],
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"distance": 6781
},
{
"time": {
"arrival": "2021-10-23T10:19:06Z",
"departure": "2021-10-23T10:44:06Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_4",
"type": "delivery",
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"time": {
"start": "2021-10-23T10:19:06Z",
"end": "2021-10-23T10:44:06Z"
}
}
],
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"distance": 7403
},
{
"time": {
"arrival": "2021-10-23T10:45:50Z",
"departure": "2021-10-23T11:10:50Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_1",
"type": "delivery",
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"time": {
"start": "2021-10-23T10:45:50Z",
"end": "2021-10-23T11:10:50Z"
}
}
],
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"distance": 8209
},
{
"time": {
"arrival": "2021-10-23T11:13:38Z",
"departure": "2021-10-23T11:13:38Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T11:13:38Z",
"end": "2021-10-23T11:13:38Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 9823
}
],
"statistic": {
"cost": 8.7913,
"distance": 9823,
"duration": 11618,
"times": {
"driving": 1118,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}前述のソリューションでは、次の図に示すように、最適化アルゴリズムは追加の制約なしで後続の停車地間の最速ルートを決定します。
前述のソリューションで示したように、最適化アルゴリズムにより、GroupIdがあるジョブとないジョブを単一の問題内に含めることができます。同時に、このアルゴリズムは、GroupIDのないジョブがグループに属するジョブに混在しないようにします。この分離により、グループ内のジョブが確実に連続的に処理され、ワークフローが最適化され、混乱が起こる可能性を排除します。
PUDOを使用したジョブグループ
「PUDO」とは「Pick-Up and Drop-Off」ポイントの略称で、配送のために荷物を受け取る、または次の処理のために荷物を届ける場所のことです。グループジョブのケースでは、PUDOは最初または最後の場所として機能し、商品の集荷や配達、乗客の送迎を容易にします。
注
現在この機能はベータ版です。ベータ機能は開発の最終段階にあり、重大なバグは存在しませんが、カバレッジ、品質、パフォーマンス、またはテストカバレッジがまだ最終形ではない可能性があります。この機能のデータモデルおよび問題定義は、以前のバージョンから安定しており変更されていません。本番環境での完全な利用に向けて機能が完成に近づく中で、動作の細かな調整が行われる可能性があることを理解した上で、ベータ機能をアプリケーションで使用できます。
ユースケース:パーセルの集荷地点と配達地点を指定する
サンプルの宅配便サービスを考えてみましょう。このサービスでは、PUDOを集荷地点または配達地点として機能するよう戦略的に配置し、HERE Tour Planning APIのジョブグループの開始時または終了時の業務効率を促進します。この例のケースでは、サービスはPUDOを次の2つのカテゴリーに分類できます。
-
最初のPUDO:特定のグループに属する一連のジョブの最初の停車地として位置付けられ、後で宅配業者が配達できるよう顧客が荷物を預けることができる店舗、郵便局、または専用の集荷ロッカーを表します。
-
最後のPUDO:ジョブグループ内の最終停車地として位置付けられ、都市内の主要エリアに戦略的に配置された宅配ロッカーを表します。通常の配達時間内にパーセルを受け取ることができない可能性がある顧客は、荷物が自宅やオフィスの代わりにこれらのロッカーに配達されるよう選択できます。
車両を必ずPUDOで開始または終了させるには、次のスニペットに示すように、問題のJSONのplanオブジェクト内にオブジェクトのgroup配列を追加します。
"plan": {
"fleet": {...},
"groups": [
{
"id": "Bradley",
"pudos": [
{
"id": "pudoBradleyFirst",
"assignAt": "first",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyFirstPudo"
}
]
},
{
"id": "pudoBradleyLast",
"assignAt": "last",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyLastPudo"
}
]
}
]
}
],
"jobs": {...}
}このJSONスニペットは、ジョブグループ内で荷物配達タスクを整理するためのデータ構造を記述しており、特に前の例の"Bradley"グループに焦点を当てています。
"id": "Bradley":これにより、PUDOが適用されるグループが一意の識別子"Bradley"によって識別されます。"pudos":この配列には、Bradleyグループに関連付けられたPUDO (Pick Up Drop Offポイント) に関する情報が含まれています。1つのグループに最大2つのPUDOを含めることができ、それぞれに異なるassignAt値が設定されます。"id": "pudoBradleyFirst"と"id": "pudoBradleyLast":これらはそれぞれ、Bradleyグループ内の最初と最後のPUDOの識別子です。"assignAt":PUDOがグループの一連の配達タスクの最初 ("first") または最後 ("last") に割り当てられているかどうかを示します。"places":各PUDOに関連付けられた場所、所要時間、タグに関する詳細が含まれています。"location":PUDOの緯度と経度の座標を指定します。"duration":PUDOで費やした推定時間を秒単位で表します。"tag":"groupBradleyFirstPudo"や"groupBradleyLastPudo"など、PUDOを説明するタグを指定します。
詳細については、「APIリファレンス」を参照してください。
問題
次の問題は、両方のグループにPUDOを組み込むことによって、前に示した問題をさらに発展させたものです。この更新された問題では、BradleyグループにはfirstとlastのPUDOが割り当てられていますが、AudubonグループにはlastのPUDOしかありません。
Click to expand/collapse the sample JSON
{
"configuration": {
"experimentalFeatures":
["pudos"]
},
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {
"fixed": 2,
"distance": 0.0001,
"time": 0.0005
},
"shifts": [
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
},
"end": {
"time": "2021-10-23T21:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
}
}
],
"capacity": [
10
],
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car"
}
]
},
"plan": {
"groups": [
{
"id": "Audubon",
"pudos": [
{
"id": "pudoAudubonLast",
"assignAt": "last",
"places": [
{
"location": {
"lat": 38.21394813756292,
"lng": -85.72935333995113
},
"duration": 300,
"tag": "groupAudubonLastPudo"
}
]
}
]
},
{
"id": "Bradley",
"pudos": [
{
"id": "pudoBradleyFirst",
"assignAt": "first",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyFirstPudo"
}
]
},
{
"id": "pudoBradleyLast",
"assignAt": "last",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyLastPudo"
}
]
}
]
}
],
"jobs": [
{
"id": "Job_1_Bradley",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_2_Bradley",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_3_Bradley",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_4_Audobon",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_5_Audobon",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_6_Audobon",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_7_No_Group",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"duration": 1500
}
],
"demand": [
1
]
}
]
}
}
]
}
}ソリューション
更新されたソリューションが示すように、両方のグループにPUDOを導入すると、グループとジョブの順序に大きな影響を与えます。
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 10.2287,
"distance": 16177,
"duration": 13222,
"times": {
"driving": 1822,
"serving": 11400,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
7
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:03:14Z",
"departure": "2021-10-23T08:28:14Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job_4_Audobon",
"type": "delivery",
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"time": {
"start": "2021-10-23T08:03:14Z",
"end": "2021-10-23T08:28:14Z"
}
}
],
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"distance": 1962
},
{
"time": {
"arrival": "2021-10-23T08:29:55Z",
"departure": "2021-10-23T08:54:55Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job_6_Audobon",
"type": "delivery",
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"time": {
"start": "2021-10-23T08:29:55Z",
"end": "2021-10-23T08:54:55Z"
}
}
],
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"distance": 2584
},
{
"time": {
"arrival": "2021-10-23T08:55:56Z",
"departure": "2021-10-23T09:20:56Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_5_Audobon",
"type": "delivery",
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"time": {
"start": "2021-10-23T08:55:56Z",
"end": "2021-10-23T09:20:56Z"
}
}
],
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"distance": 3045
},
{
"time": {
"arrival": "2021-10-23T09:22:16Z",
"departure": "2021-10-23T09:27:16Z"
},
"load": [
4
],
"activities": [
{
"jobId": "pudoAudubonLast",
"type": "pudo",
"jobTag": "groupAudubonLastPudo",
"location": {
"lat": 38.21394813756292,
"lng": -85.72935333995113
},
"time": {
"start": "2021-10-23T09:22:16Z",
"end": "2021-10-23T09:27:16Z"
}
}
],
"location": {
"lat": 38.21394813756292,
"lng": -85.72935333995113
},
"distance": 3627
},
{
"time": {
"arrival": "2021-10-23T09:30:01Z",
"departure": "2021-10-23T09:55:01Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_7_No_Group",
"type": "delivery",
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"time": {
"start": "2021-10-23T09:30:01Z",
"end": "2021-10-23T09:55:01Z"
}
}
],
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"distance": 4879
},
{
"time": {
"arrival": "2021-10-23T09:59:54Z",
"departure": "2021-10-23T10:04:54Z"
},
"load": [
3
],
"activities": [
{
"jobId": "pudoBradleyFirst",
"type": "pudo",
"jobTag": "groupBradleyFirstPudo",
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"time": {
"start": "2021-10-23T09:59:54Z",
"end": "2021-10-23T10:04:54Z"
}
}
],
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"distance": 7887
},
{
"time": {
"arrival": "2021-10-23T10:07:28Z",
"departure": "2021-10-23T10:32:28Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_3_Bradley",
"type": "delivery",
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"time": {
"start": "2021-10-23T10:07:28Z",
"end": "2021-10-23T10:32:28Z"
}
}
],
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"distance": 9022
},
{
"time": {
"arrival": "2021-10-23T10:34:31Z",
"departure": "2021-10-23T10:59:31Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_1_Bradley",
"type": "delivery",
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"time": {
"start": "2021-10-23T10:34:31Z",
"end": "2021-10-23T10:59:31Z"
}
}
],
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"distance": 10444
},
{
"time": {
"arrival": "2021-10-23T11:02:32Z",
"departure": "2021-10-23T11:27:32Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_2_Bradley",
"type": "delivery",
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"time": {
"start": "2021-10-23T11:02:32Z",
"end": "2021-10-23T11:27:32Z"
}
}
],
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"distance": 11695
},
{
"time": {
"arrival": "2021-10-23T11:29:43Z",
"departure": "2021-10-23T11:34:43Z"
},
"load": [
0
],
"activities": [
{
"jobId": "pudoBradleyLast",
"type": "pudo",
"jobTag": "groupBradleyLastPudo",
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"time": {
"start": "2021-10-23T11:29:43Z",
"end": "2021-10-23T11:34:43Z"
}
}
],
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"distance": 12487
},
{
"time": {
"arrival": "2021-10-23T11:40:22Z",
"departure": "2021-10-23T11:40:22Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T11:40:22Z",
"end": "2021-10-23T11:40:22Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 16177
}
],
"statistic": {
"cost": 10.2287,
"distance": 16177,
"duration": 13222,
"times": {
"driving": 1822,
"serving": 11400,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}次の図は、前のソリューションを視覚化したもので、各グループの停車地の順序と、各グループに割り当てられたPUDOを強調表示しています。
このソリューションが示すように、Bradleyグループには同じ場所にfirstとlastの両方のPUDOが含まれるようになりました。したがって、このグループを担当する車両は、Bradleyグループ外の他のジョブに進む前に、最初と最後の停車地としてその場所に立ち寄る必要があります。このアプローチにより、車両がグループに関連するすべてのパーセルを集荷し、グループ内のすべてのジョブを完了した後に、未配達のパーセルを同じ場所に降ろすようになります。未配達の荷物は別のツアーで受け取ることができます。
一方、Audubonグループには最後のPUDOしかありません。これは、この特定のグループを担当している間、この停車地が常に最後の停車地であり、これより前の停車地の順序は最適化アルゴリズムによって動的に決定されることを意味します。
フレキシブルグループ
flexibleGroups機能を使用すると、関連するジョブを相互にリンクでき、さまざまなユースケースにメリットをもたらします。特定のグループ内のジョブは1台の車両しか完了できないという制約を利用して、車両は異なるグループのジョブを組み合わせて実行することでルートを最適化できます (例:A1 -> B1 -> A2 -> B2)。このアプローチは、車両は他のグループのジョブに移行する前に1つのグループ内のすべてのジョブを完了する必要がある、より厳格に元のジョブをグループ化するアプローチとは対照的です (例:A1 -> A2 -> B1 -> B2)。
たとえば、郵便配達員に特定の建物、郵便受け、コミュニティなどにアクセスするための特定のキーセットを割り当てることができます。strictのアプローチでは、郵便配達員は、特定のキーセットに対応するすべての割り当てを完了してから次のグループに移る必要があり、これは必ずしも効率的とは限りません。
flexibleのアプローチでは、ルートの効率が最も高くなるのであれば、郵便配達員は「キーセットA」を必要とする荷物をいくつか配達し、次に「キーセットB」を必要とする荷物を配達し、再び「キーセットA」を必要とする荷物に戻ることができます。
グループの配置は、次の例に示すように、plan.groups.placementオブジェクトの一部として設定します。
{ ...
"groups": [
{
"id": "group_A",
"placement": "flexible"
},
{
"id": "group_B",
"placement": "flexible"
},
{
"id": "Group_C",
"placement": "strict"
},
]
...
}strict値を指定すると、車両はこのグループ内のすべての割り当てを完了しないと、別のグループの対応に進めません。詳細はこのドキュメントの前のセクションを参照してください。
詳細については、「APIリファレンス」を参照してください。
注
これはアルファ機能 (新規またはテスト段階であり、現在開発中) です。アルファ機能は、テストおよびフィードバックの目的で提供されています。これらは大幅に変更されたり、一般に入手できなくなったりする可能性があります。 詳細については、「テスト段階の機能の詳細」を参照してください。
この機能を有効にするには、
flexibleGroupsフラグをexperimentalFeatures配列に追加します。フレキシブルグループはPUDO機能と互換性があります。
ユースケース:生徒を学校に安全に送迎する
この機能の有用性をわかりやすく示す例として、生徒が自宅から学校に行き、学校から自宅に戻る2つの通学経路を持つ、スクールバスのシナリオが挙げられます。多くの場合、このような状況では、保護者は生徒が同じドライバーによって学校に送迎されることで、生徒の安全が確保されることを望みます。
フレキシブルグループを使用することで、生徒が午前と午後の通学時に同じドライバーが送迎するスクールバスの最適なツアーを設計できます。
次のリストは、一般的な生徒の日々の通学中に発生する主なイベントをまとめたものです。
- 午前のピックアップ:生徒は自宅でピックアップされ、1日が始まります。
- 学校でのドロップオフ:生徒は学校に到着し、教育活動が始まります。
- 午後のピックアップ:生徒は学校でピックアップされ、その後の日課を続けたり、自宅へ帰ったりします。
- 夕方のドロップオフ:生徒の1日は、自宅にドロップオフされ締めくくられます。
HERE Tour Planning APIでは、このような生徒の通学イベントを、生徒ごとに2つの別々のマルチジョブ (午前の通学と午後の通学) としてモデル化できます。各マルチジョブには、ピックアップタスクとデリバリータスクの2つのタスクを使用する必要があります。次の例は、この概念を示しています。
[ジョブ1:ピックアップA→デリバリーA]→[ジョブ2:ピックアップB→デリバリーB]
問題の午前と午後のジョブを確実にリンクさせるには、問題に次の設定項目を含める必要があります。
groupsオブジェクトで、生徒ごとに一意のグループidを作成します。各グループの配置をflexibleとして設定します。- 学校への登下校の送迎を示す各ジョブペアで、午前中のドロップオフ (デリバリー) タスクと午後のピックアップタスクを同じ
groupIdに割り当てます。
flexibleGroups機能を使って関連するジョブをグループ化することで、ルートを最適化できるだけでなく、各生徒が午前と午後の両方の通学を同じドライバーに (または同じバスで) 送迎されるようになります。これにより、生徒の送迎がこなかったり、別のドライバーに誤って割り当てられたりする可能性が低くなるため、安全性とセキュリティが高まります。
次の図は、このユースケースをわかりやすくまとめたものです。
問題
次の問題JSONファイルでは、前述のスクールバスのユースケースを次の設定で再現しています。
- 運行管理が2台の車両で構成されており、各車両はツアー中の任意の地点で最大4人の生徒を乗せることができます。
- 生徒は7人おり、ドライバーは午前中にピックアップし、学校にドロップオフし、午後には自宅に送る必要があります。
- 各生徒 (生徒コードで示されている) には、それぞれ一意の
groupIdが割り当てられています。 - 各グループの
placement設定はflexibleに設定されています。 - 生徒コードごとに、学校での午前のドロップオフと午後のピックアップを表すタスクが
groupIdを使用して割り当てられます。これにより、生徒は往復とも同じドライバーに割り当てられ、ドライバーはそのバスで複数の生徒を同時に運ぶことができるようになるので、ツアーの効率が高まります。
Click to expand/collapse the sample JSON
{
"configuration": {
"experimentalFeatures":
["flexibleGroups"]
},
"fleet": {
"types": [
{
"id": "bus",
"profile": "bus",
"costs": {
"fixed": 20,
"distance": 0,
"time": 0.005
},
"shifts": [
{
"start": {
"time": "2023-05-28T06:00:00Z",
"location": {
"lat": 52.50935,
"lng": 13.41997
}
},
"end": {
"time": "2023-05-28T18:00:00Z",
"location": {
"lat": 52.50935,
"lng": 13.41997
}
}
}
],
"capacity": [
4
],
"amount": 2
}
],
"profiles": [
{
"type": "bus",
"name": "bus"
}
]
},
"plan": {
"groups": [
{
"id": "Student_Code_1",
"placement": "flexible"
},
{
"id": "Student_Code_2",
"placement": "flexible"
},
{
"id": "Student_Code_3",
"placement": "flexible"
},
{
"id": "Student_Code_4",
"placement": "flexible"
},
{
"id": "Student_Code_5",
"placement": "flexible"
},
{
"id": "Student_Code_6",
"placement": "flexible"
},
{
"id": "Student_Code_7",
"placement": "flexible"
}
],
"jobs": [
{
"id": "PickupEvent_1",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_1"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_2",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_2"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_3",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_3"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_4",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_4"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_5",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_5"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_6",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_6"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_7",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_7"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_1",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_1"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_2",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_2"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_3",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_3"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_4",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_4"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_5",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_5"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_6",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_6"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_7",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_7"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
}
]
}
}ソリューション
次の図は、前の問題のソリューションを視覚化したもので、重要な要素が強調表示されています。
図に示されているように、2台の車両がこのジョブを完了するように割り当てられており、各車両は午前と午後の送迎で同じ生徒を担当しています。たとえば、PickupEvent_6とDropoffEvent_6インスタンスとして自宅 (停車地3および5) と学校 (停車地4) が強調表示されています。すべてのグループをflexible配置に設定することで、ドライバーは各生徒を別々にピックアップしてドロップオフするのではなく、ジョブを効率的かつ順番に処理できるようになりました。
次のセクションには、このユースケースの完全なソリューションJSONが含まれています。
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 338.235,
"distance": 63391,
"duration": 59647,
"times": {
"driving": 8473,
"serving": 140,
"waiting": 51034,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "bus_2",
"typeId": "bus",
"stops": [
{
"time": {
"arrival": "2023-05-28T06:00:00Z",
"departure": "2023-05-28T07:07:57Z"
},
"load": [
0
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T06:00:00Z",
"end": "2023-05-28T07:07:57Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 0
},
{
"time": {
"arrival": "2023-05-28T07:12:00Z",
"departure": "2023-05-28T07:12:05Z"
},
"load": [
1
],
"activities": [
{
"jobId": "PickupEvent_1",
"type": "pickup",
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"time": {
"start": "2023-05-28T07:12:00Z",
"end": "2023-05-28T07:12:05Z"
}
}
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"distance": 1445
},
{
"time": {
"arrival": "2023-05-28T07:16:34Z",
"departure": "2023-05-28T07:16:39Z"
},
"load": [
2
],
"activities": [
{
"jobId": "PickupEvent_2",
"type": "pickup",
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"time": {
"start": "2023-05-28T07:16:34Z",
"end": "2023-05-28T07:16:39Z"
}
}
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"distance": 3411
},
{
"time": {
"arrival": "2023-05-28T07:21:30Z",
"departure": "2023-05-28T07:21:35Z"
},
"load": [
3
],
"activities": [
{
"jobId": "PickupEvent_7",
"type": "pickup",
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"time": {
"start": "2023-05-28T07:21:30Z",
"end": "2023-05-28T07:21:35Z"
}
}
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"distance": 5523
},
{
"time": {
"arrival": "2023-05-28T07:30:00Z",
"departure": "2023-05-28T07:30:05Z"
},
"load": [
4
],
"activities": [
{
"jobId": "PickupEvent_4",
"type": "pickup",
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"time": {
"start": "2023-05-28T07:30:00Z",
"end": "2023-05-28T07:30:05Z"
}
}
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"distance": 8722
},
{
"time": {
"arrival": "2023-05-28T07:36:15Z",
"departure": "2023-05-28T14:00:20Z"
},
"load": [
4
],
"activities": [
{
"jobId": "PickupEvent_1",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:00Z",
"end": "2023-05-28T07:50:05Z"
}
},
{
"jobId": "PickupEvent_2",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:05Z",
"end": "2023-05-28T07:50:10Z"
}
},
{
"jobId": "PickupEvent_7",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:10Z",
"end": "2023-05-28T07:50:15Z"
}
},
{
"jobId": "PickupEvent_4",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:15Z",
"end": "2023-05-28T07:50:20Z"
}
},
{
"jobId": "DropoffEvent_4",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:00Z",
"end": "2023-05-28T14:00:05Z"
}
},
{
"jobId": "DropoffEvent_7",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:05Z",
"end": "2023-05-28T14:00:10Z"
}
},
{
"jobId": "DropoffEvent_2",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:10Z",
"end": "2023-05-28T14:00:15Z"
}
},
{
"jobId": "DropoffEvent_1",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:15Z",
"end": "2023-05-28T14:00:20Z"
}
}
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"distance": 11767
},
{
"time": {
"arrival": "2023-05-28T14:08:47Z",
"departure": "2023-05-28T15:00:05Z"
},
"load": [
3
],
"activities": [
{
"jobId": "DropoffEvent_4",
"type": "delivery",
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"time": {
"start": "2023-05-28T15:00:00Z",
"end": "2023-05-28T15:00:05Z"
}
}
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"distance": 16119
},
{
"time": {
"arrival": "2023-05-28T15:11:42Z",
"departure": "2023-05-28T15:11:47Z"
},
"load": [
2
],
"activities": [
{
"jobId": "DropoffEvent_7",
"type": "delivery",
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"time": {
"start": "2023-05-28T15:11:42Z",
"end": "2023-05-28T15:11:47Z"
}
}
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"distance": 21927
},
{
"time": {
"arrival": "2023-05-28T15:16:58Z",
"departure": "2023-05-28T15:17:03Z"
},
"load": [
1
],
"activities": [
{
"jobId": "DropoffEvent_2",
"type": "delivery",
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"time": {
"start": "2023-05-28T15:16:58Z",
"end": "2023-05-28T15:17:03Z"
}
}
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"distance": 24039
},
{
"time": {
"arrival": "2023-05-28T15:21:02Z",
"departure": "2023-05-28T15:21:07Z"
},
"load": [
0
],
"activities": [
{
"jobId": "DropoffEvent_1",
"type": "delivery",
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"time": {
"start": "2023-05-28T15:21:02Z",
"end": "2023-05-28T15:21:07Z"
}
}
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"distance": 25734
},
{
"time": {
"arrival": "2023-05-28T15:25:04Z",
"departure": "2023-05-28T15:25:04Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T15:25:04Z",
"end": "2023-05-28T15:25:04Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 27179
}
],
"statistic": {
"cost": 169.13500000000002,
"distance": 27179,
"duration": 29827,
"times": {
"driving": 3669,
"serving": 80,
"waiting": 26078,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
},
{
"vehicleId": "bus_1",
"typeId": "bus",
"stops": [
{
"time": {
"arrival": "2023-05-28T06:00:00Z",
"departure": "2023-05-28T07:05:54Z"
},
"load": [
0
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T06:00:00Z",
"end": "2023-05-28T07:05:54Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 0
},
{
"time": {
"arrival": "2023-05-28T07:13:22Z",
"departure": "2023-05-28T07:13:27Z"
},
"load": [
1
],
"activities": [
{
"jobId": "PickupEvent_5",
"type": "pickup",
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"time": {
"start": "2023-05-28T07:13:22Z",
"end": "2023-05-28T07:13:27Z"
}
}
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"distance": 3861
},
{
"time": {
"arrival": "2023-05-28T07:21:26Z",
"departure": "2023-05-28T07:21:31Z"
},
"load": [
2
],
"activities": [
{
"jobId": "PickupEvent_3",
"type": "pickup",
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"time": {
"start": "2023-05-28T07:21:26Z",
"end": "2023-05-28T07:21:31Z"
}
}
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"distance": 7532
},
{
"time": {
"arrival": "2023-05-28T07:30:00Z",
"departure": "2023-05-28T07:30:05Z"
},
"load": [
3
],
"activities": [
{
"jobId": "PickupEvent_6",
"type": "pickup",
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"time": {
"start": "2023-05-28T07:30:00Z",
"end": "2023-05-28T07:30:05Z"
}
}
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"distance": 11071
},
{
"time": {
"arrival": "2023-05-28T07:46:23Z",
"departure": "2023-05-28T14:00:15Z"
},
"load": [
3
],
"activities": [
{
"jobId": "PickupEvent_5",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:00Z",
"end": "2023-05-28T07:50:05Z"
}
},
{
"jobId": "PickupEvent_3",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:05Z",
"end": "2023-05-28T07:50:10Z"
}
},
{
"jobId": "PickupEvent_6",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:10Z",
"end": "2023-05-28T07:50:15Z"
}
},
{
"jobId": "DropoffEvent_3",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:00Z",
"end": "2023-05-28T14:00:05Z"
}
},
{
"jobId": "DropoffEvent_6",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:05Z",
"end": "2023-05-28T14:00:10Z"
}
},
{
"jobId": "DropoffEvent_5",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:10Z",
"end": "2023-05-28T14:00:15Z"
}
}
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"distance": 18116
},
{
"time": {
"arrival": "2023-05-28T14:17:26Z",
"departure": "2023-05-28T15:00:05Z"
},
"load": [
2
],
"activities": [
{
"jobId": "DropoffEvent_6",
"type": "delivery",
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"time": {
"start": "2023-05-28T15:00:00Z",
"end": "2023-05-28T15:00:05Z"
}
}
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"distance": 25234
},
{
"time": {
"arrival": "2023-05-28T15:08:03Z",
"departure": "2023-05-28T15:08:08Z"
},
"load": [
1
],
"activities": [
{
"jobId": "DropoffEvent_3",
"type": "delivery",
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"time": {
"start": "2023-05-28T15:08:03Z",
"end": "2023-05-28T15:08:08Z"
}
}
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"distance": 29002
},
{
"time": {
"arrival": "2023-05-28T15:15:52Z",
"departure": "2023-05-28T15:15:57Z"
},
"load": [
0
],
"activities": [
{
"jobId": "DropoffEvent_5",
"type": "delivery",
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"time": {
"start": "2023-05-28T15:15:52Z",
"end": "2023-05-28T15:15:57Z"
}
}
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"distance": 32699
},
{
"time": {
"arrival": "2023-05-28T15:22:54Z",
"departure": "2023-05-28T15:22:54Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T15:22:54Z",
"end": "2023-05-28T15:22:54Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 36212
}
],
"statistic": {
"cost": 169.10000000000002,
"distance": 36212,
"duration": 29820,
"times": {
"driving": 4804,
"serving": 60,
"waiting": 24956,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}次のステップ
26 日前の更新
