เนื่องจากอิทธิพลของปัจจัยที่ไม่สามารถควบคุมได้ เช่น หน่วยความจำระบบ สถานะของคอมพิวเตอร์ ฯลฯ จำนวนการดำเนินการในลูป 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;
@แทนที่
โมฆะสาธารณะวิ่ง () {
สำหรับ(;!Thread.ขัดจังหวะ();){
f=((f/2)+r[f])%m;
สุ่ม=r[f];
-
-
int คงที่ส่วนตัว [] getR () {
//บันทึกตัวเลข 65536 0-65536 ลงใน r[] ตามลำดับที่แน่นอน
int[] r=ใหม่ int[m];
ร[0]=13849;
สำหรับ(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;
-
โมฆะคงที่ส่วนตัว changeR (int [] r, int f) {
// ย้าย r[]
int[] r1=ใหม่ int[r.length];
System.arraycopy(r,0,r1,0,r.ความยาว);
สำหรับ(int i=0;i<r.length;i++){
r[i]=r1[(i+f)%m];
-
-
getRandom_0_1(){ สาธารณะคงที่สองเท่า
สองเท่า[] dd=คู่ใหม่[13];
สำหรับ(int i=0;i<dd.length;i++){
รันได้ runnable=ใหม่ MyRandom();
เธรดเธรด = เธรดใหม่ (รันได้);
เธรด.เริ่มต้น();
พยายาม{
Thread.sleep(x+1);
-
จับ (InterruptedException e) {
e.getMessage();
-
เธรด.ขัดจังหวะ();
rr คู่ = (คู่) สุ่ม / (คู่) m;
x=ฉ%13;
เปลี่ยนR(r,11+(f/7));
วว[i]=rr;
ถ้า((i>0)&&(dd[i]==dd[i-1])){
changeR(r,13+(f/11));
//ป้องกันผลกระทบของจุดคงที่บนโปรแกรม เมื่อค่าทั้งสองค่าเท่ากัน แสดงว่าโปรแกรมอาจเข้าสู่ทางตัน นั่นคือจุดคงที่ สามารถอ้างอิงถึงความรู้เกี่ยวกับฟังก์ชันทางคณิตศาสตร์ขั้นสูงได้
-
-
วิ่งสองครั้ง = dd [12];
วิ่งกลับ;
-
โมฆะคงที่สาธารณะ main (String [] args) {
สองเท่า rs=getRandom_0_1();
System.out.println(อาร์เอส);
-
-
MyRandom.java
คัดลอกรหัสรหัสดังต่อไปนี้:
/**
* ผู้แต่ง: หยวนหงหลง
* วันที่:2014-1-9
-
แพ็คเกจ mine.loop;
MyRandom คลาสสาธารณะใช้งาน Runnable{
int คงที่ส่วนตัวสุ่ม;
int คงที่ส่วนตัว f = 127;
int คงที่ส่วนตัว m=(int)Math.pow(2,16);
int คงที่ส่วนตัว [] r = getR ();
int คงที่ส่วนตัว x=13;
@แทนที่
โมฆะสาธารณะวิ่ง () {
สำหรับ(;!Thread.ขัดจังหวะ();){
f=((f/2)+r[f])%m;
สุ่ม=r[f];
-
-
int คงที่ส่วนตัว [] getR () {
// เก็บตัวเลข 65536 0-65536 ใน r[] ตามลำดับที่กำหนด
int[] r=ใหม่ int[m];
ร[0]=13849;
สำหรับ(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;
-
โมฆะคงที่ส่วนตัว changeR (int [] r, int f) {
int[] r1=ใหม่ int[r.length];
System.arraycopy(r,0,r1,0,r.ความยาว);
สำหรับ(int i=0;i<r.length;i++){
r[i]=r1[(i+f)%m];
-
-
getRandom_0_1(){ สาธารณะคงที่สองเท่า
สองเท่า[] dd=คู่ใหม่[13];
สำหรับ(int i=0;i<dd.length;i++){
รันได้ runnable=ใหม่ MyRandom();
เธรดเธรด = เธรดใหม่ (รันได้);
เธรด.เริ่มต้น();
พยายาม{
Thread.sleep(x+1);
-
จับ (InterruptedException e) {
e.getMessage();
-
เธรด.ขัดจังหวะ();
rr คู่ = (คู่) สุ่ม / (คู่) m;
x=ฉ%13;
เปลี่ยนR(r,11+(f/7));
วว[i]=rr;
ถ้า((i>0)&&(dd[i]==dd[i-1])){
changeR(r,13+(f/11));
// ป้องกันผลกระทบของจุดคงที่บนโปรแกรม เมื่อค่าทั้งสองค่าเท่ากัน แสดงว่าโปรแกรมอาจเข้าสู่ทางตัน นั่นคือจุดคงที่ สามารถอ้างอิงถึงความรู้เกี่ยวกับฟังก์ชันทางคณิตศาสตร์ขั้นสูงได้
-
-
วิ่งสองครั้ง = dd [12];
วิ่งกลับ;
-
โมฆะคงที่สาธารณะ main (String [] args) {
สองเท่า rs=getRandom_0_1();
System.out.println(อาร์เอส);
-
-