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

不使用Math.random方法生成随机数(随机数生成器)

程序员文章站 2024-02-14 17:36:40
由于一些不可控因素的影响,比如系统内存,计算机状态等,每一次在while循环中执行的次数会有一定差异大概几百次。这就导致了结果的差异。注意这个程序使用了许多静态变量,也就是...

由于一些不可控因素的影响,比如系统内存,计算机状态等,每一次在while循环中执行的次数会有一定差异
大概几百次。这就导致了结果的差异。
注意这个程序使用了许多静态变量,也就是说,在下一个线程继续执行与上一个线程相同的run方法时,其初始值是上一个线程执行后的值,这形成了经典的蝴蝶效应,通过将这个差异放大,导致最终随机数的产生。
在这个程序中,一共开启了13个thread线程,每一次都会将那几个静态变量的值向混乱的方向推动,
于是最后得到的数组double[] bb的混乱程度几何上升,
最开始的bb[0]只有约几百个可能的值,而到了bb[3]就可以是65536个数据中的任何一个。
为了做到随机,我循环了13次,bb[12]几乎可以说是绝对的随机了。

复制代码 代码如下:

/**
 * author:yuanhonglong
 * date:2014-1-9
 */

public class myrandom implements runnable{

 private static int random;
 private static int f=127;
 private static int m=(int)math.pow(2,16);
 private static int[] r=getr();
 private static int x=13;

 @override
 public void run(){
  for(;!thread.interrupted();){
   f=((f/2)+r[f])%m;
   random=r[f];
  }
 }

 private static int[] getr(){
                //将0-65536这65536个数按照一定顺序存入r[]中
  int[] r=new int[m];
  r[0]=13849;
  for(int i=1;i<m;i++){
   r[i]=((2053*r[i-1])+13849)%m;
  }
  int k=r[65535];
  r[65535]=r[(f+1)%m];
  r[(f+1)%m]=k;
  return r;
 }

 private static void changer(int[] r,int f){
                //对r[]进行移动
  int[] r1=new int[r.length];
  system.arraycopy(r,0,r1,0,r.length);
  for(int i=0;i<r.length;i++){
   r[i]=r1[(i+f)%m];
  }
 }

 public static double getrandom_0_1(){
  double[] dd=new double[13];
  for(int i=0;i<dd.length;i++){
   runnable runnable=new myrandom();
   thread thread=new thread(runnable);
   thread.start();
   try{
    thread.sleep(x+1);
   }
   catch(interruptedexception e){
    e.getmessage();
   }
   thread.interrupt();
   double rr=(double)random/(double)m;
   x=f%13;
   changer(r,11+(f/7));
   dd[i]=rr;
   if((i>0)&&(dd[i]==dd[i-1])){
    changer(r,13+(f/11));
                                //防止不动点对程序的影响,当两个值相同说明程序有可能进入了死胡同,也就是不动点,关于不动点的问题可以参考高等数学关于函数的知识
   }
  }
  double ran=dd[12];
  return ran;
 }

 public static void main(string[] args){
  double rs=getrandom_0_1();
  system.out.println(rs);
 }
}

myrandom.java

复制代码 代码如下:

/**
 * author:yuanhonglong
 * date:2014-1-9
 */
package mine.loop;

public class myrandom implements runnable{

 private static int random;
 private static int f=127;
 private static int m=(int)math.pow(2,16);
 private static int[] r=getr();
 private static int x=13;

 @override
 public void run(){
  for(;!thread.interrupted();){
   f=((f/2)+r[f])%m;
   random=r[f];
  }
 }

 private static int[] getr(){
  // 将0-65536这65536个数按照一定顺序存入r[]中
  int[] r=new int[m];
  r[0]=13849;
  for(int i=1;i<m;i++){
   r[i]=((2053*r[i-1])+13849)%m;
  }
  int k=r[65535];
  r[65535]=r[(f+1)%m];
  r[(f+1)%m]=k;
  return r;
 }

 private static void changer(int[] r,int f){
  int[] r1=new int[r.length];
  system.arraycopy(r,0,r1,0,r.length);
  for(int i=0;i<r.length;i++){
   r[i]=r1[(i+f)%m];
  }
 }

 public static double getrandom_0_1(){
  double[] dd=new double[13];
  for(int i=0;i<dd.length;i++){
   runnable runnable=new myrandom();
   thread thread=new thread(runnable);
   thread.start();
   try{
    thread.sleep(x+1);
   }
   catch(interruptedexception e){
    e.getmessage();
   }
   thread.interrupt();
   double rr=(double)random/(double)m;
   x=f%13;
   changer(r,11+(f/7));
   dd[i]=rr;
   if((i>0)&&(dd[i]==dd[i-1])){
    changer(r,13+(f/11));
    // 防止不动点对程序的影响,当两个值相同说明程序有可能进入了死胡同,也就是不动点,关于不动点的问题可以参考高等数学关于函数的知识
   }
  }
  double ran=dd[12];
  return ran;
 }

 public static void main(string[] args){
  double rs=getrandom_0_1();
  system.out.println(rs);
 }
}