メンバーシップのクエリのすべてのサブセットをテストするためのデータ構造


7

次の操作を効率的にサポートするデータ構造はありますか?

  1. セットを追加
  2. セットのサブセットが追加されたかどうかを照会します。

これは、すべてのクエリ中にすべての追加セットをテストすることにより、線形オーバーヘッドで実装できます。より効率的に実装できますか?偽陽性/陰性の小さな確率は許容されます(ブルームフィルタースタイルなど)。


あるセットが追加された場合、o(n)よりも速くチェックすることも可能ですか?ここで、nは追加されたセットの数です。どうやって?
アルバートヘンドリックス

@alberthendriksすべてのセットがシングルトンである場合、ログ時間でそれを行うことができるので、このより一般的な設定でより効率的に実行できるかどうか疑問に思います
Elliot Gorokhovsky


1
セットについて詳しく教えてください。それらは整数のセットですか?そうでない場合、それらは少なくとも弱い順序を持っていますか?
orlp

1
@RenéGこれらの整数には限界があるかどうか?はいの場合、限界は何ですか?とにかく、この情報を質問に編集してください。
orlp

回答:


2

あなたのすべてのセットが有限のサブセットであるとしましょう N。しましょうSP(N) セットのセットを示します。

次の2つの操作が必要です。

  • O1(S,s):すべての sN、 追加 sS

  • O2(S,s):すべての sN、いくつかありますか sS そのため ss


スピードアップするためのアイデアをいくつか紹介します。

  • セットが別のサブセットであるかどうかをテストするので、おそらくサイズを維持する必要があります |s| 各セットの s で利用可能 O(1) テストする必要があるときに ss、まず、 |s||s|そうでない場合は、すぐにfalseを返すことができます。そして、あなたは確かに持っています|s||s|、その後、通常の低速テストを実行します。

  • あなたが持っている場合は注意してください s1S そして s2S、 そのため s1s2、その後 s2s、あなたも持っています s1s。だからあなたは保つ必要はありませんs2S ために O2。だからあなたは表すことができますS セットのセットによって sS そして ss 意味する sS。言い換えれば、あなただけのセットを追跡する必要がありますS含めるのは最小限です。これはかなり効率的に実装できます:セットを追加するときs、すべてのセット sS そのため |s||s| (枢機卿の昇順で並べ替え) ss、次に追加しないでください s 最小限ではない(またはすでに存在するため) S)。それ以外の場合は、s そしてセットの間で sS そのため |s|<|s|、それらを削除して、 ss (それらはもはや最小ではないため)。

  • セットを保つ t それはすべてのセットの和集合に等しい S。次に、実行する代わりにO2(S,s)、実行できます O2(S,st) 代わりに(一部の場合 sSss、それ以来 stsst で、もし sst、その後 ssts)。

これらのアイデアを念頭に置いて、私は代表します S 辞書(ペアの二重リンクリストとして実装) (key,value) キーの昇順で) d そのため d(k) に含まれる最小限の(含まれる)セットを正確に含む二重リンクリストです S 枢機卿の k

O1(S,s')
  if O2(S,s')
    return
  if d(k) doesn't exist
    d(k) := new_doubly_linked_list()
  add(d(k),s')
  S.t := union(S.t, s')
  for each key k of d so that |s'|+1 <= k
    for s in d(k)
      if subset(s', s)
        remove s

_O2(S,s')
  for each key k of d so that k <= |s'|
    for s in d(k)
      if subset(s,s')
        return true
  return false

O2(S,s')
  return _O2(S,inter(S.t,s'))

(私がのコードで明示的にそれをしなかったとしても、をO1表す二重にリンクされたリストの単一のトラバーサルを行うことができることに注意してくださいd

最悪の場合、あまり改善しないと思いますが、平均的には改善するはずです。


これらは有用な実用的な改善のように見えます。しかし、私はあなたがそれを意味すると思いますdマップデータ構造のリンクリストある必要があります(それ自体がキーで順序付けられたリンクリストである可能性があります-ハッシュテーブルまたはバランスツリーははるかに高速です)。
j_random_hacker

3
また、2番目の提案については、最悪の場合でも、 (nn2)Sperner's Theoremによれば、セットには他のセットは含まれていません。これは、宇宙にn 要素、そしてあなたはすべてを追加します n2-サイズセット。
j_random_hacker

最後に、クエリの「方向」が間違っていると思います。OPの質問に答えて、クエリセットを含むサブセットがまだ追加されていないかどうかを確認します。もちろん、これは簡単に修正できます(DeMorganの法則により、すべての入力セットを「反転」する関数(つまり、ユニバースとの対称差を取る)で実装を「ラップ」し、クエリの戻り値を反転することもできます) )。
j_random_hacker

2番目の箇条書きでは、sは非メンバーシップを意味する厳密なサブセットである必要があります。とにかく、この答えがおそらく最善だと思うので、それを受け入れます。
Elliot Gorokhovsky

@j_random_hackerそうですが、必要なのはセット(つまり、ユニットへのマップ)だけです。私が表す場合lex それらを宇宙からの関数として見ることによって与えられたセットの辞書式順序 {0,1}、その後、マップはその順序とバランスの取れたツリーを使用して実装できます。または、それをバイナリ決定図として表し、キーに関連付けられた値を対応するリーフに配置します。
xavierm02
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.