是否有可能在JavaScript中播种随机数生成器(Math.random) ?
当前回答
不,不可能为Math.random()提供种子,但是编写自己的生成器相当容易,或者更好的是使用现有的生成器。
请看:这个相关的问题。
另外,请参阅David Bau的博客了解更多关于播种的信息。
其他回答
这是Jenkins哈希的采用版本,从这里借来的
export function createDeterministicRandom(): () => number {
let seed = 0x2F6E2B1;
return function() {
// Robert Jenkins’ 32 bit integer hash function
seed = ((seed + 0x7ED55D16) + (seed << 12)) & 0xFFFFFFFF;
seed = ((seed ^ 0xC761C23C) ^ (seed >>> 19)) & 0xFFFFFFFF;
seed = ((seed + 0x165667B1) + (seed << 5)) & 0xFFFFFFFF;
seed = ((seed + 0xD3A2646C) ^ (seed << 9)) & 0xFFFFFFFF;
seed = ((seed + 0xFD7046C5) + (seed << 3)) & 0xFFFFFFFF;
seed = ((seed ^ 0xB55A4F09) ^ (seed >>> 16)) & 0xFFFFFFFF;
return (seed & 0xFFFFFFF) / 0x10000000;
};
}
你可以这样使用它:
const deterministicRandom = createDeterministicRandom()
deterministicRandom()
// => 0.9872818551957607
deterministicRandom()
// => 0.34880331158638
不可能在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的所有其他答案!
对于0到100之间的数。
Number.parseInt(Math.floor(Math.random() * 100))
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没有的另一个功能:多个独立的随机生成器。如果您希望同时运行多个可重复的模拟,这一点尤其重要。
SIN(id + seed)是一个非常有趣的替代RANDOM函数,不能像SQLite一样播种:
https://stackoverflow.com/a/75089040/7776828
推荐文章
- 如何使用Jest测试对象键和值是否相等?
- 将长模板文字行换行为多行,而无需在字符串中创建新行
- 如何在JavaScript中映射/减少/过滤一个集?
- Bower: ENOGIT Git未安装或不在PATH中
- 添加javascript选项选择
- 在Node.js中克隆对象
- 为什么在JavaScript的Date构造函数中month参数的范围从0到11 ?
- 使用JavaScript更改URL参数并指定默认值
- 在window.setTimeout()发生之前取消/终止
- 如何删除未定义和空值从一个对象使用lodash?
- 检测当用户滚动到底部的div与jQuery
- 在JavaScript中检查字符串包含另一个子字符串的最快方法?
- 检测视口方向,如果方向是纵向显示警告消息通知用户的指示
- ASP。NET MVC 3 Razor:在head标签中包含JavaScript文件
- 禁用从HTML页面中拖动图像