欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java随机数算法原理与实现方法实例详解

程序员文章站 2024-03-01 12:20:46
本文实例讲述了java随机数算法。分享给大家供大家参考,具体如下: 软件实现的算法都是伪随机算法,随机种子一般是系统时间 在数论中,线性同余方程是最基本的同余方程,“线...

本文实例讲述了java随机数算法。分享给大家供大家参考,具体如下:

软件实现的算法都是伪随机算法,随机种子一般是系统时间

在数论中,线性同余方程是最基本的同余方程,“线性”表示方程的未知数次数是一次,即形如:

ax≡b (mod n)的方程。此方程有解当且仅当 b 能够被 a 与 n 的最大公约数整除(记作 gcd(a,n) | b)。这时,如果 x0 是方程的一个解,那么所有的解可以表示为:

{x0+kn/d|(k∈z)}

其中 d 是a 与 n 的最大公约数。在模 n 的完全剩余系 {0,1,…,n-1} 中,恰有 d 个解。

例子编辑

* 在方程 3x ≡ 2 (mod 6) 中, d = gcd(3,6) = 3 ,3 不整除 2,因此方程无解。

* 在方程 5x ≡ 2 (mod 6) 中, d = gcd(5,6) = 1,1 整除 2,因此方程在{0,1,2,3,4,5} 中恰有一个解: x=4。

* 在方程 4x ≡ 2 (mod 6) 中, d = gcd(4,6) = 2,2 整除 2,因此方程在{0,1,2,3,4,5} 中恰有两个解: x=2 and x=5。

纯线性同余随机数生成器

线性同余随机数生成器介绍:

古老的lcg(linear congruential generator)代表了最好最朴素的伪随机数产生器算法。主要原因是容易理解,容易实现,而且速度快。

lcg 算法数学上基于公式:

x(0)=seed;
x(n+1) = (a * x(n) + c) % m;

其中,各系数为:

x(0)表示种子seed

模m, m > 0

系数a, 0 < a < m

增量c, 0 <= c < m

原始值(种子) 0 <= x(0) < m

其中参数c, m, a比较敏感,或者说直接影响了伪随机数产生的质量。

一般来说我们采用m=(2^31)-1 = 2147483647,这个是一个31位的质数,a=48271,这个a能使m得到一个完全周期,这里c为奇数,同时如果数据选择不好的话,很有可能得到周期很短的随机数,例如,如果我们去seed=179424105的话,那么随机数的周期为1,也就失去了随机的意义。

(48271*179424105+1)mod(2的31次方-1)=179424105

package test;
import java.util.hashmap;
import java.util.map;
import java.util.concurrent.atomic.atomiclong;
public class random {
 public final atomiclong seed=new atomiclong();
 public final static long c = 1;
 public final static long a = 48271;
 public final static long m = (1l << 31) - 1;
 public random(int seed){
  this.seed.set(seed);
 }
 public random(){
  this.seed.set(system.nanotime());
 }
 public long nextlong(){
  seed.set(system.nanotime());
  return (a *seed.longvalue() + c) % m;
 }
 public int nextint(int number){
  return new long( (a * system.nanotime() + c) % number).intvalue();
 }
 public static void main(string[] args) {
  system.out.println(new random().nextlong());
  map<integer,integer> map=new hashmap<integer,integer>();
  for(int i=0;i<100000;i++){
   int ran=new random().nextint(10);
   if(map.containskey(ran)){
    map.put(ran, map.get(ran)+1);
   }else{
    map.put(ran, 1);
   }
  }
  system.out.println(map);
 }
}

自己写个简单例子,随机10万次,随机范围0到9,看看是否均匀

Java随机数算法原理与实现方法实例详解

相对来说还是挺均匀的

ps:这里再为大家提供几款功能类似的在线工具供大家参考:

在线随机数字/字符串生成工具:

在线随机字符/随机密码生成工具:

高强度密码生成器:
http://tools.jb51.net/password/createstrongpassword

更多关于java算法相关内容感兴趣的读者可查看本站专题:《java数据结构与算法教程》、《java字符与字符串操作技巧总结》、《java操作dom节点技巧总结》、《java文件与目录操作技巧汇总》和《java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。