23

私は、巡回セールスマンの問題を解決する A* アルゴリズム (提供されるヒューリスティック) の実装を作成する任務を負っています。私はアルゴリズムを理解しています。それは十分に単純ですが、それを実装するコードを見ることができません。つまり、わかりました。距離 + ヒューリスティック (ノード) でソートされたノードの優先度キューは、パスに最も近いノードを追加します。問題は、前の最も近いノードから最も近いノードに到達できない場合はどうなるかということです。関数の引数として「グラフ」を実際にどのように取るのですか? アルゴリズムが実際にどのように機能するのか、コードとしてはわかりません。

質問を投稿する前にウィキペディアのページを読みました。繰り返します。それは実際には質問に答えません-グラフを検索することは、TSPを解決することとはまったく異なります。たとえば、同じ長さの 2 つのパスは等しくないため、任意の時点で最短のノードが常にバックトラックになるグラフを作成できますが、A から B に行こうとしているだけの場合は 2 つのパスになります。同じ長さは等しいです。

常に最初に最も近いノードに移動することで、一部のノードに決して到達しないグラフを導き出すことができます。

A* が TSP にどのように適用されるかはよくわかりません。つまり、A から B へのルートを見つけるということです。しかし、TSP?接続がわかりません。

4

6 に答える 6

11

ここで解決策を見つけました

ヒューリスティックとして最小スパニングツリーを使用します。

初期状態の設定:開始都市のエージェントで、他の都市を訪問したことがない

目標の状態:エージェントはすべての都市を訪問し、再び開始都市に到達しました

後継機能:まだ訪問していないすべての都市を生成します

エッジコスト:ノードによって表される都市間の距離。このコストを使用してg(n)を計算します。

h(n):現在の都市から最も近い未訪問の都市までの距離+すべての未訪問の都市を移動するための推定距離(ここではMSTヒューリスティックを使用)+未訪問の都市から開始都市までの最も近い距離。これは許容されるヒューリスティック関数であることに注意してください。計算を容易にするために、訪問した都市のリストと未訪問の都市のリストを維持することを検討できます。

于 2012-04-20T14:12:02.260 に答える
3

アルゴリズムとその仕組みを理解するだけの問題である場合は、紙にグラフを描き、それに重みを割り当てて描画することを検討してください。また、ダイクストラの最短経路を示すいくつかのアニメーションをおそらく見つけることができます。ウィキペディアには良いものがあります。Dijkstra と A* の唯一の違いはヒューリスティックの追加であり、ターゲット ノードに到達するとすぐに検索を停止します。それを使用して TSP を解決する限り、頑張ってください!

于 2010-12-15T18:32:10.277 に答える
1

これをもう少し抽象的に考えてみましょう。A* のことはしばらく忘れてください。いずれにせよ、ダイクストラはヒューリスティックを使用したものです。以前は、A から B に行きたいと思っていました。目標は何でしたか? B に到達する。目標は、最小のコストで B に到達することでした。ある時点で、あなたの現在の「状態」はどのようなものでしたか? おそらく、グラフ上のあなたの場所だけです。

では、A から始めて、B と C の両方に進みたいと考えています。今の目標は何ですか? 最小限のコストを維持しながら、B と C の両方を通過する。これをより多くのノードで一般化できます: D、E、F、... または単に N ノード。さて、ある時点で、あなたの現在の「状態」は何ですか? これは重要です。グラフ内のあなたの位置だけではありません。B または C のどちらであるか、または検索でこれまでに訪れたノードでもあります。

Xを動かした後、「目標状態」に達したかどうかを尋ねる関数を呼び出すように、独自のアルゴリズムを実装します。以前は、関数は「はい、状態 B にいるため、ゴールに到達しています」と言うだけでした。しかしここで、検索のパスが関心のある各ポイントを通過した場合、その関数が「はい、目標の状態にいます」を返すようにします。現在の状態に含まれているため、検索がすべての関心のあるポイントを通過したかどうかがわかります。

それを取得したら、ヒューリスティックを使用して検索を改善し、A* をアップします。

于 2012-02-08T09:33:30.583 に答える
0

問題は、前の最も近いノードから最も近いノードに到達できない場合はどうなるかということです。

この手順は必要ありません。のように、以前の最も近いノードから現在の最も近いノードへのパスを計算しているのではなく、目標ノードに到達しようとしており、現在最も近いノードだけが重要です (たとえば、アルゴリズムは最後の反復を気にしません)。この反復では 96 km しか離れていないため、100 km 離れていました)。

概説すると、A* はパスを直接構築しません。探索した領域内にパスが含まれていることが確実にわかるまで探索し、探索中に記録された情報に基づいてパスを構築します。

( Wikipedia の記事のコードを参照実装として使用して、説明を補助します。)

次の 2 つのノード セットがありますclosedsetopenset

closedset完全に評価されたノードを保持します。つまり、それらがどれだけ離れているかを正確に把握しておりstart、すべての隣接ノードが 2 つのセットのいずれかに属しています。これにより、それらを使用して実行できる計算はこれ以上ないため、それらを (ある程度) 無視することができます。(基本的にこれらは境界内に完全に含まれます。)

opensetは「境界」ノードを保持します。これらが からどれだけ離れているかはわかってstartいますが、まだ隣接ノードに触れていないため、これまでの検索の端にあります。

(暗黙的に、3 番目のセットがあります。完全に手を加えられていないノードです。しかし、それらが入るまで実際には触れないopensetので、それらは重要ではありません。)

特定の反復で、探索するノード (つまり、 のノードopenset) がある場合は、探索するノードを決定する必要があります。これはヒューリスティックの仕事であり、基本的に、どのノードが への最短経路を持つと考えられるかを伝えることで、次に探索するのに最適な境界上のポイントについてのヒントを提供しますgoal

以前の最も近いノードは関係ありません。新しいノードを に追加して、境界を少し拡張しただけopensetです。これらの新しいノードは、この反復で最も近いノードの候補になります。

最初はopensetのみが含まれてstartいますが、その後反復し、最終的に に到達するまで、各ステップで境界線が少し (最も有望な方向に) 拡張されますgoal

A* が実際に探索を行っているときは、どのノードがどこから来たかは気にしません。startからの距離とヒューリスティック関数を知っているので、必要はありません。必要なのはそれだけです。

ただし、後でパスを再構築するには、パスの記録が必要camefromです。特定camefromのノードについて、 に最も近いノードにリンクするため、startから逆方向にリンクをたどることで最短パスを再構築できますgoal

関数の引数として「グラフ」を実際にどのように取るのですか?

グラフの表現の 1 つを渡す。

A* が TSP にどのように適用されるかはよくわかりません。つまり、A から B へのルートを見つけるということです。しかし、TSP?接続がわかりません。

別のヒューリスティックと別の終了条件が必要です。goalもはや単一のノードではなく、すべてが接続された状態です。ヒューリスティックは、残りのノードを接続する最短パスの長さの推定値です。

于 2012-04-20T16:48:50.360 に答える
0

あなたの質問の1つに答えるために...

グラフを関数の引数として渡すには、いくつかのオプションがあります。すべてのノードを含む配列へのポインターを渡すことができます。完全に接続されたグラフの場合は、開始ノードを 1 つだけ渡して、そこから作業することができます。最後に、内部に必要なデータ構造を含むグラフ クラスを作成し、そのクラスのインスタンスへの参照を渡すことができます。

最も近いノードに関する他の質問については、必要に応じてバックトラックする A* 検索の一部ではありませんか? または、そのような状況に対処するために、独自の種類のバックトラッキングを実装することもできます。

于 2010-12-15T18:30:19.580 に答える