2010-12-15 3 views
17

私は旅行セールスマンの問題を解決するA *アルゴリズム(ヒューリスティックスが提供されています)の実装を書くことを任されました。私はアルゴリズムを理解しています、それは十分簡単ですが、私はそれを実装するコードを見ることができません。つまり、私はそれを得る。 distance +ヒューリスティック(ノード)でソートされたノードの優先順位キューは、パスに最も近いノードを追加します。問題は、直近のノードから直近のノードに到達できない場合はどうなりますか?どのように実際に関数の引数として "グラフ"を取るのでしょうか?私はアルゴリズムが実際にコードとしてどのように機能するのか分かりません。A *を使ってトラベリングセールスマンを解決する

質問を投稿する前に、私はウィキペディアのページを読んでいます。繰り返す。それは本当に質問に答えるものではありません。グラフの検索はTSPを解決する方法とは異なる方法です。たとえば、同じ長さの2つのパスが等しくないため、常に最短ノードがバックトラックになるグラフを作成できます。一方、AからBへ、2つのパス同じ長さのものは等しい。

いつも一番最初に行くことによって決して到達できないノードがあるグラフを導き出すことができます。

A *がTSPにどのように当てはまるかわかりません。私は、AからBへのルートを見つけることを意味します、確かに、私はそれを取得します。しかしTSP?私は接続が表示されません。関数の引数としてグラフを渡すには、あなたの質問の1 ...

に答えるために

+0

[A *](http://en.wikipedia.org/wiki/A*_search_algorithm)はbと思われる私がCSコースから覚えているものからかなり良いサマリー。 [Dijkstraアルゴリズム](http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)は非常に似ていますが(よ​​りシンプルなので)、最初はもっとうまくいくかもしれません。どちらの場合でも優先キューが便利です。 –

+6

@pst:A *とDijkstraのアルゴリズムは、A点からB点に移動したい場合に便利です。A点からA点まで、特定の制約のあるパスで移動したい場合は、それ以外の方法があります。 –

+0

Uni(以前の千年紀)に私が望んでいた言語でA *を実装する課題がありました。私たちが最もよく知っていたC++を選んだのですが、Prologを選択しました。短編小説、私は多くの人よりもはるかに速く割り当てを終えました。おそらくPrologで始まり、中間段階をスキップすることができます。 – Motti

答えて

0

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

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

2

アルゴリズムを理解する上で問題があるだけで、それがどのように機能するのかは、紙面にグラフを描き、重みを付けて描画することを検討するとよいでしょう。また、ダイクストラの最短経路を示すアニメーションもあります。Wikipediaには良いものがあります。 DijkstraとA *の唯一の違いは、ヒューリスティックの追加であり、ターゲットノードに到達するとすぐに検索を停止します。 TSPを解決するためにそれを使用する限り、それは幸運です!

+2

"それと幸運"、確かに! –

+0

TSPをA *で解くことが困難であることが示唆された場合、そうではありません。 Dijkstraの方が簡単であるとの上記のコメントに同意しますが、実装の詳細を決めるとかなり簡単です。 –

+6

私はA *がTSPをどのようにして解決するのかを見ていないと思います。最も近い未訪問のネイバーを選択するだけで、有効なルートが得られますが、必ずしも最短のネイバーになるとは限りません。 TSP(常に私に言われているように)は、最短の非繰り返しパスを求めています。多分、私はOPの目標を誤って解釈しています。 – fbl

1

もう少し抽象的に考えてみましょう。とにかくA *を忘れてしまったら、それはちょうど経験的なダイクストラです。前に、あなたはAからBに行きたいと思った。あなたの目標は何だった? Bに到達するための目標は、最低コストでBに到達することでした。どの時点でも、あなたの現在の「状態」は何でしたか?グラフ上のあなたの位置だけでしょう。

今度は、Aで始まり、次にBとCの両方に行きたいと思います。目標は今何ですか? BとCの両方を渡すには、コストを最小限に抑えます。より多くのノード(D、E、F、...またはN個のノード)でこれを一般化することができます。今、どのような時点でも、あなたの現在の「国家」は何ですか?これは非常に重要です。グラフ内のあなたの所在だけではなく、BやCのいずれか、またはこれまでに検索したノードを表します。

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

あなたがそれを得たら、いくつかのヒューリスティックとA *上で検索を改善してください。

+1

私はdijekstrsを理解することは難しいですが、あなたの考えはブルートフォースのように見えます。 – Bytemain

9

私はhere

使用ヒューリスティックとして最小スパニングツリー解決策を見つけました。

設定 初期状態:エージェント開始市と他の都市

ゴール状態訪問していない:エージェントはすべての都市を訪問し、スタート都市再

後継機能に達している:すべての都市を生成します

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

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

+0

MSTが直観に反して動作する問題のあるグラフを構築することは可能です。訪問したN都市が残っているグラフがあるとします。 MSTを使用すると、目標までの残りの距離の下限を取得できます。その後、都市を削除し、N-1都市を訪問する。ゴールまでの残りの距離が今大きくなっている可能性があります!この問題は今週、A *最寄りの検索で最小限のスパニングツリーを使用しようとしていたときに私に噛みました。私のソリューションは、機能を円滑にするために訪れた都市の数にボーナスを差し引くことでした。 –

0

問題は、直近のノードから直近のノードに到達できない場合はどうなりますか?

この手順は必要ありません。同様に、現在の最も近いものから最も近いものから、目的ノードに到達しようとしているものを計算しているわけではなく、現在の最も近いものだけが重要です(アルゴリズムが最後の繰り返しを気にしないあなたは100キロ離れていました。この繰り返しは96キロしか離れていないからです)。

概説として、A *は経路を直接構築しない:探索した領域内に経路が含まれていることを確実に知るまで調査し、探査中に記録された情報に基づいて経路を構築する。

(私は私の説明を補助するために、リファレンス実装としてthe code in the Wikipedia articleを使用するつもりです。)

あなたはノードの2セットを持っている:closedsetopenset

closedsetが完全に評価されたノードを保持し、つまり、あなたはどれくらい正確に彼らがstartからどれくらい離れているかを知っていて、すべての隣人は2つのセットのうちの1つにあります。これは、あなたがそれらで行うことができる計算がもうないので、それらを無視することができます。

opensetは「ボーダー」ノードを保持していますが、これはstartからどのくらい離れているかを知っていますが、まだ近隣に触れていないため、検索の端にありますこれまでのところ。

は(暗黙的に、第三のセットがあります:。完全に手付かずのノードしかし、彼らはそう、彼らは問題ではありませんopensetになるまで、あなたは実際にそれらに触れないでください。)

所与の反復では、「あなたの場合veは探索するノードを持っています(つまり、ノードはopensetにあります)。どのノードを探索するかを検討する必要があります。これはヒューリスティックの仕事ですが、基本的に境界線のどの点が次にどのノードを探索するのかについてのヒントを与えます。最短経路はgoalです。

以前の最も近いノードは無関係です。境界を少し広げただけで、新しいノードをopensetに追加しました。これらの新しいノードは、この繰り返しで最も近いノードの候補になりました。あなたが最終的にgoalに到達するまで、

は最初に、opensetstartが含まれていますが、その後、あなたは反復処理し、各ステップで境界線が(最も有望な方向に)少し拡大しています。

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

しかし、後でパスを再構築するには、パスのレコードが必要です。これはcamefromです。特定のノードの場合、camefromstartに最も近いノードにリンクするため、goalからのリンクを逆にたどって最短パスを再構築することができます。

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

representations of a graphのいずれかを渡します。

A *がTSPにどのように当てはまるかわかりません。私は、AからBへのルートを見つけることを意味します、確かに、私はそれを取得します。しかしTSP?私は接続が表示されません。

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

1

ここでの混乱は、あなたがTSPを解決しようとされているグラフは、あなたが*サーチAを実行しているないグラフであるということです。

関連資料:Sudoku solving algorithm C++

必要にこの問題を解決するために:

  • はあなたを定義します。
    • TSPは
    • TSP初期状態
    • TSPの目標状態(複数可述べて)
    • TSP状態後継機能TSPは述べて

      • :ヒューリスティック
      • TSP状態が
    • このTSPの状態グラフ

    まで私が考えることができる簡単な例に、一般的なA *ソルバーを適用するノードのリストを(都市)現在のTSPサイクル

  • TSPの初期状態:単一のノードを含むリスト、旅行セールスマンの故郷
  • TSPの目標状態:都市のグラフにすべてのノードが含まれている場合の目標です。
  • TSP後継機能:現在のサイクルにないノード(都市)を末尾に追加できますサイクル内のノードのリストは、新しい状態
    • 移行のコストは、あなたがサイクルに
  • TSP状態ヒューリスティックを追加しているエッジのコストに等しいを取得するために:あなたは
  • を決めます
関連する問題