我无法理解这个,哪个更随机?

rand()

OR:

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实际上是随机的。通过任何类型的函数运行值都不能增加更多的熵,而且很可能会删除熵,使其不再随机。

根据您的计算机体系结构,相乘数字最终会得到更小的解决方案范围。

如果您的计算机显示16位数字,rand()将为0.1234567890123乘以第二个rand(),0.1234567890123,将得到0.0152415如果你把实验重复10^14次,你肯定会找到更少的解决方案。

大多数这种分布发生是因为你必须限制或规范随机数。

我们将其标准化为全部为正,符合范围,甚至符合指定变量类型的内存大小限制。

换句话说,因为我们必须将随机调用限制在0和X之间(X是变量的大小限制),所以我们将有一组介于0和X的“随机”数。

现在,当你将随机数与另一个随机数相加时,总和将介于0和2X之间。。。这会使值偏离边缘点(当两个随机数在较大范围内时,将两个小数字相加和将两个大数字相加的概率非常小)。

想象一下这样一个例子,你有一个接近于零的数字,你将它与另一个随机数相加,它肯定会变大,远离0(这对于大数字是正确的,因为随机函数不可能两次返回两个大数字(接近于X的数字)。

现在,如果你用负数和正数设置随机方法(跨越零轴),情况将不再如此。

例如,假设RandomReal({-x,x},50000,.01),那么你会得到负数和正数的偶数分布,如果你将随机数相加,它们将保持其“随机性”。

现在我不确定Random()*Random(()从负到正的跨度会发生什么。。。这将是一个有趣的图表。。。但我现在得回去写代码了-P

这不是很明显,但rand()通常比rand(*rand)更随机。重要的是,对于大多数用途来说,这实际上不是很重要。

但首先,它们产生了不同的分布。如果这是你想要的,这不是问题,但这很重要。如果你需要一个特定的分布,那么忽略整个“哪个更随机”的问题。那么为什么rand()更随机呢?

rand()之所以更随机(假设它产生的是[0..1]范围内的浮点随机数,这是非常常见的)的核心是,当你将两个FP数与尾数中的大量信息相乘时,你会在结尾处丢失一些信息;IEEE双精度浮点中没有足够的位来保存从[0..1]中均匀随机选择的两个IEEE双精度浮点数中的所有信息,这些额外的信息位将丢失。当然,这无关紧要,因为你(可能)不会使用这些信息,但损失是真实的。您产生哪种分布(即,使用哪种操作进行组合)也并不重要。这些随机数中的每一个都有(最多)52位随机信息——这就是IEEE双精度的容量——如果你将两个或多个随机数合并为一个,那么你仍然只能拥有最多52位的随机信息。

大多数随机数的使用甚至没有使用随机源中实际可用的那么多随机性。得到一个好的PRNG,不要太担心它。(“好”的程度取决于你在用它做什么;你在做蒙特卡洛模拟或密码学时必须小心,否则你可能会使用标准PRNG,因为这通常要快得多。)

过度简化以说明一点。

假设随机函数只输出0或1。

random()是(0,1)之一,但random(()*random(是(0,0,0,1)之一

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


当我第一次发布这个答案时,我希望尽可能简短,以便阅读它的人一眼就能理解random()和random(*random)之间的区别,但我无法阻止自己回答最初的广告垃圾问题:

哪个更随机?

如果random()、random(()*random()、random()+random(()、(random(+1)/2或任何其他不会导致固定结果的组合具有相同的熵源(或者在伪随机生成器的情况下具有相同的初始状态),那么答案将是它们具有相同的随机性(差异在于它们的分布)。我们可以看到的一个完美的例子是Craps游戏。你得到的数字将是随机的(1,6)+随机的(6,6),我们都知道得到7的几率最高,但这并不意味着掷两个骰子的结果比掷一个骰子的效果更随机。