List<int>
非常に遅いリモート乱数生成ソースからバイト(ちょうど)を読み取るものを書いています。それと私の個人的な要件のために、ソースからできるだけ少ないバイトを取得したいと思います。
今、私は署名が次のように見えるメソッドを実装しようとしています:
int getRandomInteger(int min, int max)
ランダムなソースからバイトをフェッチし、それらを整数に変換する方法には2つの理論があります。
アプローチ#1はナイーブです。(max - min) / 256
バイト数を取得して合計します。それは機能しますが、私が持っている遅い乱数ジェネレーターソースから多くのバイトをフェッチします。たとえば、100万から0までのランダムな整数を取得したい場合、4000バイト近くをフェッチします...これは受け入れられません。
アプローチ#2は私には理想的に聞こえますが、アルゴリズムを思い付くことができません。こんなふうになります:
例として、最小:0、最大:1000を取り上げます。
ceil(rangeSize / 256)
この場合はどれであるかを計算しceil(1000 / 256) = 4
ます。次に、ソースから1バイトをフェッチします。- この1バイトを0〜255の範囲から0〜3の範囲(または1〜4)にスケーリングし、使用するグループを決定します。たとえば、バイトが250の場合、4番目のグループ(最後の250の数値、範囲内の750〜1000を表す)を選択します。
- 次に、別のバイトをフェッチし、0〜255から0〜250にスケーリングして、グループ内の位置を決定します。したがって、この2番目のバイトがたとえば120の場合、最終的な整数は
750 + 120 = 870
です。
そのシナリオでは、合計2バイトをフェッチするだけで済みました。ただし、範囲が0〜1000000であるかのように、いくつかの「グループ」が必要であるため、はるかに複雑です。
このようなものを実装するにはどうすればよいですか?Java / C#/JavaScriptコードまたは擬似コードで大丈夫です。
また、結果がエントロピー/ランダム性を失わないようにしたいと思います。ですから、整数のスケーリングが少し心配です。