セットのパーティションを表すコンパクトな方法は何ですか?


11

セットパーティションを表すための効率的なデータ構造が存在します。これらのデータ構造は、UnionやFindなどの操作には時間的に複雑ですが、スペース効率は特に高くありません。

セットのパーティションを表すスペース効率の良い方法は何ですか?

以下は、考えられる開始点の1つです。

N個の要素 を持つセットのパーティション数はN番目のベル数であるB Nであることを知っています。したがって、N個の要素を持つセットのパーティションを表すための最適な空間の複雑さは、 log 2B Nビットです。そのような表現を見つけるために、(N要素のセットのパーティションのセット)と(1からB Nまでの整数のセット)の間の1対1のマッピングを探すことができます。NBNNNlog2(BN)N1BN

計算するのに効率的なそのようなマッピングはありますか?「効率的」とは、このコンパクトな表現を、またはlog 2B N)の時間多項式で、操作が簡単な表現(リストのリストなど)との間で変換したいということです。Nlog2(BN)


疑問に思って、は、整数がパーティションを表すセットの各要素に一意の整数を割り当てるだけの単純な/自然なエンコーディングからどれくらい離れているでしょうか?多分それは「それほど大きな違いではない」...log2(BN)
vzn 2013

回答:


7

以下の漸化式を導き出す方法を使用して、エンコーディングを見つけることができます:

Bn+1=k=0n(nk)Bk.
これは、要素n+1を含む部分に他の要素がいくつあるかを検討することによって証明されます。ある場合nkこれらの、そして我々は持っている(nnk)=(nk)それらの選択肢、および残りを分割するためのBk選択肢。

これを使用して、n+1パーティションを0,,Bn+11の範囲の数値に変換する再帰的アルゴリズムを提供できます。私はあなたが既にサイズのサブセット変換の方法があるとしk{1,,n}の範囲内の数値に0,,(nk)1(このようなアルゴリズムは、Pascalの再帰(nk)=(n1k)+(n1k1))。

n+1含む部分にk他の要素が含まれているとします。コードC1を見つけます。残りのすべての要素をその範囲に「圧縮」して、{1,,nk}パーティションを計算します。そのコードC2再帰的に計算します。新しいコードは

C=l=0nk1(nl)Bl+C1Bnk+C2.

他の方向では、コードの所与C、ユニーク見つけるkように

l=0nk1(nl)BlC<l=0nk(nl)Bl,
および定義
C=Cl=0nk1(nl)Bl.
以降0C<(nk)Bnk、それはのように書くことができるC1Bnk+C20C2<Bnk。今C1コードを含む部分の要素n+1、およびC2コードのパーティション{1,,nk}、再帰的にデコードできます。デコードを完了するには、後者のパーティションを「解凍」して、n+1を含む部分に表示されないすべての要素が含まれるようにする必要があります。


同じ方法を使用して、サイズk{ 1 n }のサブセットSを再帰的にエンコードする方法を次に示します。場合K = 0は、コードは0、そう仮定するK > 0。もしN Sは次いでせてC 1のコードでS { N }サイズのサブセットとして、K - 1{ 1 ... N - 1 }{1,,n}kk=00k>0nSC1S{n}k1{1,,n1}; SのコードはC1です。もしnS次いでせてC1のコードでSサイズのサブセットとして、k{1,,n1}SのコードはC1+(n1k1)

コードCをデコードするには、2つのケースがあります。もしC<(n1k1)、次いでデコードA部分集合S{1,,n1}サイズのk1コードであるC、及び出力S{n}。そうでなければ、デコードA部分集合S{1,,n1}サイズのkコードであるC(n1k1)、および出力S


すばらしい答え。ありがとうございました。マイナーバグ:上部の漸化式の証明スケッチでは、私はあなたの意味だと思う「があるこれらの」代わり「があるのK -その後、残ったものを」k個の要素がに分割することができるBのK方法。nkkkBk
cberzan 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.