疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

java产生随机数


 

   

  产生自己的随机数,注意我们不要调用Math.random方法,因为那样太没有意思了

  原理:现代计算机运行速度很快,在主线程等待一定毫秒数时,其他线程就会执行run方法中的while循环,

  一般会执行数十万次。

  由于一些不可控因素的影响,比如系统内存,计算机状态等,每一次在while循环中执行的次数会有一定差异

  大概几百次。这就导致了结果的差异。

  注意这个程序使用了许多静态变量,也就是说,在下一个线程继续执行与上一个线程相同的run方法时,其初始值是上一个线程执行后的值,这形成了经典的蝴蝶效应,通过将这个差异放大,导致最终随机数的产生。

  在这个程序中,一共开启了13个thread线程,每一次都会将那几个静态变量的值向混乱的方向推动,

  于是最后得到的数组double[] bb的混乱程度几何上升,

  最开始的bb[0]只有约几百个可能的值,而到了bb[3]就可以是65536个数据中的任何一个。

  为了做到随机,我循环了13次,bb[12]几乎可以说是绝对的随机了。

  代码片段(2) [全屏查看所有代码]

  1. [代码][Java]代码

  /**

  * 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

  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[i]=r1[(i+f)%m];

  }

  }

  public static double getRandom_0_1(){

  double[] dd=new double[13];

  for(int i=0;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);

  }

  }

  2. [文件] 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

  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[i]=r1[(i+f)%m];

  }

  }

  public static double getRandom_0_1(){

  double[] dd=new double[13];

  for(int i=0;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);

  }

  }