我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
当前回答
过度简化以说明一点。
假设随机函数只输出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的几率最高,但这并不意味着掷两个骰子的结果比掷一个骰子的效果更随机。
其他回答
关于“随机性”的一些事情是反直觉的。
假设rand()的平面分布,下面将得到非平面分布:
高偏差:sqrt(rand(范围^2))中间偏差峰值:(rand(range)+rand(range))/2低:偏差:范围-sqrt(rand(范围^2))
有很多其他方法可以创建特定的偏置曲线。我对rand()*rand(()做了一个快速测试,它得到了一个非常非线性的分布。
只是一个澄清
尽管每当你试图发现伪随机变量或其乘法的随机性时,前面的答案都是正确的,但你应该知道,虽然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()均匀分布时:
BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]
随机()+随机()不是!
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个均匀分布的随机变量相加,可以看到从均匀分布到正态分布的道路:
Edit
几个学分
感谢Thomas Ahle在评论中指出,最后两张图片中显示的概率分布称为Irwin Hall分布
感谢Heike出色的撕裂功能
这不是很明显,但rand()通常比rand(*rand)更随机。重要的是,对于大多数用途来说,这实际上不是很重要。
但首先,它们产生了不同的分布。如果这是你想要的,这不是问题,但这很重要。如果你需要一个特定的分布,那么忽略整个“哪个更随机”的问题。那么为什么rand()更随机呢?
rand()之所以更随机(假设它产生的是[0..1]范围内的浮点随机数,这是非常常见的)的核心是,当你将两个FP数与尾数中的大量信息相乘时,你会在结尾处丢失一些信息;IEEE双精度浮点中没有足够的位来保存从[0..1]中均匀随机选择的两个IEEE双精度浮点数中的所有信息,这些额外的信息位将丢失。当然,这无关紧要,因为你(可能)不会使用这些信息,但损失是真实的。您产生哪种分布(即,使用哪种操作进行组合)也并不重要。这些随机数中的每一个都有(最多)52位随机信息——这就是IEEE双精度的容量——如果你将两个或多个随机数合并为一个,那么你仍然只能拥有最多52位的随机信息。
大多数随机数的使用甚至没有使用随机源中实际可用的那么多随机性。得到一个好的PRNG,不要太担心它。(“好”的程度取决于你在用它做什么;你在做蒙特卡洛模拟或密码学时必须小心,否则你可能会使用标准PRNG,因为这通常要快得多。)
好的,所以我会尝试添加一些值来补充其他答案,说你正在创建和使用一个随机数生成器。
随机数发生器是一种具有多种特性的设备(从非常普遍的意义上讲),可以根据需要进行修改。其中一些(来自我)是:
熵:如香农熵分布:统计分布(泊松、正态等)类型:数字的来源(算法、自然事件、组合等)和应用的算法。效率:执行的速度或复杂性。模式:周期、顺序、运行等。也许还有更多。。。
在这里的大多数答案中,分布是主要的关注点,但通过混合和匹配函数和参数,您可以创建生成随机数的新方法,这些随机数将具有不同的特征,其中一些特征乍一看可能不明显。
使用实现原始多项式的线性反馈移位寄存器(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结果。