我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
我无法理解这个,哪个更随机?
rand()
OR:
rand() * rand()
我发现这是一个真正的脑筋急转弯,你能帮我吗?
编辑:
直觉上,我知道数学上的答案是它们是同样随机的,但我不禁想,如果你在将两者相乘时“运行随机数算法”两次,你会创建比只做一次更随机的东西。
当前回答
用更离散的数字来考虑可能会有所帮助。考虑一下要生成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之间的浮点数。
其他回答
正如其他人所说,简单的简短答案是:不,它不是更随机的,但它确实改变了分布。
假设你在玩骰子游戏。你有一些完全公平的随机骰子。如果在每次掷骰子之前,你先把两个骰子放在一个碗里,摇晃它,随机选一个骰子,然后掷那一个,掷骰子会更随机吗?显然,这不会有什么不同。如果两个骰子都给出了随机数字,那么从两个骰子中随机选择一个不会有任何区别。无论哪种方式,你都会得到一个介于1和6之间的随机数,在足够数量的卷上均匀分布。
我想在现实生活中,如果你怀疑骰子可能不公平,这样的程序可能会有用。例如,如果骰子稍微不平衡,那么一个骰子往往比1/6的时间更频繁地给出1,而另一个骰子则往往异常频繁地给出6,那么在这两个骰子之间随机选择将有助于掩盖偏差。(尽管在这种情况下,1和6仍然比2、3、4和5多。嗯,我想这取决于失衡的性质。)
随机性有很多定义。随机序列的一个定义是,它是由随机过程产生的一系列数字。根据这个定义,如果我掷一个公平骰子5次,得到数字2、4、3、2、5,那就是一个随机序列。如果我再掷同样的骰子5次,得到1,1,1、1,1和1,那么这也是一个随机序列。
一些海报指出,计算机上的随机函数不是真正随机的,而是伪随机的,如果你知道算法和种子,它们是完全可预测的。这是真的,但大多数时候是完全无关的。如果我洗牌,然后一次翻一张,这应该是一个随机系列。如果有人偷看卡片,结果将是完全可预测的,但根据大多数随机性的定义,这并不会减少随机性。如果该系列通过了随机性统计测试,我偷看卡片的事实不会改变这一事实。在实践中,如果我们在赌你猜下一张牌的能力,那么你偷看这些牌的事实是非常重要的。如果我们使用该系列来模拟访问我们网站的访客的菜单选择,以测试系统的性能,那么你偷看的事实将毫无区别。(只要您不修改程序以利用这些知识。)
EDIT
我认为我无法将我对蒙蒂霍尔问题的回应变成评论,所以我会更新我的答案。
对于那些没有阅读Belisarius链接的人来说,其要点是:游戏节目参赛者可以选择3个门。在一个人的背后是有价值的奖品,在其他人的背后是毫无价值的东西。他选了1号门。在揭示它是赢家还是输家之前,主持人打开3号门,揭示它是输家。然后,他给了参赛者切换到2号门的机会。参赛者是否应该这样做?
答案是,他应该改变,这违背了许多人的直觉。他最初选择的获胜者的概率是1/3,而另一个门获胜的概率是2/3。我和许多其他人的直觉一样,最初的直觉是,切换不会有任何好处,赔率刚刚改为50:50。
毕竟,假设有人在主持人打开丢失的门后打开了电视。那个人会看到剩下的两扇紧闭的门。假设他知道游戏的性质,他会说每个门都有1/2的机会隐藏奖品。观众的赔率是1/2:1/2,而参赛者的赔率却是1/3:2/3?
我真的不得不考虑这一点,才能让我的直觉成形。要了解它,请理解,当我们讨论像这样的问题中的概率时,我们的意思是,在给定可用信息的情况下,您分配的概率。对于将奖品放在1号门后面的工作人员来说,奖品在1号门后的概率为100%,而在其他两个门后面的概率为零。
机组成员的赔率与参赛者的赔率不同,因为他知道参赛者不知道的东西,即他把奖品放在了哪个门后面。同样,竞争对手的赔率与观众的赔率不同,因为他知道观众不知道的东西,即他最初选择了哪扇门。这并不是无关紧要的,因为主人选择打开哪扇门并不是随机的。他不会打开选手选的门,也不会打开隐藏奖品的门。如果这是同一扇门,他就有两个选择。如果它们是不同的门,那么只剩下一扇门。
那么我们如何得出1/3和2/3?当参赛者最初选择一扇门时,他有1/3的机会选择获胜者。我认为这是显而易见的。这意味着有2/3的机会,其他门中的一个获胜。如果东道主给他机会在不提供任何额外信息的情况下进行切换,那就不会有任何收获。同样,这应该是显而易见的。但有一种看法是,他有2/3的机会通过换人获胜。但他有两个选择。因此,每一个人只有2/3除以2=1/3的机会成为赢家,这并不比他最初的选择更好。当然,我们已经知道最终结果,这只是以不同的方式计算。
但现在主持人透露,这两个选择中的一个不是赢家。因此,对于他没有选择的门有2/3的机会获胜,他现在知道,2个备选方案中的1个不是。另一个可能是,也可能不是。因此,他不再有2/3除以2。他打开的门为零,关闭的门为2/3。
浮动随机数通常基于一种算法,该算法产生一个介于零和一定范围之间的整数。因此,通过使用rand()*rand((),您实际上是在说int_rand()*int_rand()/rand_max ^2-这意味着您排除了任何素数/rand_max^2。
这显著改变了随机分布。
rand()在大多数系统中都是均匀分布的,如果正确播种,很难预测。除非你有特殊的理由对其进行数学运算(例如,将分布成形为所需的曲线),否则使用该方法。
关于“随机性”的一些事情是反直觉的。
假设rand()的平面分布,下面将得到非平面分布:
高偏差:sqrt(rand(范围^2))中间偏差峰值:(rand(range)+rand(range))/2低:偏差:范围-sqrt(rand(范围^2))
有很多其他方法可以创建特定的偏置曲线。我对rand()*rand(()做了一个快速测试,它得到了一个非常非线性的分布。
答案将是,这取决于,希望rand()*rand(()比rand)更随机,但如下所示:
两个答案都取决于你的值的位数在大多数情况下,你根据伪随机算法生成(它主要是一个数字生成器,依赖于你的计算机时钟,而不是那么随机)。让你的代码更可读(不要用这种咒语来召唤一些随机的巫毒神)。
好吧,如果你检查上面的任何一个,我建议你使用简单的“rand()”。因为你的代码会更可读(不会问自己为什么要写这个,时间……嗯……超过2秒),易于维护(如果你想用super_rand替换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结果。