検索アルゴリズム -- ジャンプポイント検索

編集者: トニー

日付: 2021-12-30


注: この記事では主に JPS アルゴリズムの原理を紹介します

1. 背景

JPS (ジャンプ ポイント検索) アルゴリズムは、実際には A* パスファインディング アルゴリズムを改良したものであるため、この記事を読む前に A* アルゴリズムを理解する必要があります。 A* アルゴリズムは、ノードを拡張するときにノードのすべての隣接ノードを考慮するため、オープンリスト内のポイントの数が多くなり、検索効率が遅くなります。

オクルージョンがない場合 (複数の等コスト パスが存在することがよくあります)、始点から終点までのパスのうち 1 つだけが選択されることを望み、このパスの外側にある他のノードは不必要にオープンリストに入れられる可能性があります。 (不必要な近隣ノードを追加したくありません)。

 

第二に、直線の途中の点をオープンリストに入れる必要がないことも望んでいます。各直線のサブパスの始点と終点のみを入れれば、オープンリストは不要な部分を大幅に節約できます。ノード:

 

JPS アルゴリズムで検索されたノードは常に「ジャンプ」していることがわかりますが、これはこれらのキー ノードが歩行方向を変える必要がある変曲点であるためであり、これが Jump Point という名前の由来でもあります。

2. コンセプト

自然隣接 : 図に示すように、赤いブロックは自然隣接です。

強制隣接 : 点 x の 8 つの隣接点の間に障害物があり、n は x の自然な隣接点ではなく、親ノード p(x) は x にあります。 x が x を通過する n までの距離コストが、x を通過しない n までのパスの距離コストより小さい場合、n は x の強制近傍であると言われます。これは p(x) の記述を意味します。最も完全な式は、x の親ノードが p(x) であるとき、n が x の強制近傍であるということです。図を参照してください。

ジャンプ ポイント : 点 x (現在の点は x)、検索方向は d (斜め、水平、または垂直) に基づいて、点 y は次の条件を満たします。次の 3 つの条件のいずれかの場合、y がジャンプポイントになります。
a. ノード y が終了点であり、ノード y がジャンプ点です。
b. ノード y に少なくとも 1 つの強制ネイバーがある場合、ノード y はホップ ポイントになります。
c. d が斜め探索の場合、ノード y の水平方向または垂直方向に条件 a、b を満たす点があれば、ノード y がジャンプ点となります。注: ノード y の水平方向または垂直方向は、斜めベクトルの分解です。たとえば、ベクトル d=(1,1) の場合、水平方向は (1,0) になります。左方向への検索は行われません。ベクトル d=(-1,-1) の場合、水平方向は (-1,0) となり、左側のみが検索され、右側は見られません。 . 他も同様です。

赤いブロックは自然な隣接ブロック、黒いブロックは障害物、緑のブロックは強制的な隣接ブロックです。

黒色のブロックは障害物を表し、オレンジ色のブロックは現在のノード (カレント) を表し、緑色のブロックは前のポイント (親) を表し、黄色のカラー ブロックは現在のノードの強制ネイバーを表します。親ノードから現在のノードまで水平にジャンプします。このとき、現在のノードの上部は障害物によってブロックされ、パスが形成されます。強制ネイバーになります。親ノードから強制隣接ノードへ。 ホップ ポイント これは親ノードと強制隣接ノード間の最短パスとなり、現在のノードは親ノードからの現在の

現在のノードの上にある障害物を取り除くと、下図のように別の最短経路が存在しますが、このとき、黄色のブロックは現在のノードのForced Neighborとは言えません。

 前述したように、親ノードから現在のノードへのプロセスは ジャンプ と呼ばれ、 斜めジャンプ。直線ジャンプは、図に示すように、水平ジャンプ用と垂直ジャンプ用に分けられます。下の図では、オレンジ色の矢印は直線ジャンプを示し、紫色の矢印は斜めジャンプを示します。一般的には、最初に直線的にジャンプし、次に斜めにジャンプします。直線ジャンプ時に障害物や境界線に到達すると親に戻って斜めジャンプを行い、斜めジャンプ後のノードが障害物や境界線になるとジャンプが停止します。

定義:強制ネイバーを持つノードはホップです。もちろんこの定義は厳密なものではなく、下図のように緑色のノードがオープンリストから出てくるノードで、そのノードから青色の親ノードまで斜めにジャンプし、親ノードから現在のノードまで真っ直ぐジャンプするというものです。 current には Forced Neighbor があることがわかり、current はジャンプ ポイントですが、ノードから current に直接ジャンプすることはできず、親を経由するため、親もジャンプ ポイントになります。したがって、定義を続けます。ノード x が前のノードからの対角ジャンプによって取得され、x からの線形ジャンプによって取得された現在のノードがジャンプ ポイントである場合、ノード x もジャンプ ポイントになります。 a>。

3. アルゴリズム原理

  • 水平検索

 

 

 

  • 斜め探索

 

  • 原理と手法

JPS アルゴリズムは A* アルゴリズムと非常によく似ており、手順は大まかに次のとおりです。

  1. Openlist は重みが最も低いノードを取得し、検索を開始します。 (A*と同じです)
  2. 検索する場合は、まず直線検索(4/8方向、ジャンプ検索)を実行してから斜め検索 (4 方向、検索は 1 ステップのみ)。探索中に特定の方向でジャンプポイントが見つかったり障害物(または境界)に遭遇した場合、探索は現在の方向で終了し、ジャンプポイントが見つかった場合はオープンリストに追加されます。
ジャンプ探索とは、ジャンプポイントまたは障害物(境界)が見つかるまで、直線に沿って探索することを指します(多数のグリッドを探索する場合もあります)。最初にスタート地点から探索すると、直線方向は上下左右の 4 方向となり、斜め 4 方向すべてに 1 歩進むと直線方向は 8 方向になります。
  1. 斜め方向の探索が完了していない場合は、斜め方向に 1 歩進み、上記の処理を繰り返します。
直線方向はジャンプサーチなので必ず検索が完了します。
  1. 検索が全方向で完了した場合、現在のノードが検索されたとみなされ、現在のノードはオープンリストから削除され、クローズリストに追加されます。
  2. オープンリストが空になるか、エンドポイントが見つかるまで、オープンリストの重みが最も低いノードの検索を繰り返します。

次の図は、プロセス 2 と 3 をわかりやすく説明するために使用されます: まず、検索の開始としてオープンリストから緑色のノードを取り出します。最初に直線検索を実行し、次に斜め検索を実行します。ジャンプ ポイントは見つかりません。

4. 実験結果

  • 障害物に遭遇しない斜め方向の探索

 

  • 斜めの探索で障害物に遭遇する

 

  • シーン - 200 * 400 サイズのマップ

 

  • 各経路探索アルゴリズムの性能データ比較の参考

 

5. JPS+を展開する

  • 原理と手法

JPS+ (Jump Point Search Plus) は基本的に JPS パスファインディングですが、前処理を追加して改善し、パスファインディングを高速化します。

まず、マップの各ノードでジャンプ ポイント判定を実行し、すべての主要なジャンプ ポイントを見つけます。

次に、各ノードのジャンプ ポイントの直線到達可能性を判断し、ジャンプ ポイントの直線到達可能性を記録します。

到達可能な場合は、番号ジャンプ ポイントの直線距離を記録する必要があります。

同様に、各ノードの傾斜距離を記録します。

残りの方向のデータがジャンプポイントに到達できない場合は、0 または負の距離として記録されます。対応する方向に 1 歩移動した後に障害物 (または境界) に遭遇した場合は、0 として記録されます。n+1 歩移動した後に障害物 (または境界) に遭遇した場合、データは負の距離 -n として記録されます。

最後に、各ノードの 8 つの方向が記録され、JPS+ の前処理プロセスが完了します。

上記の前処理プロセスでは、地図上の各グリッドの 8 方向の衝突またはジャンプ ポイントからの距離を格納するデータ構造が必要です。

  • プロセス例

マップを前処理した後、JPS+ アルゴリズムを使用できるようになります。一般的な考え方は JPS アルゴリズムと同じですが、今回は前処理されたデータを使用することで、 直線検索

特定の検索方向には次のようなものがあります。

  • 正の距離 n (ジャンプ ポイントから n ブロック離れていることを意味します) の場合、n ステップ離れたノードをジャンプ ポイントとしてオープンリストに直接追加できます。
  • 距離が 0 (まったく移動がないことを意味する) の場合、その方向に検索する必要はありません。
  • 負の距離 -n (境界または障害物から n ブロック離れていることを意味します) の場合、n ステップ離れたノードでジャンプ ポイントの判断を直接行います (ジャンプ ポイントの 3 番目の条件を満たすことは可能ですが、前処理のおかげで)データがある場合は、この手順もすぐに完了できます)。

以下の図に示すように、開始ノードは、以前のように 3 ステップを繰り返す (そして各ステップでジャンプするかどうかを判断する) 必要がなく、記録された上方向の距離を通じて 3 ステップ離れたジャンプ ポイントをオープンリストに直接追加します。

他のプロセスも同様です。

 

 

 

  • 要約する

JPS/JPS+ アルゴリズムでは、多数の不要なポイントを除いて、ジャンプ ポイントのみがオープンリストに追加され、最終的に見つかった最短パスもジャンプ ポイントで構成されていることがわかります。これは、JPS/JPS+ が効率的である主な理由でもあります。

JPS

  • ほとんどのマップでは、JPS アルゴリズムは A* アルゴリズムよりも高速で、使用するメモリも少なくなります (オープンリスト内のノードの数がはるかに少なくなります)。
  • JPS ジャンプ ポイントを判断するときは、過度の再帰の深さを避けるようにしてください (または将来、再帰を回避するアルゴリズムの出現に期待してください)。そうしないと、非常に大きなマップでのジャンプ ポイントの再帰判断が悲惨な結果を引き起こす可能性があります。
  • JPS は地図を動的に変更する場合にも使用できますが、地図が変更されるたびに JPS 検索が必要になります。
  • JPS は本来、ノードをマージする(つまり、途中の不要なノードを直線的に削除する)機能を持っていますが、まだマージが続けられる箇所がいくつかあります。
  • JPS はグリッド ノード タイプでのみ動作し、Navmesh やウェイ ポイントをサポートしません。

JPS+

  • JPS アルゴリズムと比較して、JPS+ は 1 レベル高速です (特に再帰的判断ジャンプ ポイントの複数の層を回避するという点で) メモリ使用量は、各グリッドが 8 つの追加方向の距離データを記録する必要があることです。
  • JPS+ アルゴリズムには前処理プロセスが含まれているため、動的に変化するマップに対処する際に固有の欠点があるため (動的マップはほとんど受け入れられません)、静的マップにより適しています。
  • JPS+ 预处理的复杂度为 O(n) ,n 代表地图格子数。
アルゴリズム パフォーマンス メモリ使用量 ダイナミックマップをサポート 前処理 サポートノードタイプ
あ* 中くらい 大きい サポート なし メッシュ、ナビメッシュ、パスポイント
JPS 素早い 小さい サポート なし グリッド
JPS+ とても早い 中くらい サポートしません はい、O(n) グリッド

要約すると、JPS/JPS+ は A* アルゴリズムに代わる優れた代替手段であり、ほとんどの場合、より高速でメモリ フットプリントが小さいだけで十分魅力的です。 GDC 2015 での JPS+ アルゴリズムに関する講演で、Steve Rabin は、A* アルゴリズムよりも 70 ~ 350 倍も高速なデータを提供しました。

6. 参考資料

おすすめ

転載: blog.csdn.net/fightingTony/article/details/122251631
おすすめ