システムメモリ、コンピュータのステータスなどの制御不能な要因の影響により、while ループの実行数は毎回異なります。
おそらく何百回も。これが結果の違いにつながります。
このプログラムは多くの静的変数を使用することに注意してください。つまり、次のスレッドが前のスレッドと同じ run メソッドを実行し続ける場合、その初期値は前のスレッドの実行後の値になります。これは古典的なバタフライ効果を形成します。この差は増幅され、最終的な乱数の生成につながります。
このプログラムでは、合計 13 個のスレッドが開かれ、そのたびにそれらの静的変数の値がカオスな方向にプッシュされます。
したがって、最終的な配列 double[] bb の混乱の度合いは幾何級数的に増加します。
最初の bb[0] には約数百の値しかなく、bb[3] になると 65536 個のデータのいずれかになります。
ランダム性を実現するために 13 回ループしましたが、bb[12] はほぼ完全にランダムであると言えます。
次のようにコードをコピーします。
/**
* 著者:袁紅龍
* 日付:2014-1-9
*/
public class MyRandom は Runnable{ を実装します
プライベート静的整数ランダム;
プライベート静的 int f=127;
private static int m=(int)Math.pow(2,16);
プライベート静的 int[] r=getR();
プライベート静的 int x=13;
@オーバーライド
public void run(){
for(;!Thread.interrupted();){
f=((f/2)+r[f])%m;
ランダム=r[f];
}
}
プライベート静的 int[] getR(){
// 0 ~ 65536 の 65536 個の数値を特定の順序で r[] に保存します
int[] r=新しい 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;
rを返します。
}
private static void changeR(int[] r,int f){
//r[]を移動
int[] r1=新しい 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];
}
}
パブリック静的ダブルgetRandom_0_1(){
double[] dd=新しい double[13];
for(int i=0;i<dd.length;i++){
実行可能 runnable=new MyRandom();
スレッド thread=新しいスレッド(実行可能);
thread.start();
試す{
スレッド.スリープ(x+1);
}
catch(InterruptedException e){
e.getMessage();
}
thread.interrupt();
ダブル rr=(ダブル)ランダム/(ダブル)m;
x=f%13;
変更R(r,11+(f/7));
dd[i]=rr;
if((i>0)&&(dd[i]==dd[i-1])){
変更R(r,13+(f/11));
//プログラムへの固定点の影響を防止します。 2 つの値が同じ場合、プログラムが行き止まり、つまり固定点に入った可能性があることを意味します。高度な数学における関数の知識を参照できます。
}
}
ダブルラン=dd[12];
戻って走った。
}
public static void main(String[] args){
ダブル rs=getRandom_0_1();
System.out.println(rs);
}
}
MyRandom.java
次のようにコードをコピーします。
/**
* 著者:袁紅龍
* 日付:2014-1-9
*/
パッケージmine.loop;
public class MyRandom は Runnable{ を実装します
プライベート静的整数ランダム;
プライベート静的 int f=127;
private static int m=(int)Math.pow(2,16);
プライベート静的 int[] r=getR();
プライベート静的 int x=13;
@オーバーライド
public void run(){
for(;!Thread.interrupted();){
f=((f/2)+r[f])%m;
ランダム=r[f];
}
}
プライベート静的 int[] getR(){
// 0 ~ 65536 の 65536 個の数値を特定の順序で r[] に格納します
int[] r=新しい 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;
rを返します。
}
private static void changeR(int[] r,int f){
int[] r1=新しい 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];
}
}
パブリック静的ダブルgetRandom_0_1(){
double[] dd=新しい double[13];
for(int i=0;i<dd.length;i++){
実行可能 runnable=new MyRandom();
スレッド thread=新しいスレッド(実行可能);
thread.start();
試す{
スレッド.スリープ(x+1);
}
catch(InterruptedException e){
e.getMessage();
}
thread.interrupt();
ダブル rr=(ダブル)ランダム/(ダブル)m;
x=f%13;
変更R(r,11+(f/7));
dd[i]=rr;
if((i>0)&&(dd[i]==dd[i-1])){
変更R(r,13+(f/11));
// プログラムに対する固定点の影響を防ぎます。 2 つの値が同じ場合、プログラムが行き止まり、つまり固定点に入った可能性があることを意味します。高度な数学における関数の知識を参照できます。
}
}
ダブルラン=dd[12];
戻って走った。
}
public static void main(String[] args){
ダブル rs=getRandom_0_1();
System.out.println(rs);
}
}