不使用Math.random方法生成隨機(jī)數(shù)(隨機(jī)數(shù)生成器)
由于一些不可控因素的影響,比如系統(tǒng)內(nèi)存,計(jì)算機(jī)狀態(tài)等,每一次在while循環(huán)中執(zhí)行的次數(shù)會(huì)有一定差異
大概幾百次。這就導(dǎo)致了結(jié)果的差異。
注意這個(gè)程序使用了許多靜態(tài)變量,也就是說,在下一個(gè)線程繼續(xù)執(zhí)行與上一個(gè)線程相同的run方法時(shí),其初始值是上一個(gè)線程執(zhí)行后的值,這形成了經(jīng)典的蝴蝶效應(yīng),通過將這個(gè)差異放大,導(dǎo)致最終隨機(jī)數(shù)的產(chǎn)生。
在這個(gè)程序中,一共開啟了13個(gè)thread線程,每一次都會(huì)將那幾個(gè)靜態(tài)變量的值向混亂的方向推動(dòng),
于是最后得到的數(shù)組double[] bb的混亂程度幾何上升,
最開始的bb[0]只有約幾百個(gè)可能的值,而到了bb[3]就可以是65536個(gè)數(shù)據(jù)中的任何一個(gè)。
為了做到隨機(jī),我循環(huán)了13次,bb[12]幾乎可以說是絕對(duì)的隨機(jī)了。
/**
* 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個(gè)數(shù)按照一定順序存入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){
//對(duì)r[]進(jìn)行移動(dòng)
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));
//防止不動(dòng)點(diǎn)對(duì)程序的影響,當(dāng)兩個(gè)值相同說明程序有可能進(jìn)入了死胡同,也就是不動(dòng)點(diǎn),關(guān)于不動(dòng)點(diǎn)的問題可以參考高等數(shù)學(xué)關(guān)于函數(shù)的知識(shí)
}
}
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個(gè)數(shù)按照一定順序存入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));
// 防止不動(dòng)點(diǎn)對(duì)程序的影響,當(dāng)兩個(gè)值相同說明程序有可能進(jìn)入了死胡同,也就是不動(dòng)點(diǎn),關(guān)于不動(dòng)點(diǎn)的問題可以參考高等數(shù)學(xué)關(guān)于函數(shù)的知識(shí)
}
}
double ran=dd[12];
return ran;
}
public static void main(String[] args){
double rs=getRandom_0_1();
System.out.println(rs);
}
}
相關(guān)文章
Eclipse Web項(xiàng)目打成war包的方法圖解
當(dāng)Tomcat啟動(dòng)后該壓縮文件自動(dòng)解壓縮,war包方便了web工程的發(fā)布,那么Eclipse中如何將Web項(xiàng)目打成war包呢?下面小編通過圖文并茂的方式給大家講解下Eclipse Web項(xiàng)目打成war包的方法,一起看看吧2016-08-08Spring中@ConditionalOnProperty注解的作用詳解
這篇文章主要介紹了Spring中@ConditionalOnProperty注解的作用詳解,@ConditionalOnProperty注解主要是用來判斷配置文件中的內(nèi)容來決定配置類是否生效用的,如果條件不匹配,則配置類不生效,需要的朋友可以參考下2024-01-01SpringBoot Maven打包插件spring-boot-maven-plugin無法解析原因
spring-boot-maven-plugin是spring boot提供的maven打包插件,本文主要介紹了SpringBoot Maven打包插件spring-boot-maven-plugin無法解析原因,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03C語言中下標(biāo)與指針的轉(zhuǎn)換以及指向指針的指針的例子
這篇文章主要介紹了C語言中下標(biāo)與指針的轉(zhuǎn)換以及指向指針的指針的示例,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11springboot集成mybatisplus實(shí)例詳解
這篇文章主要介紹了springboot集成mybatisplus實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09SpringSecurity構(gòu)建基于JWT的登錄認(rèn)證實(shí)現(xiàn)
這篇文章主要介紹了SpringSecurity構(gòu)建基于JWT的登錄認(rèn)證實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02