MATLAB博客

给处于领先地位的人的实用建议

[6 3 7 8 5 1 2 4 9 10]——或《关于随机性的惊奇故事》

早在3月底,Tom Rhys Marshall就发现了MATLAB处理随机数的一些令人惊讶和担忧的事情!
randperm 函数生成一个随机的整数排列 randperm (10) 将以随机顺序返回从1到10的所有整数。在一个新的MATLAB会话中,“随机”顺序总是相同的
randperm (10)
ans = 1×10
6 3 7 8 5 1 2 4 9 10
正如汤姆和其他人所指出的,世界分为两种人:一种人认为这很好,众所周知,另一种人不知道这是真的,非常惊讶和担心。
如果我告诉你....计算机上的随机数并不是随机的!
出于法律原因,我被告知我不能在这个博客上使用知名的表情包,但你可能知道我心中的那个对吧?无论如何,在像MATLAB, Python或R这样的软件中,随机数的特点是它们不是随机的。它们是完全确定的。然而,根据设计,这些返回的数字 随机数算法与真正的随机数具有相同的统计数据, 只要我们小心 ,我们可以用M 蒙特卡罗模拟等等,好像一切都是随机的。
让我再说一遍。 在大多数现代编程语言和仿真平台中使用的所有“随机”数字生成器都是完全确定的 .如果你打算使用随机数做任何严肃的事情,那么这是你迟早要学习的一课。
很长一段时间以来,MATLAB的随机数生成器使用的默认算法被称为 梅森素数捻线机 .与许多其他实现一样,MathWorks对此的实现将根据您设置的“种子”为您提供不同的随机数集。种子是一个整数,并使用 rng () 函数。当你开始用MATLAB时,t 种子默认设置为0。
rng (0)
randperm (10)
ans = 1×10
6 3 7 8 5 1 2 4 9 10
不同的种子会产生不同的结果
rng (1)
randperm (10)
ans = 1×10
3 6 5 7 4 8 9 1 10 2
有些人似乎认为你必须对种子做一些奇特的事情,以获得“更随机”的数字,但事实并非如此。 您可以使用任何整数,并且对于大多数常见的、简单的随机数使用都很好(在处理并行模拟时变得更加复杂! 相关参考文献见文末)。
设计选择:启动时种子应该是什么?
如果你看汤姆的回复 twitter的线程 你会看到一些人指出,其他一些系统不像MATLAB那样运行。例如,Python中的默认生成器在每次启动时都会(可能)给你一组不同的随机数。这并不是因为这些系统在某种程度上比MATLAB更随机,而是因为它们选择了不同的设置种子的方式。
在启动时设置种子的常用方法是利用系统时间。其思想是使用当前时间生成一个整数,并将其作为种子。瞧!每次你启动你的系统,你得到一个不同的种子,因此一组不同的随机数。
你也可以在MATLAB中使用 rng(“洗牌”)
rng (“洗牌”)使用系统时钟设置种子
randperm (10)
ans = 1×10
7 4 5 6 1 3 9 2 10 8
现在可以说(很多人在推特上说了!)这比MATLAB在启动时总是使用相同的种子更好。认为这是一个好主意的论据包括:
  • 它更随机(当然每次都不一样。这可能有用,也可能没用。)
  • 人们可以运行两个会话并获得“独立”结果(也许!在实践中,它更微妙,有一个更好的方法来做到这一点。用这种方法产生的两个序列在统计上是独立的,虽然你可能会侥幸逃脱。)
然而,在过去的某个时候,设计决策是在MathWorks进行的 可重复性高于所有其他问题……这是我们的许多用户所依赖的。使用系统时钟为随机数生成器提供种子(而不记录实际使用的种子)是可再现性的诅咒。
如果您不同意这个设计决定,那么您可以继续使用 rng(“洗牌”) 我们不介意!
错误报告:我的“随机”数字不同
早在2008年,MathWorks就改变了MATLAB编程语言使用的默认算法,结果搞得一团糟。许多MATLAB用户提交了错误报告,因为他们的测试失败了。事实证明,一些用户用精确的可重复随机数来验证算法,当这些随机数发生变化时,他们会非常沮丧。当然,一直都可以调整所使用的算法和种子,但许多人使用默认设置。可以说这是一种糟糕的做法,但非常普遍!
MathWorks不得不忍受默认的改变,因为旧算法存在基本问题。梅森扭扭机就是为了解决这个问题而设计的。快进到2022年,对于很多工作来说,Mersenne Twister仍然是一个不错的选择,当用户想要或需要不同的东西时,MathWorks已经为这些情况添加了几个额外的可选算法。
MathWorks不会轻易改变默认行为!我们有数百万的用户,他们依赖于事物本身的方式。
我的故事:为什么使用系统时钟作为种子并不总是一个好主意
很久以前,在我了解计算机上的随机数方法之前,我是曼彻斯特大学一群极客中的一员,他们使用一种叫做秃鹰的技术,把大学所有的台式计算机变成了一台特别的超级计算机。按照当时的标准,这是一个相当大的资源,在高峰时大约有5000个CPU内核可用。我们渴望用户。
一位研究人员向我们提供了一个完美的应用程序。是M onte-Carlo 用MATLAB以外的东西编写的仿真程序,他在一个周末完成了几十年的CPU时间。他非常高兴,直到他开始筛选结果。
每次他在桌面上运行模拟,他都得到了不同的结果,正如预期的那样。但是在我们的系统中,他会得到一组相同的结果。有时只有几个相同的结果,有时是数百个,没有明显的模式。我们当时很困惑,因为我们不清楚随机数到底是如何工作的。
我们使用的所有电脑都通过互联网进行了系统时钟同步。许多(但不是所有)作业在完全相同的时间启动,因此它们具有完全相同的种子,因此具有相同的随机数流。
在这篇文章的前面,我说过“ 在大多数现代编程语言和仿真平台中使用的所有“随机”数字生成器都是完全确定性的。 每个随机数生成器的用户都需要学习这个。
这是我的时代!你的生日是什么时候?
了解更多
随机数是一个很流行的话题 这些年来的一些博客文章,更不用说官方的MATLAB文档了。如果你想更深入地了解这一切,我推荐一些方法。
感谢Peter Perkins和Michelle Hirsch的校对和建议。剩下的错误都是我的!
|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。