グラフ検索の最適化問題を解決しています。有向加重グラフを使用して、k個の最適な非循環最短経路を見つける必要があります。
正確で概算のk-bestアルゴリズムがいくつかあることは知っていますが、最近の研究のほとんどは、非常に大きく、非常にまばらに接続されたグラフ(道路の経路や方向など)を志向しているようで、私のグラフもどちらでもありません。
私の問題の特徴的な側面:
グラフは約160個の頂点で構成されています。
グラフはほぼ完全に接続されています(双方向なので、約160 ^ 2〜= 25kエッジ)
kはかなり小さい(おそらく10未満)
最大パス長はおそらく制限され、非常に小さくなります(例:3-5エッジ)
上記で「非循環」と言いましたが、繰り返しますが、ソリューションにはサイクルを含めないでください。これは1-best最短パスの問題ではありませんが、k-bestの問題になります。たとえば、道路の経路を検討します。AからBへの2番目の最短パスは、1-bestと同じかもしれません。どこかでブロックの周りの短い旅行。これは数学的には最適かもしれませんが、あまり有用な解決策ではありません。 ;-)
計算ごとにオンザフライでエッジのウェイトを再調整する必要がある場合があります。エッジコストは、いくつかの要素の重み付き合計で構成され、最終的な要件(取得された場合はいつでも)により、ユーザーはそれらの重み付け要素の独自の優先順位を指定して、エッジの重みを変更できます。これは比較的小さいグラフ(数百KBで表すことができるはずです)であるため、グラフをメモリに複製し、再重み付けを適用してから、複製されたグラフに対して検索を実行するのが妥当でしょう。しかし、オンザフライで重みを計算しながら検索を実行するより効果的な方法がある場合、私は興味があります。
私は、Santos(K最短パスアルゴリズム)、Eppstein 1997(k最短パスの検索)などで説明されているアルゴリズムを見ています。円のアルゴリズムは、主に既存のJava implementation のために)興味があります。研究論文を読むのは怖いことではありませんが、私の問題の詳細といくつかの読書時間を節約するための指針を求めます。
そして、もしあなたがJava実装へのポインタを持っているなら、さらに良いでしょう。
私自身の質問に部分的に答えるには:
この質問を投稿してから、正のエッジの重みと負のエッジの重みを処理する必要があることを発見しました(非循環/単純/ループのないパスへの制限は、最良のソリューションが定義されることを意味しますが、その制限なしに、負のグラフの最短パス-コストサイクルは未定義です)。
円のアルゴリズムと私が調べた他のほとんどのアルゴリズムは、一連の1-best検索に依存しています。ほとんどの場合、中間検索にはダイクストラを使用します。ダイクストラは負のエッジウェイトをサポートしていませんが、代わりにベルマンフォードを使用できます(少なくとも円では、おそらくローラーまたはエップスタインでも同様です)。 (長さの)パス長の制限と、検索中の明示的なサイクルチェック(標準のポスト検索サイクル検出の代わり)を備えたベルマンフォードの変更を開発しました。計算の複雑さはさらに悪くなりますが、私の要件では扱いやすくなっています。投稿の許可を得たら、この返信を編集して技術レポートにリンクします。
私はこの質問は簡単にグーグルでき、重複でもあると思います:
そうは言っても、私はすでにEppsteinを使用および実装しており、推奨しています。とてもエレガントだと思いました。私の記憶が正しければ、それも最適である可能性があり、次の論文はそれを非常にうまく説明しています:
http://pdf.aminer.org/001/059/121/finding_the_k_shortest_paths.pdf