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

时间:2021-11-28 05:08:46 

由于一些不可控因素的影响,比如系统内存,计算机状态等,每一次在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);
 }
}

标签:随机数生成器,生成随机数,random方法
0
投稿

猜你喜欢

  • springboot自定义Starter过程解析

    2023-07-24 22:24:55
  • 深入理解C#之继承

    2022-02-25 07:25:44
  • Java 堆内存溢出原因分析

    2023-06-27 08:34:23
  • SpringMVC接收多个对象的4种方法

    2023-11-23 06:24:18
  • Spring超详细讲解创建BeanDefinition流程

    2023-11-25 08:37:55
  • C#线程同步的三类情景分析

    2023-01-07 22:38:04
  • 在Java的Hibernate框架中使用SQL语句的简单介绍

    2022-06-13 15:54:15
  • JAVA回顾:封装,继承,多态

    2021-09-26 20:17:59
  • Android 使用 SharedPreferences 保存少量数据的实现代码

    2023-07-03 01:00:11
  • java分页工具类的使用方法

    2023-08-17 02:00:14
  • flutter material widget组件之信息展示组件使用详解

    2023-06-22 08:45:35
  • Maven本地打包war包实现代码解析

    2021-09-06 12:51:14
  • 8种常见的Java不规范代码

    2023-05-24 10:59:53
  • 最小树形图模板朱刘算法分享

    2023-11-07 07:04:38
  • 详解SpringBoot多跨域请求的支持(JSONP)

    2023-09-21 04:12:54
  • 一文带你了解Java选择排序的原理与实现

    2022-05-13 21:01:31
  • maven将项目打包上传到nexus私服的详细教程

    2023-04-18 16:20:22
  • Spring Boot 配置和使用多线程池的实现

    2022-09-04 19:53:02
  • JAVA技术实现上传下载文件到FTP服务器(完整)

    2023-08-26 15:35:43
  • SpringBoot自动装配原理小结

    2023-11-18 16:54:06
  • asp之家 软件编程 m.aspxhome.com