パスファインディングにおける状況認識


11

たとえば、ロックされたドアや鍵など、特定のアイテムが収集された後にのみ特定の通路が開かれるダンジョンを通る最短の道を見つけなければならなかったとします。

「最短経路」という言葉に対する通常の腸の反応は明らかにA *です。しかし、A *はこのような環境では失敗します。信頼できるヒューリスティックを定義する多くの問題があり、さらに、ノードに複数回アクセスする必要がある可能性が高いためです。これは、従来のA *では不可能であり、ヒューリスティックを困難にします。

私が考えたのは、ダンジョンの始まりから終わりまでの道を探すことだけで、ブロックされたドアは無視されます。このパスが見つかると、道を塞いでいるドアごとに、適切なキーを探してドアに戻る追加のパスが検索され、ドアに到達する前に通過します。ドアを開くために必要なキーへのパスが、最初に開く必要がある別のドアによって再びブロックされる状況を処理するために、まったく同じシステムが使用されます。

私の解決策で私が見る大きな問題は、アイテム取得のパスを含むすべてのパスが見つかった後、目標から遠い他のブロックされたドアが存在する可能性があるため、エージェントが移動した総距離が可能な限り最小ではない可能性があることですしかし、適切なキーをはるかに簡単に利用できます。A *は、ブロックされたドアが単に無視される最初のパスでこれらのドアを無視します。

私はこれを解決しようとする最初のものではないと私は確信しています。問題についてのいくつかの入力をいただければ幸いです。


通常のA *がどのように実装されているかはわかりませんが、さまざまなパスを持つ実装には「ウェイト」スケールがあり、さまざまなパスの魅力を変えるでしょう。すべての可能なパスを計算してから、ロックされたドアを横切るパスの「重み」を正の無限大に設定できませんか?これにより、そのパスは無限に長く見えるため、決して使用されません。これはもちろん、更新ごとにエンティティごとにパスを計算するのではなく、パスを事前計算する場合に当てはまります。
ウィリアムマリアーガー、2011年

返信ありがとうございます。ただし、忘れているのは、ドアのロック解除がゴールノードへの唯一の方法である可能性があることです。その場合、言及したアルゴリズムではパスが見つかりません。または、ブロックされたパスの重みが単純に無限である場合、ブロックされたパスの1つを選択して、元の問題の前に立ちます。
マルク・ミュラー

回答:


8

単純なA *を使用してこのような状況を最適に処理する方法は、検索スペースを拡張することです。つまり、キャラクターが運ぶアイテムの組み合わせごとに、ダンジョンのコピーが個別に存在するとします。

ダンジョンの各コピーでは、通過可能なドアは、対応するアイテムのセットを使用して通過できるドアとまったく同じです。1つのダンジョンコピーから別のダンジョンコピーに渡す唯一の方法は、アイテムの場所に立ってそれを拾うことです。

このトリックを拡張して、ドアを開閉できるスイッチなどの他の状態変更を含めることができます。プレーヤーがアイテムをドロップできるようにすることもできますが、状態にはドロップされた各アイテムの場所を含める必要があるため、これは複雑になり、潜在的な検索スペースが大幅に増加します。

非常に便利な最適化は、すべてのドアがロックされている仮定して、各ドア(実際には、各ドアの両側)とアイテムから他のすべての到達可能なドア/アイテムへの最短経路を事前計算することです。これらのパスを取得したら、これらの重要な位置を相互に接続するグラフで、それぞれを重み付きエッジとして扱い、他のすべての位置を無視できます。

たとえば、ダンジョンに10のドアと5つのキーがあるとします。次に、2 * 10 + 5 = 25の有意な位置と2 ^ 5 = 32の可能なアイテムの組み合わせがあり、フルサーチスペースで合計25 * 32 = 800のノードになります。これは非常に控えめな数ですが、特に検索スペースの多くが到達不可能である可能性が高いことを考えると。


5

現実世界の視点から:AからBに向かっていて、ロックされている方法でドアDを見つけた場合、キーDを見つける必要があることに気付くでしょう。 、それはそれ自体の一連の小さなパスファインディングステップであるキーのスカウトを含みます。一方、パスを試みる前に、そのルートにロックされたドアがあることをAIに知らせたい場合があります。その場合、鍵の場所も知っているでしょう。

どちらにしても、問題は2つのレベルでの接続の1つです。「地上」レベルでは、1つの分割されていないゾーン内で常に安全に移動できます。つまり、ロックされたドアによって分割されていません。これは、現在のA *パスファインディング実装を自由に使用できる場所です。(単純化した例では、ゾーンを1つの部屋として見ることができます。ドアのロックを解除せずに他の部屋に到達することはできません。実際には、それはあなたのダンジョンの全領域である可能性があります。)これはあなたの基礎です実体の動きですが、最初にあなたの周りの領域を調査するのではなく、目を伏せて歩き回るようなものです。または、この場合、ロックされたドア。したがって、A *が実行される地上レベルのマップは、プレーヤーを現在のゾーン内でのみ移動するように制限する必要があります。

次に、より高レベルのマップがあります。これは、本質的に地形よりもトポロジー的です。それは、障害物の地上の詳細などを実際には気にせず、ゾーン間の接続のみを気にします。このトポロジマップは、現在ダンジョン内のすべてのゾーンの理想的な接続を示しているため、現在それらの間にドアがロックされているゾーン間の接続も示しています。そのエッジ(それぞれがゾーン間のドアを表す)には、そのドアを開くためにまだ必要なキーが格納されています。それ以外の場合は、開いていると見なされます。したがって、このグラフで最短経路を検索する場合、検索の実行時にエッジのデータをチェックすることで、見つかった経路を既に開いているルートのみに制限する必要があります。ここでの接続性は開放性を意味するのではなく、潜在的な開放性を意味します。

別のゾーン内にあるポイントに移動する場合は、まず上位マップを検索してパスを見つけます。(A *または他の最短パスアルゴリズムがこのレベルで使用される場合があります。)パスを見つけると、その上位レベルのマップは、現在のゾーンから他のゾーンに到達するために使用する必要があるドアに関する情報も提供するはずです。これで、ローカルゾーンで、地上レベルのAIを実行してそのドアに移動できます。ドアに到達すると、キャラクターはそのドア/ポータルを通過できます。彼は現在ゾーンBにいます。これがターゲットゾーンである場合、彼は地上レベルのナビゲーションを使用してキーに移動できます。そうでない場合は、ターゲットゾーンに到達するまで手順1を繰り返す必要があります。

求められている鍵自体がロックされたドアの後ろにある可能性があります...そしてそのドアへの鍵も同様に...など、吐き気がします。これは本質的に依存関係の解決の問題であり、これに取り組む方法はいくつかあります。そのうちの1つがペトリネットです。この優れた論文をご覧ください。

PS。ダンジョンを手続き的に作成している場合は、プレーヤーの開始位置がわかっている限り、作成時に依存関係の順序に関する情報を保存できます。


2

「最短経路」という言葉に対する通常の腸の反応は明らかにA *です。しかし、A *はこのような環境では失敗します。信頼できるヒューリスティックを定義する多くの問題があり、さらに、ノードに複数回アクセスする必要がある可能性が高いためです。これは、従来のA *では不可能であり、ヒューリスティックを困難にします。

まず、許容可能なヒューリスティックは完全である必要はありません。それは過小評価である必要があり、何もないよりはましでなければなりません。実際の距離で作業している場合、A *は少なくともある程度の助けになると思われ、ヒューリスティックが検索をあまり改善しなかったとしても、それでもおそらく標準の幅優先検索より優れています。または類似。

次に、A *は何度でもノードにアクセスできます。A *はパス検索アルゴリズムではなく、検索アルゴリズムであることを覚えておいてください。状態を検索します。ゲームでは、状態と位置を同一視することがよくあります。なぜなら、その状態にどのように到達したかは気にしないからです-そこにたどり着くまでの道のりの短さだけです。ただし、このような問題では、状態は位置と、保持されているキーなどの他の関連する状態の組み合わせです。

ただし、これらの複雑化により、A *は「非常に効率的」な領域から「成功するが、おそらく私が必要とするタイムスケールではない」領域に移動することは事実です。必要なタイムスケールは何ですか?実際、なぜこれを行う必要があるのですか。本当に最短のパスが必要ですか、それとも妥当なパスで十分でしょうか。

私が考えたのは、ダンジョンの始まりから終わりまでの道を探すことだけで、ブロックされたドアは無視されます。このパスが見つかると、道を塞いでいるドアごとに、適切なキーを探してドアに戻る追加のパスが検索され、ドアに到達する前に通過します。

このようなシステムが最適ではないことを証明するのは簡単です。追加のパスはどこから始めますか?最初からの場合は、ドアへの元のパスをプロットするために時間を無駄にしています。終わりからの場合、最初の近くにキーを配置すると、パスが1回で十分な場合に、マップを2回トラバースします。ドアと元のパスとの間のパスの最適なマージポイントを計算して計算すると、最適な結果が得られますが、順列の数が多くなり、検索を簡素化するためのヒューリスティックの形成が困難になるため、リソースを大量に消費します。問題に複数のキーを追加すると、巡回セールスマン問題が発生し、効率的に解決するのは容易ではありません。

「最短経路」の基準を緩和することが可能である場合、私が試みることはこれです:

  • 重要な位置(キーの位置、ドアの位置、ロックされた領域内の位置)のみを含む高レベルのグラフを作成し、それらの間の直線距離に注意してください。マップがすでに部屋やその他の個別の場所に分割されている場合、それはすばらしいことです。
  • A *を使用して、このグラフの最初から最後までのパスを見つけます。通常のデカルト距離ヒューリスティックは、それを扱いやすく保つのに十分でなければなりません。
  • これらのウェイポイント間のこの簡略化されたパスで、A *を再度使用して、1つのウェイポイントから次のウェイポイントへの低レベルパスをプロットします。
  • これらの低レベルのパスを結合して、パス全体を形成します。

それが機能するようになったら、いくつかのマイナーな最適化を検討します。低レベルのパスがキーを収集するために小さな回り道をする可能性が高くなるように、キーでエリアをより緩やかに重み付けします。


0

あなたが提供した情報があれば、少し変更するだけでA *を使用できると思います。通常のA *アルゴリズムでは、すべてのノードにパスを渡すときにマークを付け、再度パスしないようにします。それがアイテムに問題を引き起こす正確な部分です。重要な変更は、以前にノードから渡されたときにアイテムが何であったかを記憶することです。ここに私が何を意味するかを説明するsudoコードがあります:

if (nodestoCheck.notempty())
    newNode = nodeToCheck.first;
    if (notpassed(newNode.pos, newNode.items))
        if (room(newNode).containItem)
            add NewNode + room(NewNode).items 
        else
            do normal A* algorithm for new Node

このアルゴリズムでは、最初にアイテムのないすべてのノードのチェックを開始します。最初の検索グループがいくつかのドアによってブロックされる可能性が高いです。しかし、すべての部屋を検索する前に、そのドアの鍵を見つけます。そのキーから、その特定のキーを持つ新しい検索を開始します。今度は、ドアに着いたら通過できます。ダンジョンから抜け出す方法を見つけるまで、同じルーチンが続きます。唯一の問題は、ドアとキーがたくさんある場合のメモリ消費です。ただし、少なくとも10または15のキーでは問題にはなりません。


0

通常のA *だけを使用して、ロックされたドアを通行できない領域としてモデル化してみませんか。キーを手に取ると(キータイルの上を歩く?)、特定のロックされたドアが通過可能な領域に変わります。

これが意味することは、パスファインダーが最短のキーレスルートを探し、途中でキーを見つけた場合、それが役立つ場合はパスにそれを組み込むということです。

それは私にはかなり合理的に思えます。完璧ではありませんが、問題の簡単な解決策です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.