admin 管理员组文章数量: 1086019
2024年3月7日发(作者:php根目录是什么)
维普资讯
计算机科学2006Vo1.33No.12(增刊) 伪随机数及其在JAVA程序中的应用探讨 王 字 (重庆文理学院 重庆402160) 摘要本文分析了生成伪随机数的一般原理,讨论了采用线性同余法获取伪随机数的方法,结合JAvA语言产 生伪随机数的机制,通过一个游戏程序实例说明伪随机数的应用。 关键词 线性同余法,伪随机数生成,JAVA程序设计 1 引言 随机数是蒙特卡罗(Monte-Carlo)方法的应用 基础,它在程序设计中扮演着十分重要的角色,尤其 是在实践环境模拟和测试等领域中有着广泛的应 用。例如,构建随机模型、大型游戏、计算机仿真、动 画设计、数字图书保护、数字水印、分形图形技术、数 据加密等都要大量使用随机数。 所谓随机数,是指满足如下两个条件的数值序 列: ①满足一个确定的概率分布; ②序列的任意数值之间相互独立。 产生随机数的方法有两种: ①用物理方法产生真正的随机数。一般而言, 硬件应该是随机数的最佳来源,早期生成的随机数, 都是来自于各种物理装置和设备。但是生成随机数 的硬件耗资不菲,并且存在生成速度慢、效率低、需 占用大量存储空间、不可重现等问题,因此其使用价 值很有限; ②用数学方法(算法)产生一组满足一定统计规 律的迭代随机序列,即伪随机数。由于它不可能是 真正的随机数,必须对其进行检验。 从实用的角度看,获取这种数的最简单和最自 然的方法是利用各种计算机语言的函数库提供的随 机数发生器。当然不同的开发环境提供的生成随机 数的函数和方法不一样。典型情况下,它会输出一 个均匀分布在[O,1]区间内的伪随机变量的值。 2伪随机数的生成机制 根据随机数的定义,凡是用算法生成的都不是 真正的随机数。因此使用算法只能生成伪随机数。 伪随机数并非假随机数,是指计算机产生的伪随机 数既是随机的又是有规律的,这为通过算法产生随 机数提供了基础。 2.1伪随机数(Psaudo Random Number)的生 成方法 产生伪随机数的方法很多,比如线性同余法、平 方取中法、取小数法、斐波那契(Fiboneed)法、非线 性同余法、乘同余法、移位寄存器序列、混合同余法 等,都能够在特定的情况下构造优良的伪随机数。 伪随机数可以使用递推公式产生,其通用公式 为: an+1一f(a ) n一1,2,…… (1) 显而易见,当计算方法(递推公式)及初值确定 后,整个随机数序列就唯一地确定了。但是这与随 机数的独立性要求相矛盾;同时,由于伪随机数总要 出现周期性循环,这也和真的随机数有区别。因此, 在计算机上生成的伪随机数必须满足下列要求: ①分布的均匀性:即同一范围内的任何一个随 机数的出现的概率是相同的,即必须尽可能地接近 U(O,1)分布。 ②统计,上的独立性:产生的随机数序列的相关 性越小越好。 ③足够长的周期:在其达到重复(循环)之前,能 生成足够多的、不重复的随机数。 ④占用的内存尽可能少,产生随机数的速度足 够快。 前两条要求,可以使用统计方法对随机数序列 进行检验。 2.2 线性同余法LCG(Linear Congruence Generator) 在各种程序设计语言中,最常用的还是线性同 余法。这种方法是Lehmer于1951年提出的:对于 一个正整数M和任意自然数no,a,b,由递推公式: nI+1一(af(ni)+b)mod m i一0,1,2,…,m一1 (2) 生成的数值序列称为是同余序列。当函数f (n)为线性函数时,即得到线性同余序列: nI+1一(a*ni+b)mod m i=O,1,2,…,m一1 (3) 其中a为乘子(常数),b为增量(常数),m为 模,no为该随机序列的种子。如何选取该方法中的 ・ 】99・
维普资讯
常数a、b和m直接关系到所产生的随机序列的随 机性能。 ②适当地选择m、a、b,可以保证ni在[O,m一 线性同余法的如下特点: ①O≤n。≤m一1,即ni只能从O~m一1这m个 整数中取值; a 7 5 1]区间上的均匀性。 线性同余法不仅与种子有关,而且与参数m、a、 c的选取有关,实例如表1所示: 表1种子与参数的关系 b 7 3 n“ 7 7 m 1O 16 随机序列 6,9,0,7,6,9,… 6,1,8,11,10,5,12,15,14,9,0,3,2,13,4, 7,6,… 周期 4 16 5 1 1 8 6,7,4,5,2,3,0,1,6,7… 8 为了保证其统计性质,提高ni的均匀性,要求 m足够大,例如可取m为机器大数,或者把它取为 2 ,w是计算机的字长。并且在计算过程中,为了 防止整数溢出,还需要进行一些算法处理。 如果伪随机数发生器具有满周期,可以预计所 得到的ni在[O,1]区间上是均匀分布的,且取值是 相当密集的,这样就足够近似于均匀分布U(O,1)。 2.3线性同余法生成伪随机数的算法 RandomNum(n,m,seed,a,b){ no seed for(i=1;i<一n;i++) Ili=(a*nl—l+b)mod m } 其中种子参数seed的初始值可以任意选择,人 们经常使用系统测定技术来计算随机“种子”,然后 将它放入伪随机数发生器,而种子的值用快速计数 寄存器或移位寄存器来生成。 为了尽量降低重复率,既可以使用主板序列号、 硬盘序列号、网卡序列号、当前时间等作种子数,也 可以采样用户的键盘或鼠标事件,并根据时间或位 置数据来派生出随机性。 3 Java程序实例 3.1 Java生成伪随机数的机制 在Java中有两种生成伪随机数的方式:Ran— dom类和Math.random()方法 Java实用工具类库中的类java.util.Random 提供了产生各种类型随机数的方法。当创建Ran— dom对象,就可以得到一系列的随机数,它可以产 生int、long、float、double以及Goussian等类型的 伪随机数。 而java.1ang.Math中Random()只能产生 double型的随机数。 事实上,Random类是一个伪随机数发生器,它 有两个构造方法和六个普通方法。 构造方法:public Random()、public Random (1ong seed) Java默认使用当前的系统时间为种子来初始 ・200・ 化Random对象。因为没有任何时刻的时间是相同 的,所以就可以减少随机数序列相同的可能性。 普通方法:public synonronized void setSeed (1ong seed)、public int nextInt()、public long nex- tLong()、public float nextFloat()、public double nextDouble()、public synchronized double next— Goussian() Java设计者在Random类的Ramdom()构造方 法中使用当前的系统时间来初始化Random对象。 因为没有任何时刻的时间是相同的,所以就可以减 少随机数序列相同的可能性。 3.2 Java Random类的实现 对于下面两条语句: Random randomGenerator=new Random(); int randomNumber—randomGenerator.nextlnt(n); 其中用到了Random类的nextlnt方法。以下是 nextInt方法实现的主要代码: public int nextIm(int n){ int bits,val, do{ bits=next(31); val=bits n; }while(bits--val+(n--1)<=o); return val, 、} 通过nextInt方法产生的随机数的范围应根据 特定应用程序需要的不同而不同。可按照下列形式 为nextInt方法传递一个参数:value一1+random— Generator.nextlnt(6); 该语句产生一个从1到6范围内的随机整数。 当给nextInt方法传递一个参数时,由nextInt方法 所返回的值的范围为0到参数值减1。 3.3应用实例 创建一个模拟掷骰子游戏的应用程序。每个骰 子有六个面,分别为1,2,3,4,5,6这六个点。当游 戏者掷出的两个骰子停止滚动,计算其面上的点数 和。如果投掷的点数之和为7或l1,游戏者获胜并 显示“Win”;如果投掷的点数之和为2,3或12,游戏 失败并显示“Lose”;如果点数之和为4,5,6,7,9或
维普资讯
1o,则将该值作为游戏者的“点数”。~ 表面点数为1的图片的位置。该程序的运行界面如 图1所示。 为了能在掷骰子游戏应用程序中使用随机数, 需要导人java.util包中的Random类。 该应用程序中有几个地方都需要滚动和显示两 个骰子。因此需要创建两个方法:rollDice方法用 于滚动骰子;displayDice用于显示骰子的图片。其 主要代码如下: private int rollDice(){ int dicel=1+randomObject.nextlnt(6); int dice2=1+randomObject.nextint(6); displayDice(dicelJLabel,diced; displayDice(dice2JLabel,dice2); retum dice1+dice2: }//end method rollDice 图1游戏程序运行界面 该段代码将变量dicel和dice2分别设置为l~6 (包括边界值)之间的一个int型随机数。之后对 displayDice方法进行了两次调用。displayDice方 法用于显示对应于1~6之间的骰子图片,其中第1 个参数代表所显示图片的JLabel,第2个参数代表 骰子的点数值。 private void displayDice(JLabel picDiceJLabel,int face){ imagelcon image=new Imagelcon(FILE-PREFIX+face +FILE-SUFFIX); picDiceJLabe1.setlcon(image); }//end method displayDice displayDice方法显示与用rollDice方法产生的 当单击Play按钮后,该应用程序将生成两个介 于1~6之间的随机数,并将相应的骰子图片显示在 指定位置,计算出两个骰子表面上的数值之和。 结束语伪随机数在软件开发和程序设计中应 用较为广泛,如何获得质量高、性能佳的随机数是软 件开发者追求的目标之一。JAVA作为一种主流的 面向对象程序设计语言,提供了多种生成伪随机数 的途径,以满足不同的设计要求。应当指出,不同算 法产生的伪随机数的随机性还是有差别的,应当根 据实际需要加以选择。 参考文献 1 盛骤,谢式千.概率论与数理统计[M].北京:高等教育出版社, 2000 随机骰子数相对应的图片。其中参数int用来取得 幅图片,JLablel用来显示该图片。FIL PRE— FIX和FILE—SUFFIX是两个已得到声明的常量, 一字符串FILE~PREFIX+face+FILE_SUFFIX 用来指明某个图片文件的位置(FIL PREFIX和 FILE—SUFFIX都定义为private final String型,其 值分别为“Images/dice”和“.png”)。如果face的值 为1,则该表达式将变为“Images/dice1.png”,表示 (上接第186页) 2 李芝兴,杨瑞龙.Java程序设计之网络缩程[M].北京:清华大学 出版社,2006 3 王晓东.算法设计与分析[M].北京:电子工业出版社(第2版), 2004 系统》很优雅地实现了。 参考文献 1 史济民,顾春华.软件工程原理、方法与应用.高等教育出版社, 2002 开发人员可以集中关注业务; (4)采用Hibernate的ORM映射机制,抽象了 数据库,使得程序与数据库的交互透明化。 总结 面对需求无法确定和不断变化的难题, 传统软件开发方法面临很大挑战,可复用快速原型 2 乔非,严隽薇,等.企业模型体系的建模与优化方法,2000 3孙卫琴编著.基于MVC的javaweb设计和开发[M].北京:电 子工业出版社,2004 4 Johnson R EXPERT ONE —ONE J2EE DEVEL0PMENT 法由于其快速开发、修改方便、快速相应需求和高可 扩展的特点迎合了这种需求。本文提出的基于 J2EE的Struts+Spring+Hibernate架构,利用 MVC,建立了一个结构清晰的系统框架,利用IOC, 使各个模块之间松散耦合,利用AOP,用简单的方 法完成了对系统横切点的考虑,利用ROM,高效地 实现了与数据库的交互。在可复用快速原型法的指 导下,《重庆铁路物流电子商务平台一一集装箱运营 WITHOUT EJ&北京:电子工业出版社,2005 5 Johnson R Spring Reference Documentation[EB/OL'].http:// VnⅣw.springframework.om/,2004 6 Hibernate.官方.Hibernate Reference Documentation[EB/ OL3.http://www.hibernate.org/hib does/v3/reference/ en/html single/.2005 ・ 2O1 ・
版权声明:本文标题:伪随机数及其在JAVA程序中的应用探讨 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1709795415a546558.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论