JavaScript Math.random()函数返回0到1之间的随机值,根据当前时间自动播种(类似于我认为的Java) . 但是,我不能以任何方式为你设置自己的种子 .
如何创建一个随机数生成器,我可以提供自己的种子值,以便我可以生成一个可重复的(伪)随机数序列?
JavaScript Math.random()函数返回0到1之间的随机值,根据当前时间自动播种(类似于我认为的Java) . 但是,我不能以任何方式为你设置自己的种子 .
如何创建一个随机数生成器,我可以提供自己的种子值,以便我可以生成一个可重复的(伪)随机数序列?
9 回答
一个选项是http://davidbau.com/seedrandom,这是一个基于RC4的可种子Math.random()替换,具有良好的属性 .
如果您不需要播种功能,只需使用
Math.random()
并在其周围构建辅助函数(例如randRange(start, end)
) .我不确定您使用的RNG是什么,但最好知道并记录它,以便您了解它的特性和局限性 .
就像Starkii所说,Mersenne Twister是一个很好的PRNG,但实施起来并不容易 . 如果你想自己动手尝试实现LCG - 它很容易,具有不错的随机性(不如Mersenne Twister),你可以使用一些流行的常量 .
如果您希望能够指定种子,则只需要将调用替换为
getSeconds()
和getMinutes()
. 你可以传入一个int并使用mod 60的一半作为秒值,另一半使用modulo 60给你另一部分 .话虽这么说,这种方法看起来像垃圾 . 做适当的随机数生成非常困难 . 这个问题的一个明显问题是随机数种子基于秒和分钟 . 要猜测种子并重新创建随机数流,只需要尝试3600种不同的秒和分钟组合 . 这也意味着只有3600种不同的种子 . 这是可以纠正的,但我从一开始就怀疑这个RNG .
如果您想使用更好的RNG,请尝试使用Mersenne Twister . 它是经过良好测试且相当强大的RNG,具有巨大的轨道和出色的性能 .
编辑:我真的应该是正确的,并将其称为伪随机数生成器或PRNG .
我使用Mersenne Twister的JavaScript端口:https://gist.github.com/300494它允许您手动设置种子 . 另外,正如其他答案中所提到的,Mersenne Twister是一个非常好的PRNG .
您列出的代码类似于Lehmer RNG . 如果是这种情况,则
2147483647
是最大的32位有符号整数,2147483647
是最大的32位素数,48271
是用于生成数字的全周期乘数 .如果这是真的,您可以修改
RandomNumberGenerator
以接受额外的参数seed
,然后将this.seed
设置为seed
;但是你必须小心确保种子会导致随机数的良好分布(Lehmer可能会像这样奇怪) - 但是大多数种子都会很好 .以下是可以提供自定义种子的PRNG . 调用
SeedRandom
将返回随机生成器函数 .SeedRandom
可以不带参数调用,以便使用当前时间为返回的随机函数设定种子,或者可以使用1或2个非负片段作为参数调用它,以便用这些整数播种它 . 由于浮点精度,只有1个值的播种只允许发生器启动到2 ^ 53个不同状态之一 .返回的随机生成器函数采用名为
limit
的1个整数参数,该限制必须在1到4294965886的范围内,该函数将返回0到limit-1范围内的数字 .使用示例:
该生成器具有以下属性:
它有大约2 ^ 64种不同的可能内部状态 .
它的周期约为2 ^ 63,比任何人在JavaScript程序中实际需要的都多 .
由于
mod
值为素数,因此无论选择的限制如何,输出中都没有简单的模式 . 这与一些简单的PRNG不同,后者表现出一些相当系统的模式 .它会丢弃一些结果,以便无论极限如何都能获得完美的分布 .
它相对较慢,在我的机器上每秒运行大约1000万次 .
如果你在Typescript中编程,我改编了Mersenne Twister实现,这个实现是Christoph Henkelmann对这个线程作为打字稿类的回答:
你可以使用它如下:
检查源以获取更多方法 .
我发现这个代码已经开始了,它似乎可以正常工作以获得一个随机数,然后使用种子,但我不太确定逻辑是如何工作的(例如2345678901,48271和2147483647数字来自哪里) .
好的,这是我解决的解决方案 .
首先,使用“newseed()”函数创建种子值 . 然后将种子值传递给“srandom()”函数 . 最后,“srandom()”函数返回0到1之间的伪随机值 .
关键的一点是种子值存储在数组中 . 如果它只是一个整数或浮点数,那么每次调用函数时都会覆盖该值,因为整数,浮点数,字符串等的值直接存储在堆栈中,而不仅仅是指针,如数组和其他对象 . 因此,种子的 Value 可能保持持久 .
最后,可以定义“srandom()”函数,使其成为“Math”对象的一种方法,但我会把它留给你来弄清楚 . ;)
祝好运!
JavaScript的:
Lua 4(我的个人目标环境):