2009-03-10 45 views
6

Random.nextGaussian() là nghĩa vụ phải cung cấp ngẫu nhiên no.s với độ lệch trung bình 0 và std 1. Nhiều số không được tạo ra nằm ngoài phạm vi [-1, + 1]. làm thế nào tôi có thể thiết lập để nó cung cấp cho ngẫu nhiên phân phối ngẫu nhiên no.s chỉ trong phạm vi -1 đến 1.vấn đề với Random.nextGaussian()

Trả lời

17

Phân phối Gaussian có giá trị trung bình 0 và độ lệch chuẩn có nghĩa là mức trung bình của phân phối là 0 và khoảng 70% dân số nằm trong khoảng [-1, 1]. Bỏ qua các số nằm ngoài phạm vi của bạn - chúng tạo thành khoảng xấp xỉ 16% ở hai bên.

Có thể giải pháp tốt hơn là tạo phân phối với mean=0std.dev=0.5. Điều này sẽ cung cấp cho bạn phân phối với khoảng 96% giá trị trong phạm vi [-1, 1].

Một giải pháp tốt hơn nữa là làm việc ngược như trên và sử dụng ý tưởng gần đúng. 99,7% giá trị nằm trong phạm vi 3-sigma: sử dụng std.dev = 1/3. Điều đó sẽ gần như vô hiệu hóa số lượng các giá trị không hữu ích mà bạn đang nhận được. Khi bạn nhận được một, bỏ qua nó.

Tất nhiên, nếu bạn đang làm việc trên một sản phẩm chuyên sâu về toán học, tất cả điều này không có giá trị.

+3

Ngoại trừ, tất nhiên, bỏ qua những con số đó có nghĩa là các giá trị ngẫu nhiên của bạn không thực sự bình thường nữa, đúng không? –

+1

Theo định nghĩa đó, bất kỳ kẹp nào bạn thực hiện trên bất kỳ trình tạo số ngẫu nhiên nào đều đưa ra một sai lệch. – dirkgently

+0

@dirkgently: Tuyệt đối. Nó không phải là một phân phối bình thường nữa, chỉ là một bản phân phối bình thường. –

6

Phân bố bình thường mang lại xác suất không khác (nhưng "cực nhỏ") khi thấy các giá trị bên ngoài [ -1, +1] bất kỳ phương sai nào bạn đưa ra - bạn chỉ đang vẽ đường cong một cách hiệu quả.

Bạn có thể sử dụng phương sai nhỏ và sau đó chỉ chạy kết quả thông qua bản đồ cắt bất kỳ thứ gì nhỏ hơn -1 đến -1 và bất kỳ thứ gì lớn hơn 1 đến 1, nhưng sẽ không (nói đúng) là bình thường phân phối nữa.

Bạn cần phân phối này cho mục đích gì?

+1

Nó không nhỏ.Gần 30% giá trị phải nằm ngoài 1 độ lệch chuẩn. Một cái gì đó như 5% sẽ nằm ngoài 2 độ lệch chuẩn. –

+0

Các "trở nên cực kỳ nhỏ" được thiết kế để ngụ ý rằng khi bạn nhận được xa hơn từ trung bình, xác suất tạo ra các giá trị được nhỏ hơn, nhưng vẫn không khác. –

+0

tôi đang triển khai chương trình phân tích thống kê. Nó sử dụng phân phối bình thường. – BHS

10

Phân phối bình thường có bao gồm các con số tùy tiện xa mức trung bình, nhưng với xác suất ngày càng nhỏ? Nó có thể là mong muốn của bạn (bình thường và giới hạn trong một phạm vi cụ thể) không tương thích.

1

Độ lệch chuẩn 1.0 yêu cầu nhiều giá trị nằm ngoài phạm vi [-1,1].

Nếu bạn cần giữ trong phạm vi này, bạn nên sử dụng phương pháp khác, có lẽ nextDouble().

2

Phân phối Gaussian với thông số của bạn. có mật độ e^(- x^2/2). Nói chung nó có dạng e^(tuyến tính (x) + tuyến tính (x^2)) có nghĩa là bất kỳ cài đặt nào bạn cung cấp cho nó, bạn có khả năng nhận được số lượng rất lớn và rất nhỏ.
Có thể bạn đang tìm kiếm một số bản phân phối khác.

0

Mã này sẽ hiển thị đếm số ngẫu nhiên Gaussian số để điều khiển (10 trong một dòng) và hiển thị cho bạn một số thống kê (thấp nhất, cao nhất và trung bình) sau đó.

Nếu bạn thử với số nhỏ đếm, các số ngẫu nhiên có thể nằm trong phạm vi [-1,0 ... +1.0] và trung bình có thể nằm trong phạm vi [-0.1 ... +0.1]. Tuy nhiên, nếu số số vượt quá 10.000, số ngẫu nhiên sẽ giảm trong phạm vi [-4.0 ... +4.0] (số không thể đoán trước có thể xuất hiện ở cả hai đầu), mặc dù mức trung bình có thể nằm trong phạm vi [-0.001 ... + 0,001] (cách gần hơn tới 0).

public static void main(String[] args) { 
    int count = 20_000; // Generated random numbers 
    double lowest = 0; // For statistics 
    double highest = 0; 
    double average = 0; 
    Random random = new Random(); 

    for (int i = 0; i < count; ++i) { 
     double gaussian = random.nextGaussian(); 
     average += gaussian; 
     lowest = Math.min(gaussian, lowest); 
     highest = Math.max(gaussian, highest); 
     if (i%10 == 0) { // New line 
      System.out.println(); 
     } 
     System.out.printf("%10.4f", gaussian); 
    } 
    // Display statistics 
    System.out.println("\n\nNumber of generated random values following Gaussian distribution: " + count); 
    System.out.printf("\nLowest value: %10.4f\nHighest value: %10.4f\nAverage:  %10.4f", lowest, highest, (average/count)); 
}