事前に計算された経路探索はまだ関連していますか?


12

環境

Old Lucas Arts(ScummVM時代)のポイントアンドクリックグラフィックアドベンチャーゲームは、事前に計算された経路探索を使用していました。テクニックの大まかな概要は次のとおりです。

ステップ1

各部屋の床は「ウォークボックス」と呼ばれるものに分割され、ナビゲーションメッシュのノードとほぼ同等でしたが、台形に限定されていました。例えば:

 ______ _____ _________ _____
\   A  |  B  |    C    |  D   \
 \_____|     |         |_______\
       |_____|         |
             |_________|

ステップ2

オフラインアルゴリズム(ダイクストラやA *など)は、ノードの各ペア間の最短パスを計算し、使用される開始ノードと終了ノードによって各次元でインデックス付けされた2Dマトリックスにパスの最初のステップを格納ます。たとえば、上記のウォークボックスを使用します。

      ___ ___ ___ ___
     | A | B | C | D | <- Start Node
  ___|___|___|___|___|
 | A | A | A | B | C |  ---
 |___|___|___|___|___|     |
 | B | B | B | B | C |     |
 |___|___|___|___|___|     |-- Next node in shortest path
 | C | B | C | C | C |     |   from Start to End
 |___|___|___|___|___|     | 
 | D | B | C | D | D |  ---
 |___|___|___|___|___| 
   ^
   |
End Node

ご想像のとおり、ノードの数が増えると(N ^ 2)メモリ要件が急速に増加します。通常、ショートはマトリックス内の各エントリを格納するのに十分な大きさであり、300ノードの複雑なマップを使用すると、余分に格納されることになります。

300^2 * sizeof(short) = 176 kilobytes

ステップ3

一方、2つのノード間の最短パスの計算は非常に高速で簡単であり、マトリックスへの一連のルックアップだけでした。何かのようなもの:

// Find shortest path from Start to End
Path = {Start}
Current = Start
WHILE Current != End
    Current = LookUp[Current, End]
    Path.Add(Current)
ENDWHILE

この単純なアルゴリズムを適用して、CからAへの最短経路を見つけます。

1) Path = { C }, Current = C
2) Path = { C, B }, Current = B
3) Path = { C, B, A }, Current = A, Exit

質問

あらゆるレベルでこれを行うためのメモリ要件と相まって、今日の強力なハードウェアでは、実行時に単にA *を実行することで、この手法がかつて持っていたすべての利点を上回ると思われます。

また、最近のメモリ検索は一般的な計算よりも遅いかもしれないと聞いたことがあります。これがサインとコサインのルックアップテーブルの作成が一般的ではなくなった理由です。

しかし、これらの低レベルのハードウェア効率の問題についてはまだあまり知識がないことを認めなければならないので、この機会を利用して、このテーマに精通している人々の意見を聞いています。

私のエンジンでは、実行時にグラフにノードを動的に追加および削除する機能も必要だったので(これを参照)、事前に計算されたルートだけがより複雑になったため、それを廃棄しました(もちろん、ランタイムA *ソリューションはすでに完全に実行されていました)。それでも、私は疑問に思っていました...

結論として、この手法は現在でもどのシナリオでも関連していますか?


2
CPUの予算が限られている場合でも、それはまだ関係があると思います。しかし、動的なパスが必要になったら、それはもはや役に立ちません。ところで、A *アルゴリズムをどこから取得したかを見たところ、minheapやその他のトリックを使用してさらに最適化できます。ここで見ることができるC#でA *を改善するためにいくつかの反復を行いました:roy-t.nl/index.php/2011/09/24/…は役に立つかもしれません。
ロイT.11年

1
おかげで、私はそれをブックマークしており、アプリケーションの最適化を開始するときに調査します。私はEric Lippertのソリューションをいくつかの小さな変更を加えて使用しましたが、それはとてもきれいで従うのが簡単だったからです...そして、すべてのテストケースでほぼ瞬時に実行されたので、最適化することさえしませんでした。
デヴィッド

1
ところで、もしあなたが事前計算を追求することに決めたなら、あなたはFloyd-Warshallアルゴリズムを見たいと思うかもしれません。Dijkstra / A *を繰り返し使用するよりも効率的に「次のステップ」マトリックスを構築します。
amitp

@amitpヒントをありがとう、これらの代替案について知ることは常に良いことです!ただし、ほとんどの場合、事前計算はオフラインで実行されるため、より効率的にすることで得られることはあまりありません。あなたが本当にせっかちでない限り。:-)
デヴィッドゴーベイア

同意しましたが、Floyd-Warshallもダイクストラのアルゴリズムよりも実装がはるかに簡単ですので、ダイクストラの実装をまだ持っていない場合は、一見の価値があります:)
amitp

回答:


3

私のエンジンでは、実行時にグラフにノードを動的に追加および削除する機能も必要でした(これを参照) )。それでも、私は疑問に思っていました...

結論として、この手法は現在でもどのシナリオでも関連していますか?

このような手法を使用してもメリットはありません。

グラフの柔軟性がありません(異なるLODを使用できますが、特定の形状である必要はありません、など)。また、エンジンのユーザーは、グラフとは何か、グラフを使用する方法を知っています。したがって、追加の機能を追加する場合は、まったく新しい状況を使用して拡張機能を実装する方法を学習する必要があります。

あなたが言及したように、それは恐ろしくスケーリングするように見えます。また、グラフがキャッシュに収まり、すべてのパス結果を連続して実行すると、IO時間を本当に削減できることに注意してください。実装はすぐに大きくなりすぎて、どのキャッシュにも収まらないようです。

また、最近のメモリ検索は一般的な計算よりも遅いかもしれないと聞いたことがあります。これがサインとコサインのルックアップテーブルの作成が一般的ではなくなった理由です。

すべてのプログラムとその必要なメモリをキャッシュに収めることができない限り、プロセッサをボトルネックする前に、メモリに物を出し入れするボトルネックになります。

あらゆるレベルでこれを行うためのメモリ要件と相まって、今日の強力なハードウェアでは、実行時に単にA *を実行することで、この手法がかつて持っていた利点を上回ると思われます

また、多くのゲームにはAIを更新するための個別のループがあることに注意してください。私のプロジェクトの設定方法は、60hzでユーザー入力の更新ループがあり、AIが20hzであり、ゲームができるだけ早く描画することだと思います。

また、サイドノートとして、GBAプログラミングを楽しみのためだけに行いましたが、最新のデバイスを使用することはまったくありませんでした。GBAの場合、すべてがプロセッサのワークロードを最小化することでした(それは哀れなため)。また、ほとんどの高水準言語C#およびJava(C ++またはCほどではない)が大量の最適化を行うことを認識する必要があります。コードの最適化に関しては、メモリへのアクセスをできるだけ少なくすることと、キャッシュからバンプする新しいメモリを取り込む前に可能な限り多くの計算を実行すること以外に行うことはあまりありません一度だけ物事を行う。

編集:また、タイトルに答えるためにはいです。頻繁に使用されるパスの事前計算は優れたアイデアであり、ゲームループ外のどこでもA *で実行できます。たとえば、RTSのリソースをベースにして、ギャザーが退出または戻りたいたびに再計算する必要がないようにします。


編集については、頻繁に使用するパスの事前計算についてではなく、可能なすべてのパスを事前計算する方法の概要についてのみ説明しました。また、事前に計算されたパスファインディングを使用することにあなたの答えのほとんどがどのように反対しているかについて少し混乱していますが、最後にあなたはそれが素晴らしいアイデアだと言いました。それでは、GBAなどのCPUが制限された環境で役立ちますか?
デヴィッドゴーベイア

1
私の悪い点は、文脈から抜き取ったあなたのタイトルへの答えはイエスであると指摘しようとしていました。あなたの質問に記載されている特定のアルゴリズムに関連する答えはノーです。したがって、短いすべての可能なパスを事前に計算することは悪い考えですが、非常に頻繁に使用されるいくつかのパスを事前に計算することは良い考えです。
ClassicThunder

2
@ClassicThunder:数から事前計算すべてのパスのこの技術のランドマークは、しばしばと呼ばれるALTランドマーク&三角不等式を有するA-スターcs.princeton.edu/courses/archive/spr06/cos423/Handouts/GW05。 pdf
Pieter Geerkens
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.