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

rand()

OR:

rand() * rand()

我发现这是一个真正的脑筋急转弯,你能帮我吗?


编辑:

直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。


当前回答

使用实现原始多项式的线性反馈移位寄存器(LFSR)。

结果将是一个2^n个伪随机数的序列,即在序列中没有重复,其中n是LFSR中的位数。。。。导致均匀分布。

http://en.wikipedia.org/wiki/Linear_feedback_shift_registerhttp://www.xilinx.com/support/documentation/application_notes/xapp052.pdf

使用基于计算机时钟的微信号的“随机”种子,或者可能是文件系统中一些不断变化的数据的md5结果的子集。

例如,32位LFSR将从给定种子开始按顺序生成2^32个唯一数字(没有2个相同)。序列将始终按照相同的顺序,但对于不同的种子,起点将不同(显然)。因此,如果种子之间可能重复的序列不是问题,那么这可能是一个不错的选择。

我已经使用128位LFSR在硬件模拟器中使用种子生成随机测试,该种子是对不断变化的系统数据的md5结果。

其他回答

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

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

当你对随机数的组合会发生什么感到怀疑时,你可以利用你在统计理论中学到的经验。

在OP的情况下,他想知道X*X=X^2的结果是什么,其中X是沿统一[0,1]分布的随机变量。我们将使用CDF技术,因为它只是一对一映射。

由于X~Uniform[0,1],其cdf为:fX(X)=1我们需要转换Y<-X^2,因此Y=X^2求逆x(y):sqrt(y)=x,这给出了x作为y的函数。接下来,求导数dx/dy:d/dy(sqrt(y))=1/(2sqrt(y)

Y的分布如下:fY(Y)=fX(x(Y))|dx/dy |=1/(2 sqrt(Y)

我们还没有完成,我们必须得到Y的域,因为0<=x<1,0<=x^2<1因此Y在范围[0,1)内。如果你想检查Y的pdf是否真的是pdf,请在域中集成它:从0到1集成1/(2 sqrt(Y)),实际上,它会弹出为1。此外,请注意所述函数的形状看起来像belisarious发布的内容。

至于X1+X2+…+Xn,(其中Xi ~一致[0,1]),我们可以求助于中心极限定理,它适用于存在矩的任何分布。这就是Z检验存在的原因。

用于确定生成的pdf的其他技术包括雅可比变换(这是cdf技术的广义版本)和MGF技术。

编辑:作为澄清,请注意,我所说的是结果转换的分布,而不是其随机性。这实际上是一个单独的讨论。我实际上得到的是(rand())^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(),它可以有时有助于将两个样本混合在一起——尽管,如果真的是盈亏平衡的话那个程序没用。

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

假设rand()的平面分布,下面将得到非平面分布:

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

有很多其他方法可以创建特定的偏置曲线。我对rand()*rand(()做了一个快速测试,它得到了一个非常非线性的分布。