JavaScript伪随机序列生成器 [英] JavaScript pseudo-random sequence generator

查看:126
本文介绍了JavaScript伪随机序列生成器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要生成一个确定性(即可重复)的伪随机数字序列,并给出初始种子和选择该序列中的第n个项目。



如果JavaScript的随机函数是可植入的,我可以这样做:

 函数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)%最大但JavaScript没有md5(),如果我在代码中做的话,可能会有更好的选择。



我'd like a function where

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



或者理想情况下

x = randomNth (种子,seq)// x> = 0&& x < 1,与Math.random()一样



其他要求:


  • 必须在node.js和浏览器中运行

  • 数字应该是统计上随机的(或者足够接近,因为周期很小)
  • 应该是O(1)并且性能合理


解决方案

使用了(非SO)朋友的建议。我去了CRC32(),因为这是非常快的,并给出了体面随机值。



return crc32(seq + seed)%maxVal; code>



800万的运行产生了maxVal = 8的以下分配:


0 999998

1 999998

2
1000007



3
1000003



<4>
1000001


5
1000003

6
999992

7
999998


我也跑了,其结果如下: CRC32()适用于随机数字Diehard结果。简短的版本是它失败了(对于如此少量的测试数据),但它仍然足以满足我在小范围内产生数字的需求。

I need to generate a deterministic (i.e. repeatable) sequence of pseudo-random numbers given an initial seed and select the nth item from that sequence.

If JavaScript's random function was seedable, I could just do:

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; asking for the 250th number would be expensive.

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.

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
  • numbers should be statistically random (or close enough as the period will be small)
  • should be O(1) and reasonably performant

解决方案

In the end I used a suggestion from a (non-SO) friend. I went with CRC32() as this is extremely fast and gives decently random values.

return crc32(seq + seed) % maxVal;

A run of eight million produced the following distribution for maxVal = 8:

0 999998

1 999998

2 1000007

3 1000003

4 1000001

5 1000003

6 999992

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. 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.

这篇关于JavaScript伪随机序列生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆