每当我需要随机的东西时,我都会尝试使用一些世界生成机制Math.random()
,但后来决定我希望它基于种子,所以,给定一个种子,我将所有的更改Math.random()
为Math.sin(seed++)/2+0.5
,希望它会做同样的事情,但是如果种子是相同的种子,将是相同的。然后有人让我注意到正弦波没有均匀分布,最后我明白了为什么我的一些代码工作异常。我想知道是否有一个简单的修复,或者如果没有,另一个非常简单的基于种子的随机化器,像这样
3 回答
1
因此,我查看了您的方法 t1wc,发现它实际上分布不均。例如,吐出接近 0 或接近 1 的数字比吐出接近 0.5 的数字的可能性要大得多。这只是正弦函数工作方式的结果。
相反,您可以尝试使用一种名为Blum Blum Shub的方法(以原始论文的作者命名,非常棒)。它分布均匀,速度相当快。给定一个种子,它的工作原理如下:
- 将种子平方并将结果放入临时变量 (x) 中。
- 取 x base M 的 mod。
- M 是两个大素数的乘积。
- x 的值是用于未来计算的新种子。
- 返回 x/M 作为您的伪随机数。它将均匀分布在 0 和 1 之间。
下面是 Blum Blum Shub 的简单实现:
var SeededRand = function(seed, mod1, mod2)
{
return function()
{
seed = (seed*seed) % (mod1*mod2);
return seed/(mod1*mod2);
};
};
如果你想创建一个新的随机数生成器,你只需调用:
var rand = SeededRand(seed, mod1, mod2);
其中种子是一些初始种子(1234567890 效果很好),而 mod1 和 mod2 是一些大素数(7247 和 7823 效果很好)。rand
只是我定义的用于保存输出的变量。
现在,要开始获取随机值,您只需调用:
rand();
每次运行时都会吐出不同的值。
如果您有任何疑问,请询问!
于 2014-04-19T16:08:18.457 回答
0
已经制作了一个非常好的基于种子的随机化脚本。可以在这里找到。
于 2014-04-19T14:33:14.330 回答
0
好吧,伙计们,发现这是我真正想要的:
(((Math.sin(seed.value++)/2+0.5)*10000)%100)/100
它会发送均匀分布的数字,我想它比我见过的任何其他数字生成器都要简单得多
于 2014-04-19T14:48:36.213 回答