简体   繁体   English

JavaScript伪随机序列生成器

[英]JavaScript pseudo-random sequence generator

I need to generate a deterministic (ie repeatable) sequence of pseudo-random numbers given an initial seed and select the nth item from that sequence. 我需要在给定初始种子的情况下生成确定性(即可重复的) 伪随机数序列,并从该序列中选择第n项。

If JavaScript's random function was seedable, I could just do: 如果JavaScript的随机函数是可播种的,我可以这样做:

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

However, it's not, and alternative, seedable PRNGs look to be a little slow; 然而,它不是,而另类,可播种的PRNG看起来有点慢; asking for the 250th number would be expensive. 要求第250个数字会很贵。

I think a hash is what I want here, perhaps something like md5(seed + seq) % max but JavaScript doesn't have md5() and if I'm doing it in code there's probably a better choice of hash. 我认为散列是我想要的,也许像md5(seed + seq) % max但JavaScript没有md5(),如果我在代码中这样做,那么哈希可能是更好的选择。

I'd like a function where 我想要一个功能

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

or, ideally 或者,理想情况下

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

Other requirements: 其他需求:

  • must run in node.js and in a browser 必须在node.js和浏览器中运行
  • numbers should be statistically random (or close enough as the period will be small) 数字应该是统计上随机的(或者因为周期很小而足够接近)
  • should be O(1) and reasonably performant 应该是O(1)并且具有合理的性能

There are some good int -> int hashing functions on this page you can use one of them. 这个页面上有一些好的int - > int散列函数,你可以使用其中一个。

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 ) );

In the end I used a suggestion from a (non-SO) friend. 最后,我使用了(非SO)朋友的建议。 I went with CRC32() as this is extremely fast and gives decently random values. 我使用CRC32(),因为它非常快,并提供了相当随机的值。

return crc32(seq + seed) % maxVal;

A run of eight million produced the following distribution for maxVal = 8: 800万次运行产生了maxVal = 8的以下分布:

0 999998 0 999998

1 999998 1 999998

2 1000007 2 1000007

3 1000003 3 1000003

4 1000001 4 1000001

5 1000003 5 1000003

6 999992 6 999992

7 999998 7 999998

I also ran " Marsaglia's famous "Die Hard" battery of tests " mentioned in the Donald Knuth page Hans mentioned, the results of which are here: CRC32() for random numbers Diehard results . 我还在汉斯提到的Donald Knuth页面中提到了“ Marsaglia着名的”Die Hard“测试电池 ”,结果在这里: CRC32()随机数Diehard结果 The short version is that it fails miserably (for such a small amount of test data), but it's still good enough for my needs where it is generating numbers in a small range. 简短的版本是它失败了(对于如此少量的测试数据),但它仍然足以满足我在小范围内生成数字的需求。

唐纳德克努特可能会有所帮助: http//www-cs-faculty.stanford.edu/~uno/news02.html#rng

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM