2010-01-31 32 views
16

Với một loạt các kích thước n Tôi muốn tạo ra xác suất ngẫu nhiên cho mỗi chỉ số như vậy mà Sigma(a[0]..a[n-1])=1Tạo một phân bố xác suất

Một kết quả có thể có thể là:

0  1  2  3  4 
0.15 0.2 0.18 0.22 0.25 

Một kết quả hoàn toàn hợp pháp có thể là:

0  1  2  3  4 
0.01 0.01 0.96 0.01 0.01 

Tôi làm cách nào để tạo chúng dễ dàng và nhanh chóng? Các câu trả lời bằng bất kỳ ngôn ngữ nào đều tốt, Java được ưu tiên.

+0

By sigma bạn có nghĩa là độ lệch chuẩn? Tôi hy vọng bạn nhận ra rằng ngay sau khi bạn nói độ lệch chuẩn, bạn tự động ngụ ý rằng bạn đang vẽ các số ngẫu nhiên của mình từ phân phối bình thường. – ldog

+0

Hầu hết các số rút ra của máy tính RNG từ sự phân bố đồng đều. – ldog

+0

Bạn có thể giải quyết vấn đề này bằng cách nhận ra rằng định lý Giới hạn Trung tâm có thể giúp: http://en.wikipedia.org/wiki/Central_limit_theorem – ldog

Trả lời

15

Tác vụ bạn đang cố gắng hoàn thành tương đương với việc vẽ một điểm ngẫu nhiên từ đơn vị đơn vị N chiều.

http://en.wikipedia.org/wiki/Simplex#Random_sampling có thể giúp bạn.

Một giải pháp ngây thơ có thể đi như sau:

public static double[] getArray(int n) 
    { 
     double a[] = new double[n]; 
     double s = 0.0d; 
     Random random = new Random(); 
     for (int i = 0; i < n; i++) 
     { 
      a [i] = 1.0d - random.nextDouble(); 
      a [i] = -1 * Math.log(a[i]); 
      s += a[i]; 
     } 
     for (int i = 0; i < n; i++) 
     { 
      a [i] /= s; 
     } 
     return a; 
    } 

Để vẽ một điểm thống nhất từ các đơn vị simplex N-chiều, chúng ta phải mất một vector của biến ngẫu nhiên theo cấp số nhân phân phối, sau đó bình thường hóa nó bằng tổng của các biến đó. Để có được giá trị phân bổ theo cấp số nhân, chúng tôi lấy giá trị âm log âm được phân phối đồng đều.

+3

Trong hầu hết các ngôn ngữ, bạn nên tạo 'Random' chỉ một lần, hoặc bạn sẽ không nhận được kết quả ngẫu nhiên (và trong nhiều trường hợp - cùng một số hơn và hơn). Tôi cũng lo lắng về việc sử dụng 'log' - bạn có thể giải thích lý do tại sao nó có? – Kobi

+0

+1 để tham khảo tốt, nhưng tôi nghĩ 'nextDouble()' đã điều chỉnh để phân phối đồng đều: http://java.sun.com/javase/6/docs/api/java/util/Random.html#nextDouble() – trashgod

+0

Kobi, cảm ơn bạn đã chỉ ra điều mới 'Random()'. Đối với 'log' - tôi đã chỉnh sửa bài đăng của mình để bao gồm giải thích kỹ lưỡng hơn. – viaclectic

22

Nhận n số ngẫu nhiên, tính tổng của chúng và chuẩn hóa số tiền thành 1 bằng cách chia từng số bằng tổng.

+0

Nice :) không nghĩ về điều đó ... תודה! –

+12

Điều này giới thiệu sự thiên vị. Bạn không thể lấy mẫu thống nhất từ ​​một đơn giản theo cách này. – dreeves

+0

@dreeves - bạn có thể xây dựng không? –

0

Nếu bạn muốn tạo giá trị từ phân phối bình thường một cách hiệu quả, hãy thử Box Muller Transformation.

+0

Mẹo hay, nhưng tôi tin rằng nó không phải là germane. – dreeves

1

Điều này tương đối muộn, nhưng để hiển thị phần bổ sung cho câu trả lời đơn giản và đơn giản của @ Kobi được đưa ra trong paper này được chỉ định bởi @dreeves. Phương pháp (nếu tôi hiểu nó rõ ràng) là

  1. Tạo n-1 biệt giá trị từ khoảng [1, 2, ..., M-1].
  2. Sắp xếp kết quả vector
  3. Thêm 0 và M làm phần tử đầu tiên và cuối cùng của véc-tơ kết quả.
  4. Tạo một véc tơ mới bằng cách tính toán x i - x i-1 trong đó i = 1,2, ... n. Đó là, vectơ mới được tạo thành từ sự khác biệt giữa các phần tử liên tiếp của vector cũ.
  5. Chia từng phần tử của véc tơ mới cho M. Bạn có bản phân phối đồng đều của mình!

Tôi tò mò muốn biết nếu tạo biệt giá trị ngẫu nhiên và bình thường hóa chúng tới 1 bằng cách chia cho tổng của chúng cũng sẽ tạo ra một phân bố đều.

0

Nhận n số ngẫu nhiên, tính tổng của chúng và chuẩn hóa số tiền thành 1 bằng cách chia từng số với tổng.

Expanding on Kobi's answer, đây là chức năng Java thực hiện chính xác điều đó.

public static double[] getRandDistArray(int n) { 
    double randArray[] = new double[n]; 
    double sum = 0; 

    // Generate n random numbers 
    for (int i = 0; i < randArray.length; i++) { 
     randArray[i] = Math.random(); 
     sum += randArray[i]; 
    } 

    // Normalize sum to 1 
    for (int i = 0; i < randArray.length; i++) { 
     randArray[i] /= sum; 
    } 
    return randArray; 
} 

Trong một hoạt động kiểm tra, getRandDistArray(5) trả lại sau

[0.1796505603694718, 0.31518724882558813, 0.15226147256596428, 0.30954417535503603, 0.043356542883939767] 
Các vấn đề liên quan