【程阳解答】
EXCEL VBA Randomize 生成随机数的误区
更多的【程阳解答】
一个Excel_VBA随机性比对程序_06.xls
【网友问题】 来自博文留言【点击查看】
程阳老师,上面第13、14两图,也是我关心的。可是事实上很难呀,彩票的“机选”就不是随机的,而且很不随机,经常是几个号码扎堆。随便翻报纸选号,就像您说的,也不随机。我用EXCEL编了个小程序,想生成随机数Rand(),可是号码序列竟然会经常重复!真实郁闷,说白了可能最随机的数,还是把号码写在扑克牌上,洗牌抽取。可是,又太罗嗦啦。请老师指点!谢谢!
【程阳解答】
这位不知名的网友,你提到的博文中“第13、14两图”,我们在放在这里,大家可是进行分析,其实即使彩票从业者,大多数人对此也是毫无头绪的。你的言语告诉我,你对彩票随机性有相当的理解,否则我的解答还真是很难进行。
随机性研究,是一项很重要的研究领域,这方面的成果汗牛充栋,我本人1980年代也做过随机性相关研究工作,主要是用于工业控制与检测方面。而随机性则是彩票的命门,其重要性怎么说都不过分,只不过中国彩票业研究随机性的人确实很少。这里,考虑大多数彩票同仁的理解,我尽量把你的问题,解释的通俗易懂些,冗长深奥的随机性理论我们就不谈了。
总的来说,要生成随机数,无非就是三种方法:
第一是用物理器件。这种类型的芯片现在很多,同一系列等级从军用、工业用、民用性能差异也是数量级,例如现在多数快速游戏的开奖,就是使用的这类芯片生成随机数,再通过软件转换为开奖号码。尽管这类方法可以生成所谓“真随机”数,但那是对大众理解来说的,事实上要研究解决的问题永远存在,众多学者对此的研究从无停息。
第二是软件编程与物理事件结合的方法。例如可以把鼠标的运动轨迹“当成”一种物理事件,并用相关编程,最大限度地“发挥”该物理事件的随机性。这类方法,我以为是一个不上不下的方法,在现今意义已经不大,因为如果要工业、商业应用直接用“真随机”芯片更加简单,要简单玩玩编程就能实现。
第三种就是纯软件编程实现的方法。总所周知,这种方法生成的随机数,是“随机质量”很差的“伪随机”数,但是因为简单,现实中也经常使用在要求不高的场合,例如彩票号码的“机选”就可以此来简单实现,所以也会产生一些让人“揪心”的结果,并引起有关媒体的猜疑。这里要说的,许多媒体和百姓把“伪随机”当成了“作假”,其实是很片面的。其实说白了,不是彩票机构不想更加“随机”,而是理论和技术上有困难,或者要实现成本过于巨大。简单的比喻,都知道数学理论上有“圆”,但“真正的圆”现实物理世界中是没有的,地球是圆的吗?足球是圆的吗?车轮是圆的吗?彩票号球是圆的吗?严格说的都不是!甚至圆规画出来的都不是100%的“圆”,这就数学理论与现实物理世界的区别。
既然任何计算机程序语言都不可能生成真正的随机数,都是“伪随机”数,那么如何最大限度地接近真随机,就是编程者的水平问题啦。你使用的EXCEL VBA 用 Rand() 【程序中用Rnd()】函数生成随机数,出现号码序列经常重复的现象,可能的情况是——
1、 忽略了Randomize 的使用。在程序开始,使用一次 Randomize 初始化是Rand() 能够随机的前提;
2、 错误地多次使用Randomize 。这方面,大多数 EXCEL 的教科书甚至都是错误的,特别是在大多数使用 Rand()进行循环产生序列随机数的案例中,基本都错了。有些人认为Randomize 既然是“随机化”的,所以多多益善,在所有Rand()循环中多次调用。我只能告诉大家,这样的“后果很严重”。
题图,给出了一个 EXCEL VBA 随机性比对的案例:“排序法”直接在页面使用Rand(),并与彩票号码两列等长排列,然后以Rand()的大小为序排序,这样可以形成一组随机彩票号码;“R一次法”“R多次法”就是上面说的使用一次、多次Randomize。我们看到,随着“模拟彩票销额”的增加,“排序法”“R一次法”的返奖率,都慢慢向50%的理论返奖率靠拢“收敛”,而“R多次法”由于严重的非随机性,导致结果“不收敛”。这是十分严重的事情,有些地方用计算机“抽号”时,发生的很多匪夷所思的现象,也许不一定是作假,而是“水平有限”所致。