是否有可能在JavaScript中播种随机数生成器(Math.random) ?
当前回答
这里有很多很好的答案,但我有一个类似的问题,即我希望Java的随机数生成器和我最终在JavaScript中使用的任何东西之间的可移植性。
我找到了java-random包
假设种子相同,这两段代码有相同的输出:
Java:
Random randomGenerator = new Random(seed);
int randomInt;
for (int i=0; i<10; i++) {
randomInt = randomGenerator.nextInt(50);
System.out.println(randomInt);
}
JavaScript:
let Random = require('java-random');
let rng = new Random(seed);
for (let i=0; i<10; i++) {
let val = rng.nextInt(50);
console.log(val);
}
其他回答
SIN(id + seed)是一个非常有趣的替代RANDOM函数,不能像SQLite一样播种:
https://stackoverflow.com/a/75089040/7776828
数学。不是随机的,但是ran库解决了这个问题。它几乎拥有你能想象到的所有分布,并支持种子随机数生成。例子:
ran.core.seed(0)
myDist = new ran.Dist.Uniform(0, 1)
samples = myDist.sample(1000)
结合之前的一些答案,这是你正在寻找的可种子随机函数:
Math.seed = function(s) {
var mask = 0xffffffff;
var m_w = (123456789 + s) & mask;
var m_z = (987654321 - s) & mask;
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 & 65535)) >>> 0;
result /= 4294967296;
return result;
}
}
var myRandomFunction = Math.seed(1234);
var randomNumber = myRandomFunction();
Antti Sykäri的算法很好,很短。我最初做了一个变种来取代JavaScript的Math。当你调用Math.seed(s)时是随机的,但随后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没有的另一个功能:多个独立的随机生成器。如果您希望同时运行多个可重复的模拟,这一点尤其重要。
不可能在Math中植入种子。随机函数,但是用Javascript实现一个高质量的RNG是可能的,只需很少的代码。
Javascript数字是64位浮点精度,可以表示小于2^53的所有正整数。这给我们的算法带来了一个硬限制,但在这些限制内,您仍然可以为高质量的Lehmer / LCG随机数生成器选择参数。
function RNG(seed) {
var m = 2**35 - 31
var a = 185852
var s = seed % m
return function () {
return (s = s * a % m) / m
}
}
Math.random = RNG(Date.now())
如果你想要更高质量的随机数,代价是速度慢10倍,你可以使用BigInt进行算术,并选择m刚好适合双精度的参数。
function RNG(seed) {
var m_as_number = 2**53 - 111
var m = 2n**53n - 111n
var a = 5667072534355537n
var s = BigInt(seed) % m
return function () {
return Number(s = s * a % m) / m_as_number
}
}
参见Pierre l’ecuyer的这篇论文,了解上述实现中使用的参数: https://www.ams.org/journals/mcom/1999-68-225/S0025-5718-99-00996-5/S0025-5718-99-00996-5.pdf
无论你做什么,避免使用Math.sin的所有其他答案!
推荐文章
- 我如何检查如果一个变量是JavaScript字符串?
- Java生成两个给定值之间的随机数
- 如何检测如果多个键被按下一次使用JavaScript?
- 如何通过history. pushstate获得历史变化的通知?
- 如何从枚举中选择一个随机值?
- 使用jQuery改变输入字段的类型
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?