我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
当前回答
根据您的计算机体系结构,相乘数字最终会得到更小的解决方案范围。
如果您的计算机显示16位数字,rand()将为0.1234567890123乘以第二个rand(),0.1234567890123,将得到0.0152415如果你把实验重复10^14次,你肯定会找到更少的解决方案。
其他回答
很容易证明两个随机数之和不一定是随机的。假设你有一个6面骰子。每个数字有1/6的机会出现。现在假设你有2个骰子,并将结果相加。这些总数的分布不是1/12。为什么?因为某些数字比其他数字更多。它们有多个分区。例如,数字2仅是1+1的和,但7可以由3+4、4+3或5+2等组成,因此它出现的机会更大。
因此,在本例中,对随机函数应用变换(在这种情况下为加法)不会使其更随机,或必然保持随机性。在上述骰子的情况下,分布偏向于7,因此随机性较小。
关于“随机性”的一些事情是反直觉的。
假设rand()的平面分布,下面将得到非平面分布:
高偏差:sqrt(rand(范围^2))中间偏差峰值:(rand(range)+rand(range))/2低:偏差:范围-sqrt(rand(范围^2))
有很多其他方法可以创建特定的偏置曲线。我对rand()*rand(()做了一个快速测试,它得到了一个非常非线性的分布。
大多数这种分布发生是因为你必须限制或规范随机数。
我们将其标准化为全部为正,符合范围,甚至符合指定变量类型的内存大小限制。
换句话说,因为我们必须将随机调用限制在0和X之间(X是变量的大小限制),所以我们将有一组介于0和X的“随机”数。
现在,当你将随机数与另一个随机数相加时,总和将介于0和2X之间。。。这会使值偏离边缘点(当两个随机数在较大范围内时,将两个小数字相加和将两个大数字相加的概率非常小)。
想象一下这样一个例子,你有一个接近于零的数字,你将它与另一个随机数相加,它肯定会变大,远离0(这对于大数字是正确的,因为随机函数不可能两次返回两个大数字(接近于X的数字)。
现在,如果你用负数和正数设置随机方法(跨越零轴),情况将不再如此。
例如,假设RandomReal({-x,x},50000,.01),那么你会得到负数和正数的偶数分布,如果你将随机数相加,它们将保持其“随机性”。
现在我不确定Random()*Random(()从负到正的跨度会发生什么。。。这将是一个有趣的图表。。。但我现在得回去写代码了-P
根据您的计算机体系结构,相乘数字最终会得到更小的解决方案范围。
如果您的计算机显示16位数字,rand()将为0.1234567890123乘以第二个rand(),0.1234567890123,将得到0.0152415如果你把实验重复10^14次,你肯定会找到更少的解决方案。
大多数rand()实现都有一定的周期。也就是说,在大量的调用之后,序列会重复。rand()*rand(()的输出序列在一半时间内重复,因此在这个意义上它“不那么随机”。
此外,如果没有仔细的构造,对随机值执行算术往往会导致较少的随机性。上面的一张海报引用了“rand()+rand(()+rand()…”(例如,k倍),这实际上会倾向于rand(返回值范围的平均值的k倍。(这是一种随机行走,步数与平均值对称。)
具体来说,假设rand()函数返回[0,1)范围内的均匀分布随机实数。(是的,这个例子允许无限精度。这不会改变结果。)您没有选择特定的语言,不同的语言可能会做不同的事情,但以下分析适用于对rand()的任何非反常实现的修改。乘积rand()*rand(()也在[0,1)范围内,但不再均匀分布。事实上,乘积在区间[0,1/4)和区间[1/4,1)中的可能性一样大。更多的乘法将使结果进一步趋向于零。这使得结果更可预测。在广义上,更可预测的==更少的随机性。
几乎所有对均匀随机输入的操作序列都是非均匀随机的,从而提高了可预测性。小心的话,我们可以克服这一特性,但这样就可以更容易地在实际需要的范围内生成一个均匀分布的随机数,而不是在算术上浪费时间。