在Javascript中播种随机数字生成器

是否有可能在JavaScript中播种随机数发生器(Math.random)?

不,不是,但是编写自己的发电机相当容易,或者更好地使用现有发电机。 退房: 这个相关的问题 。

另外,请参阅David Bau的博客, 了解有关播种的更多信息 。

我的另一个答案代表了一个更传统的algorithm,但我发现戴夫斯科特对这个答案的评论是一个更有说服力的。 不幸的是,由于string操作,它非常慢。

这个版本的速度要快20倍,而且要更精确一些。

 var seed = 1; function random() { var x = Math.sin(seed++) * 10000; return x - Math.floor(x); } 

您可以将seed设置为任意数字,避免零(或Math.PI的任何倍数)。

在我看来,这个解决scheme的优雅来自于缺乏任何“魔术”数字(除了10000,它代表了为避免奇怪模式而必须扔掉的最小数字位数) – 请参见值为10,100,1000的结果)。 简洁也很好。

它比Math.random()要慢2到3倍,但我相信它跟用JavaScript编写的任何其他解决scheme一样快。

不,但是这是一个简单的伪随机生成器,我改编自Wikipedia :

 var m_w = 123456789; var m_z = 987654321; var mask = 0xffffffff; // Takes any integer function seed(i) { m_w = i; m_z = 987654321; } // Returns number between 0 (inclusive) and 1.0 (exclusive), // just like Math.random(). function random() { m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask; m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask; var result = ((m_z << 16) + m_w) & mask; result /= 4294967296; return result + 0.5; } 

编辑:通过使其重置m_z固定种子function

AnttiSykäri的algorithm很好,很短。 当你调用Math.seed(s)的时候,我最初做了一个replaceJavascript的Math.random的变体,但是Jason评论说返回函数会更好:

 Math.seed = function(s) { return function() { s = Math.sin(s) * 10000; return s - Math.floor(s); }; }; // usage: var random1 = Math.seed(42); var random2 = Math.seed(random1()); Math.random = Math.seed(random2()); 

这给你另一个Javascript没有的function:多个独立的随机生成器。 如果您想要同时运行多个可重复的模拟,这一点尤其重要。

请参阅Pierre L'Ecuyer的工作回到20世纪80年代末和90年代初。 还有其他的。 如果你不是专家,自己创build一个(伪)随机数发生器是非常危险的,因为很可能结果不是统计上随机的,或者有一个小的周期。 皮埃尔(和其他人)把一些好的(伪)随机数发生器放在一起,这些发生器很容易实现。 我使用他的一个LFSR发生器。

~lecuyer/myftp/papers/handstat.pdf

菲尔·特洛伊

结合一些以前的答案,这是你正在寻找的可植入的随机函数:

 Math.seed = function(s) { var m_w = s; var m_z = 987654321; var mask = 0xffffffff; return function() { m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask; m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask; var result = ((m_z << 16) + m_w) & mask; result /= 4294967296; return result + 0.5; } } var myRandomFunction = Math.seed(1234); var randomNumber = myRandomFunction(); 

不过要小心使用这个,不过我不相信随机数的分布是非常好的,它似乎向0-5范围加权。 至less那是我在随机行走可视化方面的经验。

编写你自己的伪随机生成器非常简单。

Dave Scotese的build议是有用的,但正如其他人所指出的那样,它的分布不是很均匀。

但是,这不是因为罪的整数论证。 这只是因为罪的范围,恰好是一个圆的一维投影。 如果你将采取圆的angular度,而不是一致的。

所以,而不是sin(x)使用arg(exp(i * x))/(2 * PI)。

如果你不喜欢线性顺序,把它和xor混合一下。 实际的因素也不重要。

要生成n个伪随机数,可以使用下面的代码:

 function psora(k, n) { var r = Math.PI * (k ^ n) return r - Math.floor(r) } n = 42; for(k = 0; k < n; k++) console.log(psora(k, n)) 

还请注意,当需要真正的熵时,不能使用伪随机序列。