了解 “随机性”

rand()
rand() * rand()

答案

只是一个澄清

尽管每当您尝试发现伪随机变量或其乘积的随机性时,前面的答案都是正确的,但您应该意识到,尽管Random()通常是均匀分布的,但Random()* Random()却并非如此。

这是通过伪随机变量模拟的均匀随机分布样本

Random()的直方图

BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]

这是将两个随机变量相乘后得到的分布:

随机()*随机()的直方图

BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] * 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

因此,两者都是 “随机的”,但是它们的分布却大不相同。

另一个例子

虽然2 * Random()是均匀分布的:

2 * Random()的直方图

BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]

Random()+ Random()不是!

Random()+ Random()的直方图

BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

中心极限定理

中心极限定理指出, Random()的总和会随着项的增加而呈正态分布

仅需四个学期,您将获得:

随机()+随机()+随机()+随机()的直方图

BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
                   Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
                   {50000}],
         0.01]]

通过将 1、2、4、6、10 和 20 个均匀分布的随机变量相加,您可以看到从均匀分布到正态分布的道路:

添加了不同数量的随机变量的直方图

编辑

几个学分

感谢Thomas Ahle在评论中指出最后两幅图像中所示的概率分布称为Irwin-Hall 分布

感谢Heike出色的撕裂功能

我猜这两种方法都是随机的,尽管我的 gutfeel 会说rand() * rand()的随机性较差,因为它将播种更多的零。一旦rand()0 ,则总数变为0

“随机性” 都不是。

rand()基于伪随机种子(通常基于当前时间,该时间总是在变化)生成可预测的一组数字。将序列中的两个连续数字相乘会生成一个不同但同样可预测的数字序列。

要解决这是否会减少冲突,答案是否定的。实际上,由于两个数字相乘的结果会增加冲突,其中0 < n < 1 。结果将是较小的分数,从而导致结果偏向频谱的较低端。

一些进一步的解释。在下文中,“不可预测的” 和 “随机的” 是指某人根据先前的数字猜测下一个数字将是什么的能力。一个甲骨文。

给定种子x ,它将生成以下值列表:

0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...

rand()将生成上面的列表,而rand() * rand()将生成:

0.18, 0.08, 0.08, 0.21, ...

两种方法将始终为相同的种子生成相同的数字列表,因此,甲骨文可以同样地预测它们。但是,如果查看两个调用相乘的结果,尽管原始序列分布良好,但它们都低于0.3 。由于两个分数相乘的结果,这些数字是有偏差的。结果数始终较小,因此尽管仍然不可预测,但很有可能发生碰撞。

过于简化来说明一点。

假设您的随机函数仅输出01

random()(0,1) ,但random()*random()(0,0,0,1)

您可以清楚地看到,在第二种情况下获得0的机会绝不等于获得1


当我首次发布此答案时,我想使其尽可能短,以便阅读该内容的人一眼就能理解random()random()*random()之间的区别,但是我无法阻止自己回答最初的广告问题:

哪个更随机?

就是random()random()*random()random()+random()(random()+1)/2或其他不会导致固定结果的组合具有相同的熵源(或者在伪随机数生成器的情况下,初始状态相同),答案将是它们是同等随机的(不同之处在于它们的分布)。我们可以看的一个完美示例是掷骰子游戏。您得到的数字将是random(1,6)+random(1,6) ,我们都知道获得 7 的机会最高,但这并不意味着掷出两个骰子的结果比随机掷出的骰子具有更多的随机性滚动结果。

这是一个简单的答案。考虑垄断。您掷出两个六个侧面的骰子(对于喜欢游戏符号的人则掷 2d6)并取其总和。最常见的结果是 7,因为有 7 种方式可以滚动 7(1,6 2,5 3,4 4,3 5,2 和 6,1)。而 2 只能在 1,1 上滚动。很容易看出,滚动 2d6 与滚动 1d12 是不同的,即使范围相同(忽略在 1d12 上可以得到 1 的情况,该点也保持不变)。将结果相乘而不是相加,将以类似的方式使结果倾斜,大多数结果出现在范围的中间。如果您要减少异常值,这是一个很好的方法,但它不利于进行均匀分布。

(奇怪的是,它也会增加低位掷骰。假设您的随机性从 0 开始,您会看到一个尖峰在 0,因为它将把其他掷骰变成 0。考虑两个介于 0 和 1(包括 0 和 1)之间的随机数(包括)并相乘。如果任一结果为 0,则无论其他结果如何,整个事物都将变为 0。从中获得 1 的唯一方法是两个掷骰均为 1。实际上,这可能无关紧要但这会使图表变得怪异。)

强制性的xkcd ...
返回4; //由公平骰子选择,保证是随机的。

考虑更多离散数字可能会有所帮助。考虑要生成 1 到 36 之间的随机数,因此您决定最简单的方法是抛出两个 6 面公平的骰子。你得到这个:

1    2    3    4    5    6
  -----------------------------
1|   1    2    3    4    5    6
2|   2    4    6    8   10   12
3|   3    6    9   12   15   18
4|   4    8   12   16   20   24   
5|   5   10   15   20   25   30
6|   6   12   18   24   30   36

因此,我们有 36 个数字,但并不是所有数字都被公平地表示出来,有些根本没有出现。中心对角线(左下角到右上角)附近的数字出现频率最高。

描述骰子之间不公平分配的相同原理同样适用于 0.0 到 1.0 之间的浮点数。

关于 “随机性” 的某些事情是违反直觉的。

假设rand()rand()分布,以下内容将为您提供非均等分布:

  • 高偏差: sqrt(rand(range^2))
  • 中间偏斜峰值: (rand(range) + rand(range))/2
  • 低:偏差: range - sqrt(rand(range^2))

还有许多其他方法可以创建特定的偏差曲线。我对rand() * rand()进行了快速测试,它为您提供了非常非线性的分布。

大多数 rand()实现都有一段时间。即,在经过大量调用之后,序列会重复。 rand() * rand()的输出顺序重复一半的时间,因此在这种意义上是 “随机性较低” 的。

另外,如果没有仔细的构造,对随机值执行算术往往会导致较少的随机性。上面的海报引用了 “ rand() + rand() + rand() ...”(例如,k 倍),实际上,它趋向rand()返回的值范围的平均值的 k 倍。 (这是一个随机步,其步长对称于该均值。)

为了具体起见,假设您的 rand()函数返回范围为 [0,1)的均匀分布的随机实数。 (是的,此示例允许无限的精度。这不会改变结果。)您没有选择特定的语言,并且不同的语言可能会做不同的事情,但是下面的分析对 rand 的任何非正常实现进行了修改( )。乘积rand() * rand()也在 [0,1)范围内,但不再均匀分布。实际上,乘积在间隔 [0,1 / 4)中的可能性与在间隔 [1 / 4,1)中的可能性一样。更多的乘法将使结果更趋向于零。这使得结果更加可预测。在粗笔中,更可预测 == 更少的随机性。

几乎所有对均匀随机输入的操作序列都是非均匀随机的,从而提高了可预测性。谨慎地解决了这一问题,但是在实际需要的范围内生成均匀分布的随机数会比浪费时间更容易。

“随机” 与 “更随机” 有点像问哪个零更为零。

在这种情况下, rand是 PRNG,因此不是完全随机的。 (实际上,如果知道种子,则完全可以预测)。将其乘以另一个值将使其不再或多或少是随机的。

真正的加密类型 RNG 实际上是随机的。通过任何类型的函数运行值都不能为其添加更多的熵,并且很可能会消除熵,从而使其不再具有随机性。