2009-04-10 67 views
104

Sự khác nhau giữa Math.random() * nRandom.nextInt(n) nơi số n là số nguyên?Math.random() so với Random.nextInt (int)

+0

Tôi không biết toán học, nhưng tôi biết rằng FindBugs phàn nàn nếu bạn sử dụng 'Math.random()' – finnw

+3

Hãy nhớ rằng ngẫu nhiên không có phương pháp tĩnh, vì vậy sử dụng:. (New Random()) nextInt (n)). Đối với Toán học để tạo ra một số nguyên sử dụng tương tự: Math.floor ((Math.random() * n) +1); –

Trả lời

138

Đây là the detailed explanation lý do tại sao "Random.nextInt(n) vừa hiệu quả hơn và ít thiên vị hơn Math.random() * n" từ các diễn đàn Sun gửi mà Gili liên quan đến:

Math.random() sử dụng Random.nextDouble() trong nội bộ.

Random.nextDouble() sử dụng Random.next() hai lần để tạo ra gấp đôi có xấp xỉ các bit phân phối đồng nhất trong phần định trị của nó, vì vậy nó được phân bố đồng đều trong khoảng 0 đến 1- (2^-53).

Random.nextInt (n) sử dụng Random.next() ít hơn hai lần trên trung bình - nó sử dụng nó một lần và nếu giá trị thu được nằm trên bội số cao nhất n dưới MAX_INT thì thử lại, ngược lại trả về giá trị modulo n (điều này ngăn các giá trị trên bội số cao nhất của n dưới MAX_INT lệch phân phối), do đó trả về một giá trị được phân bố đồng đều trong khoảng 0 đến n-1.

Trước khi chia tỷ lệ bằng 6, đầu ra của Math.random() là một trong 2^53 giá trị có thể được lấy từ phân phối đồng đều.

Chia tỷ lệ bằng 6 không làm thay đổi số lượng giá trị có thể, và truyền tới int sau đó buộc các giá trị này thành một trong sáu 'nhóm' (0, 1, 2, 3, 4, 5), mỗi nhóm tương ứng phạm vi bao gồm 1501199875790165 hoặc 1501199875790166 của các giá trị có thể (vì 6 không phải là một cố vấn của 2^53). Điều này có nghĩa rằng đối với một số lượng đủ các cuộn xúc xắc (hoặc chết với một số lượng đủ lớn của các bên), chết sẽ hiển thị chính nó để được thiên vị đối với các thùng lớn hơn.

Bạn sẽ chờ đợi một thời gian dài lăn xúc xắc để hiệu ứng này hiển thị.

Math.random() cũng yêu cầu xử lý gấp đôi và phải được đồng bộ hóa.

+3

Random.nextInt và nextDouble cũng phải được đồng bộ hóa. – adrianos

+0

Trong ngữ cảnh này, "ít thiên vị" có ý nghĩa gì? –

+0

@ ΦXocę 웃 Пepeúpa ツ Điều này đơn giản có nghĩa là các con số nhất định có nhiều khả năng được vẽ hơn những con số khác. Như trong nó là thiên vị để chọn một số số hơn những người khác (do đó không hoàn toàn ngẫu nhiên hoặc cho đủ lớn kích thước mẫu thống nhất) –

26

một điểm quan trọng là Random.nextInt (n) là lặp lại vì bạn có thể tạo ra hai đối tượng ngẫu nhiên với cùng hạt giống . Điều này là không thể với Math.random().

0

Theo ví dụ này Random.nextInt(n) có đầu ra ít có thể dự đoán hơn thì Math.random() * n. Theo [sắp xếp mảng nhanh hơn mảng chưa phân loại] [1] Tôi nghĩ chúng ta có thể nói Random.nextInt (n) là khó dự đoán.

usingRandomClass: Thời gian: milesecond.

usingMathsRandom: Thời gian: milesecond.

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)); 

    } 

} 
+1

Trong vòng lặp thứ hai bạn kiểm tra> = 50, điều đó đúng trong hơn 50% các trường hợp. Điều đó sẽ gây ra điều này nếu tuyên bố là đúng sự thật hầu hết các lần, mà làm cho nó dễ dự đoán hơn. Kết quả của bạn do đó thiên vị ủng hộ câu trả lời của bạn –

+0

đó là lỗi chính tả ... tạo 128 trong ví dụ thứ hai, bạn sẽ nhận được kết quả tương tự. –

Các vấn đề liên quan