回避オプションを使用した優先ルートを使用する
大規模なテリトリーに対する複雑な制約条件を持つ運行管理の車両ルート検索問題 (VRP) を構築する際、特定の車両による特定のエリアの訪問や特定の道路の使用を避けさせたい場合がよくあります。このような場合は、avoidオプションを使用します。これにより、問題に対してより正確な制約条件を設定でき、特定のプロパティに違反する特定の望ましくないルートや優先度の低いルートを車両に回避させることができます。
回避オプションを適用できるのは、場所の分布半径 (すべてのジョブの場所、車両の開始、終了、休憩場所を含む) が490 km未満の場合のみであることに注意してください。
回避機能
features- ルート計算から除外することが望ましいルート検索フィーチャーの配列。使用可能な回避フィーチャーのオプションは次のとおりです。tollRoad- 有料道路を回避motorway-高速道路または自動車道路を回避controlledAccessHighway- アクセス制御された高速道路を回避ferry- フェリーを回避carShuttleTrain- シャトルバスを回避tunnel- トンネルを回避dirtRoad- 未舗装道路を回避difficultTurns- 高速道路や自動車専用道路での難しいカーブ、急カーブ、Uターンを回避 (トラックのみ)uTurns- 高速道路や自動車専用道路でのUターンを回避 (トラックのみ)
たとえば、トンネルやアクセス制御された高速道路を回避するルートを作成するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"features": [
"tunnel",
"controlledAccessHighway"
]
}
}
]エリアを回避する
areas- ツアー中に訪問しないことが望ましい特定のエリアの配列。boundingBox型 (カンマ区切りのリストを使用して2つの緯度と2つの経度の値で定義される長方形のエリア) で指定します。north- 数値[ - 90~90] - ボックスの北の境界線を示す緯度 (WGS 84)。south- 数値[ - 90~90] - ボックスの南の境界線を示す緯度 (WGS 84)。west- 数値[ - 180~180] - ボックスの西の境界線を示す経度 (WGS 84)。east- 数値[ - 180~180] - ボックスの東の境界線を示す経度 (WGS 84)。
たとえば、地図上の特定のエリアを回避するルートを作成するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"areas": [
{
"type": "boundingBox",
"north": 52.523425044655696,
"south": 52.432243159759814,
"east": 13.435039860200588,
"west": 12.990627124745892
}
]
}
}
]地図セグメントを回避する
segments- 回避する特定の地図セグメント。各セグメント識別子エントリーの構造は次のとおりです。{segmentId}(#{direction})?。個々の部分は次のとおりです。segmentId-domain:system:type:idの形式で、カタログ内で参照されるトポロジーセグメントの識別子 (例:here:cm:segment:207551710)。セグメント識別子を取得する方法の詳細については、HERE Routing API v8開発者ガイドの「セグメントを回避する」を参照してください。direction(任意) - 双方向 (デフォルト) の場合は*、正方向の場合は+、負方向の場合は-のいずれか。
たとえば、地図の2つのセグメントを回避するルートを作成するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"segments": [
"here:cm:segment:207551710#+",
"here:cm:segment:76771992#*"
]
}
}
]リクエスト1回のペナルティ対象セグメントの最大数は250を超えないようにしてください。「ペナルティ対象セグメント」とは、最大baseSpeedがmaxSpeedOnSegmentで制限されているセグメント、またはavoid[segments]で回避されているセグメントを指します。
ゾーンIDを回避する
zoneIdentifiers- 回避する特定の地図ゾーン。ルートでの通過を回避するルート検索ゾーン識別子 (domain:system:type:idの形式) の配列。たとえば、識別子here:cm:envzone:2は、Berlin Umweltzone環境ゾーンを参照します。
回避の設定に使用するゾーンIDを取得する方法の1つは、レスポンスメッセージのroutingZoneブロックからゾーンIDを取得することです。詳細については、「ルート検索ゾーン」を参照してください。
一般的に、さまざまな地図ゾーンに関する情報はplatform.here.comの各カタログから取得できます。プラットフォームカタログへのアクセス権がない場合は、上述のルート検索レスポンスを使用できます。
たとえば、地図の特定のゾーンを回避するルートを作成するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"zoneIdentifiers": [
"here:cm:envzone:2"
]
}
}
]トラック道路タイプを回避する
truckRoadTypes- 大型車両の通行に関する追加規制が適用される、トラックが回避する必要がある特定の道路タイプ。たとえば、スウェーデンのBK (Bearing Class) 規制、メキシコのETカテゴリーなどです。詳細については、「Truck Road Type」(トラック道路タイプ) を参照してください。
たとえば、3つの特定の道路を回避するルートを作成するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"truckRoadTypes": [
"BK1",
"BK2",
"BK3"
]
}
}
]ゾーンカテゴリーを回避する
zoneCategories- 回避する特定の地図ゾーンカテゴリーと地図ゾーン。回避するゾーンカテゴリーの評価で考慮しないゾーン識別子の配列。categories- 回避するルート検索ゾーンカテゴリーの配列。exceptZoneIds- 回避するゾーンカテゴリーの評価で考慮しないゾーン識別子の配列。
たとえば、3つの特定のゾーンカテゴリーを回避するルートを作成するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"zoneCategories": {
"categories": [
"vignette",
"congestionPricing",
"environmental"
]
}
}
}
]回避されたゾーンカテゴリー内の一部のゾーンへのアクセス権が付与されている場合、任意のexceptZoneIdsカテゴリーを使用して、domain:system:type:idの形式でルート検索ゾーン識別子の配列を指定してルートを計画できます。詳細については、「ルート検索ゾーン」を参照してください。
たとえば、特定のゾーンカテゴリーを回避するルートを作成し、一部のゾーンを回避オプションから除外するには、問題の運行管理部分にある車両の制約条件に以下を追加します。
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"zoneCategories": {
"categories": [
"vignette"
],
"exceptZoneIds": [
"here:cm:envzone:2",
"here:cm:envzone:261"
]
}
}
}
]avoidオプションを使用しても、車両が特定のエリアや道路を訪問するのを完全に回避できませんが、回避されていないエリアを通過するルートが優先されます。
以下では、ツアーを計画する際にareasとfeaturesを回避するの2つの異なる例を検討します。
エリアを回避する例
以下の簡単な例で、4つのジョブを実行する車両について考えてみましょう。ツアーを遂行する際、車両は制約により問題の運行管理部分に追加されたboundingBoxに含まれる座標 (52.523425044655696、52.432243159759814、13.435039860200588、12.990627124745892) で指定された特定のエリアを回避する必要があります。
planの部分からわかるように、ジョブの場所はどれもboundingBox内には直接ありませんが、ジョブ間のルートは確実にこのエリアを通過します。そのため、以下の方法で問題を構築すると代替ルートが作成され、車両はその特定のエリアを回避します。
問題
{
"fleet": {
"types": [
{
"id": "2759a4c35b01",
"profile": "truck_1",
"costs": {
"fixed": 9.0,
"distance": 0.002,
"time": 0.009
},
"shifts": [
{
"start": {
"time": "2022-07-22T08:49:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
},
"end": {
"time": "2022-07-22T19:49:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
}
}
],
"capacity": [
50
],
"amount": 1
}
],
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"areas": [
{
"type": "boundingBox",
"north": 52.523425044655696,
"south": 52.432243159759814,
"east": 13.435039860200588,
"west": 12.990627124745892
}
]
}
}
]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.61233361982292,
"lng": 13.378211244312677
},
"duration": 135
}
],
"demand": [
14
]
}
]
}
},
{
"id": "job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.396871659783336,
"lng": 13.05446681343765
},
"duration": 516
}
],
"demand": [
7
]
}
]
}
},
{
"id": "job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.39394204075849,
"lng": 13.082571195347363
},
"duration": 571
}
],
"demand": [
9
]
}
]
}
},
{
"id": "job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.387946983417116,
"lng": 13.066284687565254
},
"duration": 378
}
],
"demand": [
6
]
}
]
}
}
]
}
}ソリューション
ジョブが割り当てられ、ルートが作成されると、総合的なコスト、距離、所要時間などのツアー全体の統計情報を確認できます。なお、このデータは、回避オプションに含まれているエリアを回避した結果、走行距離がより長いツアーになることを考慮して計算されたものです。
{
"statistic": {
"cost": 464.185,
"distance": 157451,
"duration": 15587,
"times": {
"driving": 13987,
"serving": 1600,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "2759a4c35b01_1",
"typeId": "2759a4c35b01",
"stops": [
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2022-07-22T08:49:00Z",
"departure": "2022-07-22T08:49:00Z"
},
"load": [
36
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.39394204075849,
"lng": 13.082571195347365
},
"time": {
"arrival": "2022-07-22T10:11:47Z",
"departure": "2022-07-22T10:21:18Z"
},
"load": [
27
],
"activities": [
{
"jobId": "job_3",
"type": "delivery"
}
],
"distance": 61552
},
{
"location": {
"lat": 52.38794698341712,
"lng": 13.066284687565254
},
"time": {
"arrival": "2022-07-22T10:28:36Z",
"departure": "2022-07-22T10:34:54Z"
},
"load": [
21
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
],
"distance": 63931
},
{
"location": {
"lat": 52.396871659783336,
"lng": 13.05446681343765
},
"time": {
"arrival": "2022-07-22T10:41:27Z",
"departure": "2022-07-22T10:50:03Z"
},
"load": [
14
],
"activities": [
{
"jobId": "job_2",
"type": "delivery"
}
],
"distance": 65802
},
{
"location": {
"lat": 52.61233361982292,
"lng": 13.378211244312675
},
"time": {
"arrival": "2022-07-22T12:29:14Z",
"departure": "2022-07-22T12:31:29Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 145670
},
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2022-07-22T13:08:47Z",
"departure": "2022-07-22T13:08:47Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 157996
}
],
"statistic": {
"cost": 464.185,
"distance": 157451,
"duration": 15587,
"times": {
"driving": 13987,
"serving": 1600,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}回避オプションを使わない場合
上の結果を、同じ問題でavoidオプションを使用しない場合と比較してみましょう。fleetの部分からavoidオプションを削除して、同じ問題を解決しようとした場合、エリアの制限なしでルートが作成されることが予想されるため、ツアーの全体的な統計情報は異なるはずです。
問題
{
"fleet": {
"types": [
{
"id": "2759a4c35b01",
"profile": "truck_1",
"costs": {
"fixed": 9.0,
"distance": 0.002,
"time": 0.009
},
"shifts": [
{
"start": {
"time": "2022-07-22T08:49:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
},
"end": {
"time": "2022-07-22T19:49:00Z",
"location": {
"lat": 52.530971,
"lng": 13.384915
}
}
}
],
"capacity": [
50
],
"amount": 1
}
],
"profiles": [
{
"type": "truck",
"name": "truck_1"
}
]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.61233361982292,
"lng": 13.378211244312677
},
"duration": 135
}
],
"demand": [
14
]
}
]
}
},
{
"id": "job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.396871659783336,
"lng": 13.05446681343765
},
"duration": 516
}
],
"demand": [
7
]
}
]
}
},
{
"id": "job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.39394204075849,
"lng": 13.082571195347363
},
"duration": 571
}
],
"demand": [
9
]
}
]
}
},
{
"id": "job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.387946983417116,
"lng": 13.066284687565254
},
"duration": 378
}
],
"demand": [
6
]
}
]
}
}
]
}
}ソリューション
以下のソリューションからわかるように、ツアーの総距離は、avoidオプションが使用された以前のソリューションでは157,451mであったのに対し、97,776mになりました。そのため、ツアーの所要時間とコストも減少しました。これは、車両が特定のエリアを訪問することを制限せずにツアーが作成され、アルゴリズムがジョブの遂行に最適なルートを選択したことを意味します。
{
"statistic": {
"cost": 301.95,
"distance": 97776,
"duration": 10822,
"times": {
"driving": 9222,
"serving": 1600,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "2759a4c35b01_1",
"typeId": "2759a4c35b01",
"stops": [
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2022-07-22T08:49:00Z",
"departure": "2022-07-22T08:49:00Z"
},
"load": [
36
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.39394204075849,
"lng": 13.082571195347365
},
"time": {
"arrival": "2022-07-22T09:32:23Z",
"departure": "2022-07-22T09:41:54Z"
},
"load": [
27
],
"activities": [
{
"jobId": "job_3",
"type": "delivery"
}
],
"distance": 12006
},
{
"location": {
"lat": 52.38794698341712,
"lng": 13.066284687565254
},
"time": {
"arrival": "2022-07-22T09:49:12Z",
"departure": "2022-07-22T09:55:30Z"
},
"load": [
21
],
"activities": [
{
"jobId": "job_4",
"type": "delivery"
}
],
"distance": 52603
},
{
"location": {
"lat": 52.396871659783336,
"lng": 13.05446681343765
},
"time": {
"arrival": "2022-07-22T10:02:03Z",
"departure": "2022-07-22T10:10:39Z"
},
"load": [
14
],
"activities": [
{
"jobId": "job_2",
"type": "delivery"
}
],
"distance": 54982
},
{
"location": {
"lat": 52.61233361982292,
"lng": 13.378211244312675
},
"time": {
"arrival": "2022-07-22T11:09:49Z",
"departure": "2022-07-22T11:12:04Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 56853
},
{
"location": {
"lat": 52.530971,
"lng": 13.384915
},
"time": {
"arrival": "2022-07-22T11:49:22Z",
"departure": "2022-07-22T11:49:22Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 96591
}
],
"statistic": {
"cost": 301.95,
"distance": 97776,
"duration": 10822,
"times": {
"driving": 9222,
"serving": 1600,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}回避フィーチャーの例
以下の簡単な例で、車両が2つのジョブを遂行する際にトンネルを回避する必要がある場合を考えてみましょう。以下の問題の運行管理部分では、車両truck_1にavoidオプションを追加し、featuresでtunnelを指定しました。最短ルートはトンネルを通るルートですが、車両が2つのジョブ間で代替ルートを選択することが予想されます。
問題
{
"fleet": {
"types": [
{
"id": "2759a4c35b01",
"profile": "truck_1",
"costs": {
"fixed": 9.0,
"distance": 0.002,
"time": 0.009
},
"shifts": [
{
"start": {
"time": "2022-07-22T08:49:00Z",
"location": {
"lat": 52.524021669858236,
"lng": 13.346234778981403
}
},
"end": {
"time": "2022-07-22T19:49:00Z",
"location": {
"lat": 52.524021669858236,
"lng": 13.346234778981403
}
}
}
],
"capacity": [
50
],
"amount": 1
}
],
"profiles": [
{
"type": "truck",
"name": "truck_1",
"avoid": {
"features": [
"tunnel"
]
}
}
]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.534591259017255,
"lng": 13.368714336895204
},
"duration": 215
}
],
"demand": [
11
]
}
]
}
},
{
"id": "job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.48682246237135,
"lng": 13.373210248775834
},
"duration": 135
}
],
"demand": [
14
]
}
]
}
}
]
}
}ソリューション
ジョブが割り当てられ、ルートが作成されると、総合的なコスト、距離、所要時間などのツアー全体の統計情報を確認できます。なお、このデータは、回避オプションに含まれているトンネルを回避した結果、走行距離がより長いツアーになることを考慮して計算されたものです。以下の例を確認して、avoidオプションを削除した後のソリューションと比較してください。
{
"statistic": {
"cost": 84.50899999999999,
"distance": 18202,
"duration": 4345,
"times": {
"driving": 3995,
"serving": 350,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "2759a4c35b01_1",
"typeId": "2759a4c35b01",
"stops": [
{
"location": {
"lat": 52.52402166985824,
"lng": 13.346234778981405
},
"time": {
"arrival": "2022-07-22T08:49:00Z",
"departure": "2022-07-22T08:49:00Z"
},
"load": [
25
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.534591259017255,
"lng": 13.368714336895204
},
"time": {
"arrival": "2022-07-22T09:05:29Z",
"departure": "2022-07-22T09:09:04Z"
},
"load": [
14
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 4143
},
{
"location": {
"lat": 52.48682246237135,
"lng": 13.373210248775834
},
"time": {
"arrival": "2022-07-22T09:37:12Z",
"departure": "2022-07-22T09:39:27Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_2",
"type": "delivery"
}
],
"distance": 11832
},
{
"location": {
"lat": 52.52402166985824,
"lng": 13.346234778981405
},
"time": {
"arrival": "2022-07-22T10:01:25Z",
"departure": "2022-07-22T10:01:25Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 18196
}
],
"statistic": {
"cost": 84.50899999999999,
"distance": 18202,
"duration": 4345,
"times": {
"driving": 3995,
"serving": 350,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}回避フィーチャーを使わない場合
上の結果を、同じ問題でavoidオプションを使用しない場合と比較してみましょう。fleetの部分からavoidオプションを削除して、同じ問題を解決しようとした場合、制限なしでルートが作成されることが予想されるため、車両はトンネルを通過でき、ツアーの全体的な統計情報は異なるはずです。
問題
{
"fleet": {
"types": [
{
"id": "2759a4c35b01",
"profile": "truck_1",
"costs": {
"fixed": 9.0,
"distance": 0.002,
"time": 0.009
},
"shifts": [
{
"start": {
"time": "2022-07-22T08:49:00Z",
"location": {
"lat": 52.524021669858236,
"lng": 13.346234778981403
}
},
"end": {
"time": "2022-07-22T19:49:00Z",
"location": {
"lat": 52.524021669858236,
"lng": 13.346234778981403
}
}
}
],
"capacity": [
50
],
"amount": 1
}
],
"profiles": [
{
"type": "truck",
"name": "truck_1"
}
]
},
"plan": {
"jobs": [
{
"id": "job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.534591259017255,
"lng": 13.368714336895204
},
"duration": 215
}
],
"demand": [
11
]
}
]
}
},
{
"id": "job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 52.48682246237135,
"lng": 13.373210248775834
},
"duration": 135
}
],
"demand": [
14
]
}
]
}
}
]
}
}ソリューション
以下のソリューションからわかるように、ツアーの総距離は、トンネルを回避してルートが作成された以前のソリューションでは18,202mであったのに対し、17,017mになりました。そのため、ツアーの所要時間とコストも減少しました。
{
"statistic": {
"cost": 77.918,
"distance": 17017,
"duration": 3876,
"times": {
"driving": 3526,
"serving": 350,
"waiting": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "2759a4c35b01_1",
"typeId": "2759a4c35b01",
"stops": [
{
"location": {
"lat": 52.52402166985824,
"lng": 13.346234778981405
},
"time": {
"arrival": "2022-07-22T08:49:00Z",
"departure": "2022-07-22T08:49:00Z"
},
"load": [
25
],
"activities": [
{
"jobId": "departure",
"type": "departure"
}
],
"distance": 0
},
{
"location": {
"lat": 52.534591259017255,
"lng": 13.368714336895204
},
"time": {
"arrival": "2022-07-22T09:05:29Z",
"departure": "2022-07-22T09:09:04Z"
},
"load": [
14
],
"activities": [
{
"jobId": "job_1",
"type": "delivery"
}
],
"distance": 4143
},
{
"location": {
"lat": 52.48682246237135,
"lng": 13.373210248775834
},
"time": {
"arrival": "2022-07-22T09:29:23Z",
"departure": "2022-07-22T09:31:38Z"
},
"load": [
0
],
"activities": [
{
"jobId": "job_2",
"type": "delivery"
}
],
"distance": 10649
},
{
"location": {
"lat": 52.52402166985824,
"lng": 13.346234778981405
},
"time": {
"arrival": "2022-07-22T09:53:36Z",
"departure": "2022-07-22T09:53:36Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival"
}
],
"distance": 17013
}
],
"statistic": {
"cost": 77.918,
"distance": 17017,
"duration": 3876,
"times": {
"driving": 3526,
"serving": 350,
"waiting": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}次のステップ
詳細については、以下を参照してください。
- Submit a Vehicle Routing Problem to solve it synchronously (車両ルート検索問題を送信して同期的に解決する)
- Submit a Vehicle Routing Problem to solve it asynchronously (車両ルート検索問題を送信して非同期的に解決する)
26 日前の更新