8ビットのロバートモリスとして、最大10,000カウント



nビットの助けを借りて誰もが知っているように、最大​​2 n -1までカウントするカウンターを実装できますが、リソースが非常に限られている場合、またはシーケンス、確率、ランダム性、カウンター増加を1つに実験して組み合わせたい場合は、 。






この記事では、いわゆる確率的カウンターの仕組みを説明します。
1977年に、彼のフレーズで知られるBellLabsで働く暗号作成者であるRobert Morrisによって最初に導入されました。
「コンピューターのセキュリティに関する3つのゴールデンルール:コンピューターを所有したり、電源を入れたり、使用したりしないでください。」


メーターの詳細


tビットを自由に使用できます。
負ではない増加シーケンスn i (iは0〜2 t -1の範囲にあります)を選択し、少し先に進んで、n iの値がカウンタ値になると言います。
最も興味深いのは、1にカウンターを追加する確率が1 /(n i + 1 -n i )になることです。



たとえば、シーケンスがn i = i 2の場合、カウンターを8から増やすと1 /(16-8)= 0.125の確率で真になり、その結果、n iからn i + 1へのカウンターはn i + 1だけで平均して増えます-n i操作

確率的カウンターの特殊なケースはn i = iであり、このようなシーケンスではカウンターが正常になり、追加の確率が1になることは明らかです。

実装


それでは、実際に実行してみましょう。
Java言語で実装します。
一定のメモリが8GBしかないとします。 重要なので、スコアを127に保つことができますが、これでは十分ではありません。
問題は、どのシーケンスを使用するかです。 彼女の選択は、メーターを保持する期間と、精度を犠牲にする意思があるかどうかによって異なります。 任意の整数の昇順シーケンスを自由に使用できます。たとえば、 オンラインシーケンスエンサイクロペディアで検索できます。
フィボナッチ数数の 二乗を使用します

2つの主な機能があります。 最初はカウンタをインクリメントし、2番目はシーケンスのi番目の番号を返します。

private byte counter = 0; public void increase(){ Random rand = new Random(); int randNumber = rand.nextInt(getElementSequence(counter + 1) - getElementSequence(counter)); if(randNumber == 0) counter++; } 


ここでは、確率に応じてカウンタが増加します。 カウンターはシーケンスについて何も知らず、イベントの成功または失敗に応じて、i番目の要素のみを返します。

これが二乗数列です

 private int getElementSequence(int number){ return (int) Math.pow(number, 2); } 


しかし、フィボナッチ数から

  private int getElementSequence(int number){ int sumFib = 1; int previousElement = 0; int temp; for(int i = 0; i < number + 1; i++){ temp = sumFib; sumFib = sumFib + previousElement; previousElement = temp; } return sumFib; } 

10,000回の反復で、通常のサイクルでカウンターの増加をシミュレートします。

 public static void main(String[] args) { TestApproximateCounting test = new TestApproximateCounting(); for(int i=0; i<10000; i++){ test.increase(); }; } 


まとめると



シーケンスごとに、10,000回の繰り返しのカウンターを10回実行しました

実行番号二乗数のカウンター値数の二乗フィボナッチ数のカウンター値フィボナッチ数
1938 649206 765
211112 321206 765
310511 025206 765
410310 6092110 946
5969,2162110 946
6948 8362217 711
7938 639194 181
810611,236194 181
910410 8162110 946
10948 836206 765


ご覧のとおり、エラーは非常に顕著ですが、8ビットで10,000を超えるカウントが必要な場合は、確率的カウンターが適切なオプションです。

参照:
Kormen T.、Leiserson C.、Rivest R.、Stein K.-アルゴリズム。 構築と分析-2005
Morris、R.小さなレジスターで多数のイベントをカウントします。 ACM 21、10(1977)、840〜842の通信

UPD。 リクエストに応じて、各シーケンスのカウンター値を示す2つの列をテーブルに追加しましたが、ここでも、カウンター自体の値は、カウンターからではなく、入力に対するカウンターを持つgetElementSequence関数から取得されると言います。

Source: https://habr.com/ru/post/J208268/


All Articles