4

最初のシードを指定して、決定論的な(つまり繰り返し可能な)疑似乱数のシーケンスを生成し、そのシーケンスからn番目の項目を選択する必要があります。

JavaScriptのランダム関数がシード可能である場合、私は次のことを行うことができます。

function randomNth(seed, seq)
{
    var r;
    Math.randomSeed(seed);
    for (var i = 0; i++ < seq; i++)
    {
        r = Math.random();
    }
    return r;
}

ただし、そうではなく、代替のシード可能なPRNGは少し遅いように見えます。250番目の番号を要求すると高額になります。

ハッシュは私がここで欲しいものだと思います。おそらく次のようなものですmd5(seed + seq) % maxが、JavaScriptにはmd5()がなく、コードでそれを行う場合は、おそらくハッシュのより良い選択があります。

ここで関数が欲しいのですが

x = randomNth(seed, seq, maxVal) // x is int && x >= 0 && x < maxVal

または、理想的には

x = randomNth(seed, seq) // x >= 0 && x < 1, same as Math.random()

その他の要件:

  • node.jsとブラウザで実行する必要があります
  • 数値は統計的にランダムである必要があります(または期間が短くなるため、十分に近い)
  • O(1)であり、適度にパフォーマンスが高い必要があります
4

4 に答える 4

3

このページにはいくつかの優れたint->intハッシュ関数があり、そのうちの1つを使用できます。

function hash(a)
{
    a = (a+0x7ed55d16) + (a<<12);
    a = (a^0xc761c23c) ^ (a>>19);
    a = (a+0x165667b1) + (a<<5);
    a = (a+0xd3a2646c) ^ (a<<9);
    a = (a+0xfd7046c5) + (a<<3);
    a = (a^0xb55a4f09) ^ (a>>16);
    if( a < 0 ) a = 0xffffffff + a;
    return a;
}
var seed = 26254;
var index = 250;
alert( hash( seed + index ) );
于 2011-08-25T10:57:00.577 に答える
2

結局、私は(SO以外の)友人からの提案を使用しました。これは非常に高速で、まともなランダム値を提供するため、CRC32()を使用しました。

return crc32(seq + seed) % maxVal;

800万回実行すると、maxVal=8の場合に次の分布が生成されます。

0 999998

1 999998

2 1000007

3 1000003

4 1000001

5 1000003

6 999992

7 999998

また、ハンスが言及したドナルド・クヌースのページで言及されている「マルサリアの有名な「ダイ・ハード」テストのバッテリー」を実行しました。その結果は次のとおりです。乱数のCRC32()ダイハードの結果。短いバージョンでは、(このような少量のテストデータに対して)惨めに失敗しますが、それでも、小さな範囲で数値を生成するという私のニーズには十分です。

于 2011-08-25T13:58:58.540 に答える
1

ドナルド・クヌースが助けになるかもしれません:http ://www-cs-faculty.stanford.edu/~uno/news02.html#rng

于 2011-08-25T09:56:14.657 に答える
1

このメルセンヌツイスターの実装をjavascriptで使用します。

于 2011-08-25T10:19:31.693 に答える