certificate一个随机生成的数字是均匀分布的

我在接受采访时被问到了这个问题。

给定一个随机数发生器产生一个数字[0,N),如何certificate这个数是均匀分布的。

我不知道如何解决这个问题,有什么build议吗?

为了certificate这一点,你需要知道正在使用的algorithm,并用图表的forms表示,所有状态的集合构成一个循环,没有子循环,并且状态空间模N的基数为零,所以没有比其他人更频繁地出现的一组状态。 例如,我们知道Mersenne Twister是均匀分布的,尽pipe64位版本的周期长度为2 19937 -1,并且在宇宙的生命周期内永远不能被枚举。

否则,你使用统计testing来testing均匀性的假设。 统计不能certificate结果,它不能反驳这个假设。 样本量越大,推翻假设的失败就越引人注目,但这绝不是certificate。 (这种观点与非统计学家/非科学家相比,会导致更多的沟通问题,而不是我所知道的任何其他问题。)有许多统一性testing,包括卡方检验,Anderson-Darling和Kolmogorov-Smirnov等等。

所有的均匀性testing都会传递如0,1,2,…,N-1,0,1,…这样的值序列,所以一致性不足以说明你有一个好的发生器。 您还应该testing与testing的序列相关性,例如间距testing,运行/运行,运行在平均值之上/之下,“生日”testing等等。

George Marsaglia在其职业生涯中创造了一套非常全面的统一性和序列相关性testing,并在1995年发表了他被开玩笑称为“ Diehardtesting ”(因为它是一个重型testing电池)。

对于黑盒testing(你没有访问源代码),你不能certificate它是均匀分布(UD)。 但是,您可以执行统计testing来查找UD的可能性。 多次运行发生器(比如N * X次),每个0到N之间的数字应该出现在X次左右。

这完全忽略了它是否是随机数,它只关注一致性。 但是,如果你要进行无限的testing,它只能certificate发生器是均匀分布的。 最好的情况是,在第一次N * X迭代期间,发生器的概率是一致的,但实现简单易行。

没有办法certificate这一点,因为发电机可能首先产生一个均匀的分布,然后偏离成一个不均匀的分布。

既然这是一次面试,真正的问题不是要certificate是一致的分配,真正的问题是要得到工作的select。 我会build议一种方法,让你快速决定面试官是在寻找一个关于高等math的有趣的讨论,或者是testing你的实践思维。 我的猜测是,面试官很有可能会find后者。 一个好的采访答案可能是这样的:“这一切都取决于随机数发生器的需要,如果它在音乐播放器上提供一个shuffle函数,我会让它产生100个数字,检查平均值是否大致等于N / 2 ,接下来简要介绍一下这些数字,在这一点上可以得到满足,如果目的是与encryption相关,那么这将是一个不同的故事,我会开始研究,但最终可能不会自己certificate,而是依靠在现有的,独立的证据“。

发电机只有一个号码,还是你想要的号码? 如果只有一个,你不能说一致性。 只要0≤数字<N,没关系。

假设面试官的意思是“大量结果的一致性”,则需要考虑结果的分布和结果中的模式。 首先是对结果进行sorting和分类,然后查看生成的直方图。 对于大量的数值,它应该是合理的“平坦的”(例如,不是高斯曲线)。

第二个testing有点困难,因为你可能会得到2,3,甚至4或更多的数字。 我所看到的一个三联体testing是以三个一组的方式(球面坐标(第一个是方位angular,第二个是高度,第三个是半径))绘制结果。 我不记得细节,但IIRC你应该看到一个统一填充的球体,或类似的东西。 这个testing可能有一个正式的术语,但底线是有很多testing来看看RNG在做什么,所以下一个数字很难从最后一个数字中预测出来(没有明显的模式) 。

我开始问他们多久会想要一个答案,一旦你有发电机,他们会想要多好的答案。

是的,如果你想彻底的运行一套全面的统计testing,那就太好了。 但是这可能需要几天或几周的时间。 在某些情况下,这个问题可能会在一个会议中被问到一堆想要立即回答的人,最好的答案可能就是在会议上使用google来查看发电机是否足够好其他用户。 “快速谷歌”和“综合testing”之间有一系列的答案。

要提到的是,在现实中你不能certificate发生器在所有情况下都是100%统一的。 这些情况是:

1)你不能看源代码。 所以,即使生成N个统一的随机数字,也无法知道N + 1中的每个数字是10(例如),而不会生成更多的数字。 无论你停在哪里,都不能对你还没有产生的数字作出任何声明

2)你可以看看源代码。 除非它是一个非常简单的线性同余发生器,否则它可能太难以理解了。 如果太丑了,我会说除了欣赏代码之外,你可能无法得出任何可靠的结论。

尽pipe风险很大,但值得一提的是,如果应用程序对随机数生成器的调用数量可预测,那么您可以testing该生成器以进行多次调用。 但是,我看到一些采访者会误解这一点,并假设你不知道如何制作稳健和可扩展的algorithm。

普林斯顿math课程中有关于此的讨论

但是,如何使用确定性的计算机来select10 30和10 31之间的一万个随机数呢? 答案是,实际上并不需要:几乎总是可以做一个伪随机select。 …

我们什么时候应该把这样一个序列看作“随机”? 再次提出了许多不同的答案。 一个想法是考虑简单的统计testing:我们预计从长远来看,零的频率应该与1的频率大致相同,并且更一般地,诸如00110的任何小的子序列应该以“正确的”频率出现(这对于这个序列1/32将是因为它具有长度5)。

然而,完全可能的是,一个序列通过这些简单的testing,但是通过一个确定性的过程来生成。 如果试图确定零和零序列是否实际上是随机的 – 也就是说,通过掷硬币等手段产生 – 那么如果我们能够识别产生相同序列的algorithm,那么我们将非常怀疑序列。 例如,即使通过统计testing,我们也会拒绝从π的数字中以简单的方式导出的序列。 然而,仅仅要求一个recursion过程不能产生一个序列就不能给出一个好的随机性检验:例如,如果一个序列采用任何这样的序列,并用零来replace序列的序列,那么就得到一个新的序列远不是随机的,而是仍然不能recursion地产生。

出于这个原因,冯·米塞斯在1919年提出,一个零和一个序列应该被称为随机,如果不仅是1的频率的限制是1/2的情况,而且对于任何子序列也是如此可以通过一个合理的程序来提取。“1940年,教会通过将”通过合理的程序“翻译成”借助recursion函数“来更精确地说明这一点。然而,即使这个条件太弱,是不符合“迭代对数定律”(随机序列满足的)的序列。 目前,所谓的Martin-Löf论文是1966年制定的,是随机性最常用的定义之一:随机序列是一个满足所有“有效的统计顺序testing”的序列,我们不能在这里准确地制定,但是以基本方式使用recursion函数的概念。 与教会的几乎每个math家都同意的论点相比,Martin-Löf论文仍然在讨论中。

对于一个采访来说,这是一个有点残酷的问题(除非这是一个研究的位置),但是对于一个论坛来说这是一个有趣的问题。 20年前,在完成math学位后,我会快乐地提出一个由我自己写的随机数发生器,它是随机的mathcertificate。 现在看这个代码,我很难相信我写的。 现在,我做什么实际的程序员会做什么,并使用由NAG,numpy,matlab或其他一些备受尊敬的软件包(我相信NAG)实现的algorithm,也许做一些简单的统计分析来validation,如果分布是至关重要的出于某种原因或其他原因。

采访中重要的事情是说实话。 如果你不知道,那么告诉他们你必须查找它。 如果你不知道,也没有兴趣去查,那也可以告诉他们。 做一个需要不断研究的具有挑战性的工作,必须由雇主提供良好的工作环境。 挑战是好的,但是对抗性和竞争性是反效果的(太多的C)。