专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
Java编程精选  ·  Map 只会 ... ·  2 天前  
Java知音  ·  Java面试八股文背到崩溃?Deepseek ... ·  昨天  
Java知音  ·  Java面试八股文背到崩溃?Deepseek ... ·  昨天  
芋道源码  ·  微服务架构中10个常用的设计模式 ·  2 天前  
芋道源码  ·  为什么 MyBatis 源码中,没有我那种 ... ·  3 天前  
51好读  ›  专栏  ›  ImportNew

探索 Java 各种随机函数

ImportNew  · 公众号  · Java  · 2017-10-03 12:00

正文

(点击 上方公众号 ,可快速关注)


来源:KAAAsS,

blog.kaaass.net/archives/42

如有好文章投稿,请点击 → 这里了解详情


其实写这篇文章的原由是最近准备在Java上写一个Perlin噪声的插件,所以对各种噪声函数有了一丢丢的了解,若有问题还请大家指正。转载的话希望能注明出处。


注意,本教程中的随机函数均是形参为整形,返回值为区间[0,1)内的单精浮点数的函数。测试均为1~10000的随机数生成速度测试(1D – 输入x、2D – 输入x, y)。


更新记录


2016.1.22 – 初稿。


2016.1.28


(1) – 更新了Wichman-Hill随机数的算法,修改内容。增加了几个随机算法。


(2) – 统计出了各个方法比较后的分数。


随机方法


1.Wichman-Hill 随机数产生器


Excel的随机函数曾用的方法,参考文献:


  • Wichman, B.A. 和 I.D. Hill,Algorithm AS 183:An Efficient and Portable Pseudo-Random Number Generator,《Applied Statistics》,31,188-190,1982。

  • Wichman, B.A. 和 I.D. Hill,Building a Random-Number Generator,BYTE,第127-128 页,1987 年 3 月。

  • Rotz, W. 和 E. Falk,D. Wood 和 J. Mulrow,A Comparison of Random Number Generators Used in Business,发表于 2001 年在佐治亚州亚特兰大市举行的“统计学联合会议”上。


直接上源码(2D请前去Github上查看):


/**

* This is a method of Wichman-Hill random number generator.

*

* @param x

* A seed for generator.

* @return A float random value between [0.0,1.0)

*/

public static float randomWH(java.lang.Integer x) {

int[] seed = new int[3];

seed[0] = (171 * x) % 30269;

seed[1] = (172 * (30000 – x)) % 30307;

seed[2] = (170 * x) % 30323;

return (x / Math.abs(x))

* (seed[0] / 30269.0F + seed[1] / 30307.0F + seed[2] / 30323.0F) % 1.0F;

}


以下是测试结果:


Start testing randomWH(), test: Generate 10000 numbers(1D).

Testing randomWH() completed, using time: 10 ms.


Start testing randomWH(), test: Generate 10000 numbers(2D).

Testing randomWH() completed, using time: 7 ms.


还蛮乐观,但是图像就…



无论怎么改,还是呈现了线性的趋势,波动很小……Orz


2.RSA 随机数产生器


RSA公钥算法大家都不会不熟悉吧,公认很靠谱的密钥算法。这里就是用了RSA的随机算法。参考:


  • Wikipedia – RSA problem


其公式:C = (x * exp P) mod N(P是质数,N是两个质数之积)


这是Java代码:


/**

* This is a method of RSA.

*

* @param x

*            A seed for generator.

* @return A float random value between [0.0,1.0)

*/

public static float randomRSA(java.lang.Integer x) {

return (float) (x * Math.exp(seedRSA[0]) % seedRSA[1] / seedRSA[1]);

}


测试结果:


Start testing randomRSA(), test: Generate 10000 numbers(1D).

Testing randomRSA() completed, using time: 10 ms.


Start testing randomRSA(), test: Generate 10000 numbers(2D).

Testing randomRSA() completed, using time: 9 ms.



从图像看出,这个算法的随机性很赞。况且运算速度也不赖,适合使用。


3.Java 随机数产生器


Java自带的随机数(就是java.util.Random类),用过的都知道吧。那就直接上代码:


/**

* This is a method of Java random number generator.

*

* @param x

*            A seed for generator.

* @return A float random value between [0.0,1.0)

*/

public static float randomJava(java.lang.Integer x) {

return (float) (new java.util.Random(1000 * x).nextDouble()); //乘1000来让种子间差距增大

}


这是测试数据:


Start testing randomJava(), test: Generate 10000 numbers(1D).

Testing randomJava() completed, using time: 11 ms.


Start testing randomJava(), test: Generate 10000 numbers(2D).

Testing randomJava() completed, using time: 8 ms.



非常优秀的随机数算法,速度快而且基本看不出规律。


4.简单的随机数产生器


又是扫荡Google的战利品,很抱歉忘记出处惹……代码:


/**

* This is a method of basic random generator.

*

* @param x

*            A seed for generator.

* @return A float random value between [0.0,1.0)

*/

public static float randomBasic(java.lang.Integer x) {

x = (x << 13) ^ x;

return (float) Math

.abs((1.0 - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0));

}


测试结果:


Start testing randomBasic(), test: Generate 10000 numbers(1D).

Testing randomBasic() completed, using time: 9 ms.


Start testing randomBasic(), test: Generate 10000 numbers(2D).

Testing randomBasic() completed, using time: 8 ms.



也是非常优秀的算法,随机的效果很棒,且用时也不长。


5.dotNet 随机数产生器


写了尼玛整整一个类啊我擦,不过是源码转写进来的,也没费什么力气。代码:


(DotNetRandom 类)


package kaaass.perlin2d.random;

/**

* This is a random generator which translated from dotNet.

*

* @author dotNet, KAAAsS(Translate)

*

*/

class DotNetRandom {

private final static int MBIG = Integer.MAX_VALUE;

private final static int MSEED = 161803398;

private int inext, inextp;

private int[] SeedArray = new int[56];

public DotNetRandom() {

this((int) System.currentTimeMillis());

}

public DotNetRandom(int Seed) {

int ii;

int mj, mk;

mj = MSEED - Math.abs(Seed);

SeedArray[55] = mj;







请到「今天看啥」查看全文