시스템 메모리, 컴퓨터 상태 등과 같은 제어할 수 없는 요인의 영향으로 인해 while 루프의 실행 횟수는 매번 달라집니다.
아마 수백 번은 됐을 거예요. 이로 인해 결과의 차이가 발생합니다.
이 프로그램은 많은 정적 변수를 사용합니다. 즉, 다음 스레드가 이전 스레드와 동일한 실행 메서드를 계속 실행할 때 초기 값은 이전 스레드 실행 후의 값이 됩니다. 이는 전형적인 나비 효과를 형성합니다. 이 차이가 증폭되어 최종 난수 생성이 이루어집니다.
이 프로그램에서는 총 13개의 스레드가 열리며, 그때마다 해당 정적 변수의 값이 혼란스러운 방향으로 밀려납니다.
따라서 최종 배열 double[] bb의 혼란 정도는 기하학적으로 증가합니다.
초기 bb[0]에는 약 수백 개의 가능한 값만 있고 bb[3]의 경우 65536개의 데이터 중 하나가 될 수 있습니다.
무작위성을 얻기 위해 13번 반복했는데 bb[12]는 거의 절대적으로 무작위라고 할 수 있습니다.
다음과 같이 코드 코드를 복사합니다.
/**
* 저자:위안훙롱
* 날짜:2014-1-9
*/
공개 클래스 MyRandom은 Runnable을 구현합니다.{
개인 정적 int 무작위;
개인 정적 int f=127;
개인 정적 int m=(int)Math.pow(2,16);
개인 정적 int[] r=getR();
개인 정적 int x=13;
@보수
공개 무효 실행(){
for(;!Thread.interrupted();){
f=((f/2)+r[f])%m;
무작위=r[f];
}
}
개인 정적 int[] getR(){
//65536개의 숫자(0-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;
r을 반환;
}
개인 정적 무효 변경R(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=new double[13];
for(int i=0;i<dd.length;i++){
실행 가능 runnable=new MyRandom();
스레드 스레드=새 스레드(실행 가능);
thread.start();
노력하다{
Thread.sleep(x+1);
}
catch(InterruptedException e){
e.getMessage();
}
스레드.인터럽트();
double rr=(더블)랜덤/(더블)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));
//고정점이 프로그램에 미치는 영향을 방지합니다. 두 값이 동일하면 프로그램이 막다른 골목, 즉 고정점에 진입했을 수 있음을 의미합니다. 고급 수학의 함수에 대한 지식을 의미할 수 있습니다.
}
}
더블 런=dd[12];
반환 실행;
}
공개 정적 무효 메인(문자열[] 인수){
더블 rs=getRandom_0_1();
System.out.println(rs);
}
}
내Random.java
다음과 같이 코드 코드를 복사합니다.
/**
* 저자:위안훙롱
* 날짜:2014-1-9
*/
패키지 광산.루프;
공개 클래스 MyRandom은 Runnable을 구현합니다.{
개인 정적 int 무작위;
개인 정적 int f=127;
개인 정적 int m=(int)Math.pow(2,16);
개인 정적 int[] r=getR();
개인 정적 int x=13;
@보수
공개 무효 실행(){
for(;!Thread.interrupted();){
f=((f/2)+r[f])%m;
무작위=r[f];
}
}
개인 정적 int[] getR(){
// r[]에 0부터 65536까지의 65536개의 숫자를 특정 순서로 저장합니다.
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;
r을 반환;
}
개인 정적 무효 변경R(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=new double[13];
for(int i=0;i<dd.length;i++){
실행 가능 runnable=new MyRandom();
스레드 스레드=새 스레드(실행 가능);
thread.start();
노력하다{
Thread.sleep(x+1);
}
catch(InterruptedException e){
e.getMessage();
}
스레드.인터럽트();
double rr=(더블)랜덤/(더블)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));
// 고정점이 프로그램에 미치는 영향을 방지합니다. 두 값이 동일할 경우 프로그램이 막다른 골목, 즉 고정점에 진입했을 수 있음을 의미합니다. 고급 수학의 함수에 대한 지식을 의미할 수 있습니다.
}
}
더블 런=dd[12];
반환 실행;
}
공개 정적 무효 메인(문자열[] 인수){
더블 rs=getRandom_0_1();
System.out.println(rs);
}
}