バイナリ配列に対する時間隔和クエリは、線形空間と一定時間を使用して実行できないことを示す


8

サイズのバイナリ配列が与えられます。n

どのアルゴリズムも次のことを実行できないことを示したいと思います(または驚いて、そのようなアルゴリズムが結局存在していることを知ってください):

1)無制限の時間を使用して、ただしビットのみを使用して、入力配列を前処理します。O(n)

2)クエリに一定の時間で応答します。クエリは、配列のインデックスとインデックス間のセットビット数を要求します。x y(x,y)xy

クエリごとの一定時間は、設定されたビット数を計算するのに十分な情報をアルゴリズムが読み取れないようにする必要があります。

そのようなアルゴリズムが存在しないことをどのように証明できますか?

より一般的な質問は、

アルゴリズムが空間の使用を許可されている場合、クエリ時間の下限はどのようにして導出できますか?f(n)

明らかに、スペースがある場合、すべての部分和を格納してクエリをに格納できが、が小さい場合はどうなりますか?O (1 )ff=Ω(nlog⁡n)O(1)f


メモリワードのサイズがあり、インデックスを一定の時間で読み取ることができると想定する場合があり。xは、YΘ(log⁡n)x,y


@EmilJeřábek-アルゴリズムでビット(入力サイズに線形を使用し、メモリワードを使用しないようにします。それは理にかなっていますか?O (n )O(n)O(n)
— RB

2
わかりました。ありがとうございます。さて、別の質問:記憶語に対して一定の時間内にどのような操作を実行できますか ここで、候補アルゴリズムは次のとおりにアレイ分割 -sizeブロック、及び各ブロックのために、コンテンツ記憶一つの単語として、及び前に設定されたビット数別の単語として。これはビットになります。各クエリは4つの単語を調べることで回答でき、シフト、減算、および(最も重要なことには)母集団数などのこれらの単語に対する演算を使用して計算できます。あなたのモデルはこれを許可していますか?b b b O (n )O (1 )(log⁡n)bbbO(n)O(1)
— EmilJeřábek2016

@EmilJeřábek-私は、算術演算、インデックス付け、ビット検索(つまり、単語から特定のビットを探す)のみを念頭に置いていました。シフトなどの標準ビット操作も検討できます。の設定ビット数を数えることができれば、アルゴリズムが実際に問題を解決することに同意します。O(1)
— RB

問題は、スライディングウィンドウを介した時間隔和クエリ用に作成しているアルゴリズムにあります。つまり、整数のストリームがあり、それぞれがあり、指定された間隔の合計を概算したいとします。次に、問題は(非常に小さい)バイナリ配列(これも「スライド」)の正確な間隔カウントに減少します。以下のためにバイナリスライディングウィンドウを-sized、我々が使用償却一定時間内にビットを追加し、ビット及びでクエリを実行。配列が更新されていなくても、一定時間のクエリが可能かどうか疑問に思っていました。 nはO (N )O (ログN )0,1,…,RnO(n)O(log⁡n)
— RB

@EmilJeřábek-あなたの提案と分析に感謝します!これは、私たちのニーズに完全に応えるものではありませんが、質問に対する答えになることがあります。ビットスペースが私たちのために、ハードの制約であり、我々は何のアルゴリズム、そのようなアルゴリズムは、一定時間内のクエリに答えることはできないことを示したいです。O(n)
— RB

回答:


6

あなたが探しているのは、ランク操作をサポートするコンパクトなデータ構造だと思います。見る...

https://en.m.wikipedia.org/wiki/Succinct_data_structure

具体的には、Emils(最初の)ソリューションを変更してポップカウント操作を削除し、ルックアップテーブルに置き換えることができます(詳細については、Wikiの記事を参照してください)。ブロックのサイズを(log n)/ 2ビットに減らすことにより、ルックアップテーブルはo(n)ビットを使用します。


(* facepalm *)明らかに、ルックアップテーブル。なぜそう思わなかったのですか。
— EmilJeřábek2016

上記のOPのコメントを考慮すると、構造をスライディングウィンドウとして簡単に実装できるため、ウィンドウを1ビット(またはブロック)だけ移動しても一定の時間がかかることに注意してください。
— EmilJeřábek2016

@EmilJeřábek-ソリューションをスライディングウィンドウ設定に変換することは簡単ではありません。現在のブロックに先行する配列部分全体のセットビットの数をカウントする代わりに、このブロックに先行するスライディングウィンドウ内のセットビットの数をカウントする必要があります。これは、一定の時間では実行できないようです。何か不足していますか?
— RB

いいえ、その必要はありません。最終的にのカウントをyのカウントから減算するので、保存されているすべてのカウントが固定量だけずれていても問題ありません。つまり、スライディングウィンドウの左端に任意の数を割り当てることができます。したがって、ウィンドウを移動するときは、新しい要素が存在するブロックのカウントを更新するだけで済みます。時々、多くのスペースを占有しないようにすべてのカウントを減らす必要がありますが、この小さな作業は簡単に分散できるため、クエリごとにO(1)時間しかかかりません。xy
— EmilJeřábek2016

実際、最後の文の煩わしさは、より大きい固定数を法としてすべてのカウントを計算することにより、エレガントに完全に回避できます。n
— EmilJeřábek2016

6

そのようなアルゴリズムが存在しないことを私は確信していません。非常に近いアルゴリズムは確かにあります。以下は、あるログ2 nは、ログ(K )のnでログ... ログ⏟のk  倍の N、ログ* n個である反復対数、と〜O(T (N ))であるが、O (T (N )polylog (トン(n )log⁡nlog2⁡nlog(k)⁡nlog…log⏟k times⁡nlog∗⁡nO~(t(n))。O(t(n)polylog⁡(t(n)))

命題:達成するアルゴリズムがあります

  1. 任意の定数kに対するスペースおよびクエリ時間O (1 )。O(nlog(k)⁡n)O(1)k

  2. スペースとクエリ時間〜O(ログ* n個)。O(n)O~(log∗⁡n)

k>0n=b0>b1>⋯>bk>0nb0b1b2kbi2

  • i=1,…,ki(i−1)

  • kkxy

bi

n∑i=1klog⁡bi−1bi,
O(k+bk).

kbi=log(i)⁡n0<i<kbk=1

k=log∗⁡n

bi=i(log⁡i)3log(i)⁡n.
n∑i=1klog(i)⁡n+2log⁡ii(log⁡i)3log(i)⁡n≤n∑i=1∞3i(log⁡i)2=cn
c

2

O(n)n⋅(1+o(1))

n{1,2,…,n}i′thi

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.