关于 JavaScript Math.random() 和基本逻辑的问题
Posted
技术标签:
【中文标题】关于 JavaScript Math.random() 和基本逻辑的问题【英文标题】:Question about JavaScript Math.random() and basic logic 【发布时间】:2019-10-18 09:43:11 【问题描述】:我写了一段简单的代码来比较随机数组的差异,发现了一些我不太明白的东西。
-
我生成了 2 个用随机数填充的数组
将随机数之间的差异相加
打印出平均差
我原以为结果是接近 0.5 的随机数,但实际上是 0.3333。
为什么随机数数组归位在 0.3 而不是 0.5?
const result = document.getElementById('result');
const generateRandomNrArray = (nrNumbers) =>
let i;
let result = [];
for (i = 0; i < nrNumbers; i++)
result.push(Math.random());
return result;
const getArrayDiff = (arr1, arr2) =>
var diff = 0;
arr1.forEach(function (v1, index)
diff += Math.abs(v1 - arr2[index]);
);
return diff;
const run = (nr) =>
const arr1 = generateRandomNrArray(nr);
const arr2 = generateRandomNrArray(nr);
const totalDiff = getArrayDiff(arr1, arr2);
result.innerhtml = "Average difference:" + (totalDiff / nr);
button font-size: 2em;
<div id="result"></div>
<button id="run" onclick="run(1500)">Click Me</button>
【问题讨论】:
Java 似乎也给出了结果。也许这将有助于解释这种行为? math.stackexchange.com/questions/637822/… 用 3 个数字再试一次,看看你的平均值是多少。您可能会看到模式 平均差可能趋于0。你说的是绝对差。 【参考方案1】:这基本上归结为一个限制,这是有道理的。考虑 0 到 10 之间的数字组合,并计算您可以做出的各种差异。
例如,有一种组合,差值为 9 — (0, 9)。有5个相差5个:
[0, 5],
[1, 6],
[2, 7],
[3, 8],
[4, 9]
但相差1的组合有九种:
[1, 2],
[2, 3],
...
[8, 9]
0 - 10 的计数是:
1: 9, 2: 8, 3: 7, 4: 6, 5: 5, 6: 4, 7: 3, 8: 2, 9: 1
有 45 种组合,这些组合的平均差异是 3.6666
而不是 5
,因为较小的差异比较大的差异更多。
当您将粒度从 0 - 10 增加到 0 - 100 时,同样的模式成立。有 99 种组合导致差异 1,只有 50 种差异为 50,平均为 33.6666
。
当您在相反方向增加有效数字的数量时,在 0 和 1 之间进行越来越精细的划分,您会发现与极限接近 1/3
时相同的过程。与较大的差异相比,较小的差异会拉低平均差异。对于0-1
,在 0.1 的间隔中,您会看到 9 的差异为 0.1,5 的差异为 0.5,在 0.01 时,99 的差异为 0.01,50 的差异为 0.5。随着区间接近 0,差异的平均值接近 1/3
。
【讨论】:
是的,使用固定的较大数字而不是细粒度的 0.xxxx 数字,问题变得更容易理解。 “...因为较小的差异比较大的差异更多” 这是一个很好的观点,但它提出了一些问题。为什么平均数不更小呢?例如 0.25。起初,我有一种直觉,由于某种神奇的数学原因,这个数字最终会成为 Math.PI。 @RainerPlumer 当你将区间随机分成两部分时,两部分的平均大小为1/2
。如果随机选择两个数字,则将区间分成 3 个部分,每个部分的平均大小为1/3
。那么这两个数字的平均差就是1/3
。
@Sulthan:您的评论比这里的每个答案都更清晰、更简洁。这本身就是一个很好的答案。【参考方案2】:
(事实上,您不是在看差异,而是看随机数之间的绝对差异。存在差异。(请原谅双关语))
如果您有两个独立的均匀分布随机变量X, Y ~ U[0,1]
,那么它们的绝对差|X-Y|
将遵循triangular distribution,期望为1/3。一切都是应有的。这个分布结果以及计算期望值是概率论中相当标准的作业问题。直觉直接跟随Mark's argument。
这里是绝对和非绝对差异的直方图。在左侧,您会看到较小的绝对差异有更多的质量,这拉低了期望值。
R 代码:
set.seed(1)
xx <- runif(1e5)
yy <- runif(1e5)
par(mfrow=c(1,2))
hist(abs(xx-yy),main="|X-Y|",col="grey",xlab="")
hist(xx-yy,main="X-Y",col="grey",xlab="")
(顺便说一句,如果您有概率/统计问题,我们的姊妹网站CrossValidated 是一个很好的资源。)
【讨论】:
【参考方案3】:这里有一个几何参数来说明为什么结果会收敛到 1/3。
首先,让我们定义 f(x, y) = abs(x - y)。我们需要证明的是,对于X和Y是在[0, 1]中均匀分布的两个独立随机变量,E(X, Y) = 1/3。
如果我们将函数 f 在 3D 中可视化为正方形 [0, 1] x [0, 1] 上的高度场,则 f 下的体积由两个底为半单位正方形的四面体组成,其height 是一个单位高。
E(X, Y) 是 f 下的体积。根据金字塔体积公式,两个四面体中的每一个都有体积 a*h/3,其中 a 是它的底面积,h 是它的高度。这意味着每个四面体的体积为 1/2 * 1 * 1/3 = 1/6,因此 E(X, Y) = 2 * 1/6 = 1/3。
【讨论】:
【参考方案4】:有一个简单自然的方式来看待这个:
如果你有一个区间,比如说<0.0, 1.0>
,并且你从区间中随机选择一个数字,你实际上会将区间分成<0.0, x>
和<x, 1.0>
两部分。
每个部分的平均大小(在许多随机数上)将收敛到0.5
。
现在,如果您从区间中选择两个随机数,您会将区间分成三部分 <0.0, x>
、<x, y>
和 <y, 1.0>
(x < y
)。如果你在许多随机数上计算每个部分的平均大小,它将收敛到1/3
。
这两个数字的平均差就是零件的平均尺寸。
(原为评论)
【讨论】:
【参考方案5】:离散变量法
以 N 个元素细分区间 [0;1](对应 k=1 到 N,X
将取值 k/N
)。稍后我们会让 N 趋于 infty
对于给定的X_k
(其中X
持有值k/N
),计算平均距离,由下式给出
avgDistance(k) = sum_i=1^k (k-i)/N P(Y=i) + sum_i=k+1^n (i-k)/N P(Y=i)
第一项当 y
第一项求和 0 和 k 之间的距离,所以 1/N(k(k+1)/2)
,而第二项求和 1 和 N-k 之间的距离,所以 1/N(N-k)(N-k+1)
。
此外,P(Y=i) = 1/N
对于所有 i(因为 Y
是均匀分布的)
因此
avgDistance(k) = 1/N^2 [ k(k+1)/2 + (N-k)(N-k+1)/2 ] = 1/(2N^2) [ 2k^2 + N^2 - 2kN + N ]
终于
avgDistance = sum_k=1^N avgDistance(k) P(X=k) = 1/N sum_k=1^N avgDistance(k) = 1/(2N^3) sum [ 2k^2 + N^2 - 2kN + N ]
想法是简化总和,如 aN^3 + ...项小于 N^3,因此当 N 趋于无穷大时,我们将简单地得到 aN^3/(2N^3) + 趋于 0
sum 2k^2 = 2(N(N+1)(2N+1))/6 ~ 4N^3/6
sum N^2 = N^3
sum -2kN = -2N(N(N+1)/2 ~= -N^3
因此a = 4/6
和avgDistance = 1/3
【讨论】:
以上是关于关于 JavaScript Math.random() 和基本逻辑的问题的主要内容,如果未能解决你的问题,请参考以下文章
在javascript中math.random()的用法问题?有没有简单一点的说明?谢谢!
JavaScript中Math.random()方法产生的随机数包括0和1吗?