ความแตกต่างระหว่างสิ่งที่เป็นMath.random() * n
และRandom.nextInt(n)
ที่n
เป็นจำนวนเต็ม?
ความแตกต่างระหว่างสิ่งที่เป็นMath.random() * n
และRandom.nextInt(n)
ที่n
เป็นจำนวนเต็ม?
คำตอบ:
นี่คือคำอธิบายโดยละเอียดว่าเหตุใด " Random.nextInt(n)
ทั้งมีประสิทธิภาพมากกว่าและมีความเอนเอียงน้อยกว่าMath.random() * n
" จากโพสต์ฟอรัม Sun ที่ Gili เชื่อมโยงถึง:
Math.random () ใช้ Random.nextDouble () ภายใน
Random.nextDouble () ใช้ Random.next () สองครั้งเพื่อสร้างคู่ที่มีบิตกระจายสม่ำเสมอโดยประมาณในแมนทิสซาดังนั้นจึงมีการกระจายอย่างสม่ำเสมอในช่วง 0 ถึง 1- (2 ^ -53)
Random.nextInt (n) ใช้ Random.next () น้อยกว่าสองครั้งโดยเฉลี่ย - จะใช้ครั้งเดียวและหากค่าที่ได้รับสูงกว่าค่าผลคูณสูงสุดของ n ต่ำกว่า MAX_INT ก็จะลองอีกครั้งมิฉะนั้นจะส่งกลับค่าโมดูโล n ป้องกันไม่ให้ค่าที่สูงกว่าค่าพหุคูณสูงสุดของ n ต่ำกว่า MAX_INT บิดเบือนการแจกแจง) ดังนั้นจึงส่งคืนค่าที่กระจายอย่างสม่ำเสมอในช่วง 0 ถึง n-1
ก่อนที่จะปรับขนาดด้วย 6 ผลลัพธ์ของ Math.random () คือค่าหนึ่งใน 2 ^ 53 ที่เป็นไปได้ซึ่งดึงมาจากการแจกแจงแบบสม่ำเสมอ
การสเกลด้วย 6 ไม่ได้เปลี่ยนจำนวนค่าที่เป็นไปได้และการร่ายเป็น int จะบังคับให้ค่าเหล่านี้เป็นหนึ่งในหก 'ถัง' (0, 1, 2, 3, 4, 5) แต่ละที่เก็บข้อมูลจะสอดคล้องกับช่วงที่ครอบคลุมอย่างใดอย่างหนึ่ง 1501199875790165 หรือ 1501199875790166 ของค่าที่เป็นไปได้ (เนื่องจาก 6 ไม่ใช่ disvisor ของ 2 ^ 53) ซึ่งหมายความว่าสำหรับการทอยลูกเต๋าจำนวนเพียงพอ (หรือดายที่มีจำนวนด้านมากเพียงพอ) ดายจะแสดงว่าตัวเองเอนเอียงไปทางถังที่ใหญ่กว่า
คุณจะต้องรอเป็นเวลานานมากในการทอยลูกเต๋าเพื่อให้เอฟเฟกต์นี้ปรากฏขึ้น
Math.random () ยังต้องการการประมวลผลประมาณสองเท่าและอาจมีการซิงโครไนซ์
6
ด้วย5
ลูกบาศก์ลูกเต๋า: มันจะเป็น "5-biased" คุณสามารถทอยลูกเต๋าสองสามครั้งก่อนที่คุณจะสังเกตเห็นว่ามีบางอย่างผิดปกติกับลูกเต๋า คุณถูกบังคับให้ทำการตรวจสอบอย่างละเอียดถี่ถ้วนก่อนที่คุณจะสังเกตเห็นว่ามีบางอย่างผิดปกติกับเครื่องกำเนิดไฟฟ้าแบบสุ่ม
จุดสำคัญอีกประการหนึ่งคือ Random.nextInt (n) สามารถทำซ้ำได้เนื่องจากคุณสามารถสร้างวัตถุสุ่มสองชิ้นที่มีเมล็ดพันธุ์เดียวกันได้ สิ่งนี้ไม่สามารถทำได้ด้วย Math.random ()
อ้างอิงจากhttps://forums.oracle.com/forums/thread.jspa?messageID=6594485龵 Random.nextInt(n)
ทั้งมีประสิทธิภาพมากกว่าและมีความเอนเอียงน้อยกว่าMath.random() * n
ตามตัวอย่างนี้Random.nextInt(n)
มีผลลัพธ์ที่คาดเดาได้น้อยกว่าดังนั้น Math.random () * n ตาม [อาร์เรย์เรียงเร็วกว่าอาร์เรย์ไม่ได้เรียงลำดับ] [1] ผมคิดว่าเราสามารถพูดได้ Random.nextInt (n) เป็นเรื่องยากที่จะคาดการณ์
usingRandomClass: เวลา: 328ไมล์วินาที
usingMathsRandom: เวลา: 187ไมล์วินาที
package javaFuction;
import java.util.Random;
public class RandomFuction
{
static int array[] = new int[9999];
static long sum = 0;
public static void usingMathsRandom() {
for (int i = 0; i < 9999; i++) {
array[i] = (int) (Math.random() * 256);
}
for (int i = 0; i < 9999; i++) {
for (int j = 0; j < 9999; j++) {
if (array[j] >= 128) {
sum += array[j];
}
}
}
}
public static void usingRandomClass() {
Random random = new Random();
for (int i = 0; i < 9999; i++) {
array[i] = random.nextInt(256);
}
for (int i = 0; i < 9999; i++) {
for (int j = 0; j < 9999; j++) {
if (array[j] >= 128) {
sum += array[j];
}
}
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
usingRandomClass();
long end = System.currentTimeMillis();
System.out.println("usingRandomClass " + (end - start));
start = System.currentTimeMillis();
usingMathsRandom();
end = System.currentTimeMillis();
System.out.println("usingMathsRandom " + (end - start));
}
}
Math.random()