web-dev-qa-db-ja.com

最適化されたTSPアルゴリズム

n = 100 to 200都市の 巡回セールスマン問題 を解決できるアルゴリズムを改善または考案する方法に興味があります。

私が提供したウィキペディアのリンクにはさまざまな最適化がリストされていますが、それはかなり高いレベルで行われており、実際にコードに実装する方法がわかりません。

Concorde のような産業強度ソルバーがありますが、それらは私が望むものにはあまりにも複雑であり、TSPの検索に殺到する古典的なソリューションはすべて、ランダム化されたアルゴリズムまたは古典的なバックトラッキングまたは動的を提示します約20の都市でのみ機能するプログラミングアルゴリズム。

それで、少なくとも100の都市で妥当な時間(数秒)で動作する単純な(単純な実装では100〜200行を超えるコードを必要としない)TSPソルバーを実装する方法を知っている人はいますか?私は正確な解決策にのみ興味があります。

入力はランダムに生成されると思われるかもしれませんので、特定のアルゴリズムを破ることを特に目的とした入力は気にしません。

17
IVlad

グラフが三角不等式を満たし、最適範囲内で3/2の保証が必要な場合は、クリストフィードのアルゴリズムをお勧めします。私はphpclasses.orgでphpの実装を書きました。

3
Gigamegs

コンコルドライブラリからHeld-Karpアルゴリズムを取得したところ、25の都市が0.15秒で解決されました。このパフォーマンスは私にとって完全に良いです!コンコルドライブラリからholded-karpのコード(ANSI Cで記述)を抽出できます: http://www.math.uwaterloo.ca/tsp/concorde/downloads/downloads.htm 。ダウンロードの拡張子がgzの場合は、tgzである必要があります。名前を変更する必要があるかもしれません。次に、VC++での移植を少し調整する必要があります。まず、ファイルholdedkarp hとc(名前をcppに変更)と他の約5つのファイルを取得し、調整を行うと、edgelen:euclid_ceiling_edgelenを指定してCCheldkarp_small(...)を呼び出すと機能するはずです。

1

2013年現在、Cplexの正確な定式化のみを使用して、100都市を解決することができます。各頂点に次数方程式を追加しますが、サブツアー回避制約は表示されたとおりにのみ含めます。それらのほとんどは必要ありません。 Cplexにはこれに関する例があります。

あなたは100の都市を解くことができるはずです。新しいサブツアーが見つかるたびに繰り返す必要があります。ここで例を実行し、数分と100回の反復で結果を取得しました。

1
Julek

TSPはNP困難な問題です。 (私たちの知る限り)多項式時間で実行されるNP困難問題のアルゴリズムはないので、存在しないものを要求します。

妥当な時間で終了するのに十分な速さで、正確ではないか、正確であるが100都市の生涯で終了しないかのいずれかです。

0
Karoly Horvath

ばかげた答えを与えるために:私も。誰もがそのようなアルゴリズムに興味を持っていますが、他の人がすでに述べたように、私は(まだ?)存在しません。正確な200ノード、数秒のランタイム、200行のコードの組み合わせは不可能です。 NP難しいことはすでにご存知ですが、漸近的な振る舞いのわずかな印象を受けた場合は、これを達成する方法がないことを知っておく必要があります(NP = Pであることを証明する場合を除き、それでも正確な商用ソルバーでさえ、数秒をはるかに超えるそのようなインスタンスを必要とし、想像できるように、200行をはるかに超えるコードがあります(カーネルだけを考えた場合でも)。

編集:ウィキのアルゴリズムは、線形計画法と分枝限定法という分野の「通常の容疑者」です。数千のノードを持つインスタンスに対するソリューションは、解決するのに何年もかかりました(非常に多くのCPUを並列に使用して解決したため、より高速に実行できます)。分枝限定問題の境界に関する特定の知識を使用するものもあるため、一般的なアプローチではありません。

分枝限定法は、すべての可能なパスを列挙し(たとえば、バックトラッキングを使用)、解決策が見つかったら、これを適用して、結果がすでに見つかった解決策よりも良くないことを証明できるときに、開始された再帰を停止します(たとえば、あなたの都市とパスは、見つかった200の都市ツアーよりもすでに長くなっています。その2つの都市の組み合わせで始まるすべてのツアーを破棄できます)。ここでは、問題固有の知識を関数に投資して、パスがすでに見つかったソリューションよりも良くなることはないことを伝えることができます。それが優れているほど、見なければならないパスが少なくなり、アルゴリズムが高速になります。

線形計画法は最適化手法であるため、線形不等式の問題を解決します。それは多項式時間で機能しますが(実際には単純ですが、ここでは問題ではありません)、解決策は現実的です。解は整数でなければならないという追加の制約がある場合、NP完全になります。小さなインスタンスの場合、それは可能です。それを解決する1つの方法は、解のどの変数が整数部分に違反しているかを調べ、それを変更するために加算不等式を追加します(これは切断面と呼ばれ、不等式が(高次元)平面を定義するという事実に由来します。解空間はポリトープであり、不等式を追加することで、ポリトープから平面で何かを切り取ります)。トピックは非常に複雑で、数学を深く掘り下げたくない場合は、一般的な単純なシンプレックスでさえ理解するのが困難です。いくつかの良い本があります。より良いものの1つは、Chvatal、Linear Programmingからのものですが、さらにいくつかあります。

0
flolo

私には理論がありますが、それを追求する時間がありませんでした。

TSPは境界問題(すべての点が周囲にある単一の形状)であり、最適なソリューションは、最も短い周囲を持つソリューションです。

最小の境界境界上にあるすべてのポイントを取得する簡単な方法はたくさんあります(大きなボードの釘の束の周りに張られた大きなゴムバンドを想像してください)。

私の理論では、ゴムバンドを押し込み始めて、バンドの長さが周囲の隣接するポイント間で同じ量だけ増加し、各セグメントが楕円弧の形のままである場合、引き伸ばされた弾性は上のポイントと交差します非最適パス上のポイントを通過する前の最適パス。 mathopenref.comのこのページ 楕円の描画については、特に手順5と6を参照してください。境界境界上の点は、下の画像で楕円(F1、F2)の焦点として表示できます。

Step 5.

Step 6.

私が知らないのは、新しいポイントが追加されるたびに「バブルストレッチ」プロセスをリセットする必要があるのか​​、それとも既存の「バブル」が成長し続け、周囲の新しいポイントごとにローカライズされた「バブル」のみが発生するのかということです。 2つの線分に変わります。私はあなたが理解するためにそれを残しておきます。

0
oosterwal