为什么随机不随机?

Ste*_*las 4 random programming-languages

有人可以解释现代编程语言(java,c#,python,javascript)如何应对随机性的限制以及这些限制(例如基于时间的种子)的起源.即如果它们是由底层操作系统和基于intel的硬件强加的.

基本上我想理解为什么没有适当的硬件就没有真正的随机数.

Rev*_*nzo 8

设计软件是确定性的.因此,通常生成随机数的方式是使用以统计随机顺序吐出数据的公式.这样,任何需要均匀分布数字的程序都可以根据某些物理数据(即:时间戳)设置种子,并获得看似随机的数字集.但是,给定一组特定的输入,软件将始终以相同的方式执行.

要拥有真正的随机性,需要输入不确定性.

引用维基百科,

要生成真正的随机数,需要对绝对非确定性过程进行精确,准确和可重复的系统测量.例如,开源操作系统Linux使用各种系统时序(如用户击键,I/O或最低有效数字电压测量)来产生随机数池.它会尝试不断补充池,具体取决于重要性级别,因此会发出一个随机数.该系统是一个例子,类似于专用硬件随机数发生器.

  • 米兰:您可能还会注意到,有些应用程序不需要"真正的"随机性,例如模拟.在这里复制模拟运行*精确*的选项具有很大价值,因此其他人可以重现其他人的发现.类似地,也存在*准随机*序列,它们甚至不具有随机随机性但接近完美的均匀性 - 例如,这些对于蒙特卡罗模拟是重要的. (3认同)

Ant*_*sky 6

我将首先回答你问题的第二部分:

基本上我想理解为什么没有适当的硬件就没有真正的随机数.

没有特殊硬件,您无法在计算机上生成真正的随机数,因为计算机是确定性计算机.这意味着,给定一些初始状态和执行操作,您可以准确预测机器将如何演变.例如,如果您知道,在一些假设的体系结构中,该寄存器%d0包含24和寄存器%d1包含42,并且您知道指令流中的下一条指令,则add %d0 %d1 %d2您知道在执行该指令%d2后将包含该指令66.在一个更高层次的语言,你知道写作x = 1; y = 2; z = x + y 导致z3肯定.

这是有道理的; 我们不想知道添加会做什么,我们希望它添加.但是,这与生成真正的随机数不相容.对于一些是真正随机的,需要有绝对没有办法预测它,不管你知道是什么.某些量子力学过程精确地具有这种行为,并且其他自然过程足够接近随机,对于所有实际目的而言,它们是(例如,如果它们看起来是随机的并且预测它们将需要知道大气中每个分子的状态) ).但是,计算机无法做到这一点,因为整拥有一台计算机就是拥有一台确定性地执行代码的机器.您需要能够预测运行程序时会发生什么,否则重点是什么?

你对米兰拉玛雅的回答发表评论

我同意你的意见,但仍然缺少最重要的事情 - 为什么计算机无法生成具有预先确定输入的随机数?

答案直接来自真正随机数的定义.由于真正的随机数需要完全不可预测,因此它永远不会依赖于确定性输入.如果您的算法采用预先确定的输入并使用它来生成伪随机数,则只要您知道输入和算法,就可以随意复制此过程.

你也问过

有人可以解释现代编程语言如何应对随机性的局限性以及这些局限性......的起源.

好吧,如上所述,这些限制是我们的语言和机器的确定性设计所固有的,这是有充分理由的(因此所述语言和机器是可用的:-)).假设您没有调用可以访问真正随机数的东西(例如/dev/random在存在真实随机数的系统上),则采用的方法是使用伪随机数生成器.这些算法旨在产生统计随机性输出序列 - 在正式意义上看起来不可预测的输出序列.我不知道足够的统计数据来解释或理解这个细节,但我相信这个想法是你可以运行某些数字测试来判断你的数据预测自己(在某种松散的意义上)以及类似的事情.然而,重要的是,虽然序列是确定性的,但它"看起来是随机的".出于很多目的,这已经足够了!有时候它有一些优点:例如,如果你想测试代码,能够指定一个种子并且总是让它接收相同的伪随机数序列会很好.

总之,您的问题的总体答案是:因为我们希望能够预测计算机做什么,所以它们无法生成不可预测的数字(没有特殊硬件).编程语言通常不会受此影响太大,因为伪随机数生成器对于大多数情况来说已经足够了.