2

と の 2 つの頂点リストがVありSます。

V可能なすべての有向グラフをandから生成したいと思いますS。各頂点にVは 1 つのアウト エッジと 1 つのイン エッジしかなく、各頂点にSは任意の数のイン エッジとアウト エッジを含めることができます。V結果の各グラフには、と からのすべての頂点が正確に含まれている必要がありますS。結果には、接続されたグラフと切断されたグラフの両方を含めることができます。

最初は powerset 関連の問題だと思っていましたが、powerset には 1 つの要素だけを含む可能性のある他の多くのセットがあります (それらは必要ありません)。

私の現在の戦略は次のとおりです。

  • から頂点間のすべてのペアを見つけV、に追加しPairsます。
  • から頂点間のすべてのペアを見つけS、に追加しPairsます。
  • Vとからの頂点間のすべてのペアを見つけS、 に追加しPairsます。
  • V各サブセットがv最初の位置に頂点のインスタンスを 1 つだけ持ち、2 番目の位置に頂点のインスタンスを 1 つ持ち、任意の位置からv任意の頂点の任意の数のインスタンスを持つような方法で、以上のサイズのペアのサブセットを生成する.sS

これが正しいかどうか確信が持てないので、アイデアについて知りたいです。

たぶん、完全に接続されたグラフを作成しGVそれからS何らかの方法でサブグラフを抽出できますか? (おそらく digraph:utils の助けを借りて)

PS私はこれをErlangで解決しようとしています.Erlangは私が使用していて、現在積極的に学んでいる言語だからです. しかし、Java、Ruby、または疑似コードが回答に含まれていることを嬉しく思います。

4

1 に答える 1

2

ええ、それはとてもいい問題ですが、そこでいくつかのとてもいいトリックを行うことができます。行と列の数が頂点の数である0の正方行列としてグラフを表示できます。1それぞれ1が、行の頂点から列の頂点へのエッジを示します。次に、すべての可能なグラフは、N^2 ビットの 1 つの大きな 2 進数です。つまり、N 個の頂点から作成された 2^(N^2) の可能なグラフがあります。これで、問題を 2 つの部分に分割できます。

  1. 可能なすべてのグラフを生成しますS- 各グラフは 1 つの N^2 ビット数です。
  2. 次に、このグラフごとに、行列を行と列で展開し、各行と列で正確に 1でVある組み合わせで可能性を乗算します。1V

1 つ説明が必要です。あなたが書いた... からの各頂点Sは、任意の数のインエッジとアウトエッジを持つことができます0 は任意の数に含まれますか? 次に、結果にConstrainとの間のすべての頂点が正確に含まれている必要があることをVS理解していません。それぞれがゼロのインエッジとアウトエッジを持つ頂点として各ソリューションに含まれてSいるため、意味がありません。それ以外の場合は、すべての N^2 ビット数ではなく、各行と列にS少なくとも 1 つあるものだけであり、問​​題を 2 つの部分に分割することはできず、一緒に解決する必要があります。次に、最初に行と列を満たす方が簡単かもしれません(ちょうど 1 つ)1SVV1行と列で)、次に、この各解を、行と列に少なくとも 1 つ必要な場合に制約を満たすSxS行列の解で乗算します。S1

少数の頂点のリストのリストとして、さまざまな表現を試すことができます。arrayインデックスを計算するときにモジュールを試すR+C*Nか、配列の配列を試すことができます。頂点の数が多い場合は、バイナリの配列を使用して実行できます。digraphここでモジュールを試すこともできます。同様のアプローチは、Perl で完全なクロージャー グラフを生成するのにうまく機能しましたvec。しかし、それは非常に異なる問題であるため、ここでは当てはまらないようです。より最適化されたプレゼンテーションが見つかるかもしれませんが、Erlang がこの種の計算を非常に効率的に行うための最良のツールであるとは思えません。とにかく、ここでは可能性の数がかなり急速に増加しています O(2^(N^2)) ので、大きな行列の効率的なストレージについて心配する必要はありません;-)

編集:

この観点から問題を見てください。10 個の頂点があり、それが空であるVと仮定した場合。S次に、10!可能なグラフ、つまり 3628800 がSあります。その場合、約2^1001.2677e+30 グラフ (1 秒あたり 1e+09 グラフを生成する場合は 4.0197e+13 年) になります。これは、頂点の数が非常に少ない場合、可能なグラフの数が非常に多くなることを意味します。ここでの最大の問題は、それらをどうするかということです。それらを保管することはできませんが、保管する場合は非常に効率的に保管する必要があります。Binary フィールドは、 から作成されたグラフを格納するための最も効率的な方法ですS。頂点を持つエッジのより効率的な方法を見つけることができますV。配列またはリストとして保存します。ここで、位置はエッジの始点である頂点であり、値はエッジの終点である頂点です。

したがって、ソリューションは、結果をどうするかによって大きく異なります。非常に多数のグラフで何をするか想像できないため、何らかの方法で結果を除外すると思います;-)私のアドバイスは、グラフ生成中にできるだけ早く意味のあるグラフを除外することです。これは、アルゴリズムの生成に結果のフィルタリングを含めることができるようにするには、目的によってアプローチを決定する必要があることを意味します。

そして、この問題に対する Erlang の効率について言えば、膨大な数のエンティティ (考えられるグラフ) を扱う場合、メモリと CPU の使用を非常に慎重に管理する必要があります。Erlang を使用できますが、時間が重要な部分については、NIF で C を使用する必要があります。また、リストやタプルの代わりに、よりメモリに優しいデータ構造をバイナリまたはビッグナムとして使用する必要があります。また、C、C++、OCaml、Haskell などの他の言語を見つけることもできます。このようなメモリと計算を多用するタスクにより適しています。

于 2011-11-04T22:50:08.097 に答える