Pertanyaan Nomor acak dalam rentang berdasarkan distribusi normal


Saya ingin menghasilkan angka acak dengan rentang (n ke m, misalnya 100 hingga 150), tetapi bukan murni acak saya ingin hasilnya didasarkan pada distribusi normal.

Maksud saya, secara umum saya ingin angka-angka "terkumpul" sekitar 125.

Saya telah menemukan paket angka acak ini yang tampaknya memiliki banyak hal yang saya perlukan: http://codeproject.com/KB/recipes/Random.aspx

Ini mendukung berbagai generator acak (termasuk twister mersiene) dan dapat menerapkan generator untuk distribusi.

Tapi saya bingung, jika saya menggunakan generator distribusi normal, angka acak dari sekitar -6 hingga +8 (ternyata kisaran yang sebenarnya adalah float.min to float.max).

Bagaimana skala itu pada rentang yang dibutuhkan saya?


32
2018-05-01 23:37


asal


Jawaban:


Distribusi normal standar memiliki mean 0 dan standar deviasi 1; jika Anda ingin membuat distribusi dengan rata-rata m dan penyimpangan s, cukup kalikan dengan s lalu tambahkan m. Karena distribusi normal secara teoritis tidak terbatas, Anda tidak dapat memiliki batas keras pada rentang Anda, mis. (100 hingga 150) tanpa secara eksplisit menolak angka yang berada di luarnya, tetapi dengan pilihan penyimpangan yang tepat Anda dapat yakin bahwa (mis.) 99% dari jumlah Anda akan berada dalam jangkauan.

Sekitar 99,7% dari populasi berada dalam +/- 3 standar deviasi, jadi jika Anda memilih milik Anda (25/3), seharusnya bekerja dengan baik.

Jadi Anda menginginkan sesuatu seperti: (normal * 8.333) + 125


26
2018-05-01 23:43



Demi kepentingan, itu cukup mudah untuk menghasilkan bilangan acak terdistribusi secara normal dari RNG yang seragam (meskipun harus dilakukan secara berpasangan):

Random rng = new Random();
double r = Math.Sqrt(-2 * Math.Log(rng.NextDouble()));
double θ = 2 * Math.Pi * rng.NextDouble();
double x = r * Math.Cos(θ);
double y = r * Math.Sin(θ);

x dan y sekarang berisi dua bilangan acak independen terdistribusi dengan mean 0 dan varians 1. Anda dapat mengukur dan menerjemahkannya seperlunya untuk mendapatkan kisaran yang Anda inginkan (seperti interjay menjelaskan).


Penjelasan:

Metode ini disebut Transformasi Box-Muller. Ini menggunakan properti dari unit Gaussian dua dimensi yang memiliki nilai densitas itu sendiri, p = exp(-r^2/2), didistribusikan secara merata antara 0 dan 1 (normalisasi konstan dihapus untuk kesederhanaan).

Karena Anda dapat menghasilkan nilai seperti itu dengan mudah menggunakan RNG yang seragam, Anda akan berakhir dengan kontur radius melingkar r = sqrt(-2 * log(p)). Anda kemudian dapat menghasilkan varian acak seragam kedua antara 0 dan 2*pi untuk memberi Anda sudut θ yang menentukan titik unik pada kontur melingkar Anda. Akhirnya, Anda bisa menghasilkan dua i.i.d. variates acak normal dengan mengubah dari koordinat kutub (r, θ) kembali ke koordinat kartesius (x, y).

Properti ini - itu p terdistribusi secara merata - tidak berlaku untuk dimensi lain, itulah mengapa Anda harus menghasilkan dua variasi normal sekaligus.


14
2018-05-02 00:00



Jawaban tzaman benar, tetapi ketika menggunakan perpustakaan yang Anda tautkan ada cara yang lebih sederhana daripada melakukan perhitungan sendiri: The NormalDistribution objek memiliki sifat yang dapat ditulis Mu (artinya mean) dan Sigma(standar deviasi). Jadi pergi dengan nomor tzaman, atur Mu ke 125 dan Sigma hingga 8.333.


4
2018-05-01 23:55



Ini mungkin terlalu sederhana untuk kebutuhan Anda, tetapi cara cepat & murah untuk mendapatkan nomor acak dengan distribusi yang tertimbang menuju pusat adalah dengan hanya menambahkan 2 (atau lebih) nomor acak.

Pikirkan ketika Anda melempar dua dadu 6-sisi dan menambahkannya. Jumlahnya paling sering 7, lalu 6 dan 8, kemudian 5 dan 9, dll. Dan hanya jarang 2 atau 12.


2
2018-05-01 23:44



Berikut adalah algoritm lain yang tidak perlu menghitung Sin / Cos, juga tidak perlu tahu Pi. Jangan tanya saya tentang latar belakang teoritis. Saya pernah menemukannya di suatu tempat dan itulah yang saya gunakan sejak itu. Saya menduga ini semacam normalisasi dari transformasi Box-Muller yang sama yang disebut oleh @Will Vousden. Ini juga menghasilkan hasil berpasangan.

Contohnya adalah VBscript; cukup mudah untuk mengkonversi ke bahasa lain.

Sub calcRandomGauss (byref y1, byref y2)
    Dim x1, x2, w
    Do
        x1 = 2.0 * Rnd() - 1.0
        x2 = 2.0 * Rnd() - 1.0
        w = x1 * x1 + x2 * x2
    Loop While w >= 1.0 Or w = 0  'edited this line, thanks Richard

    w = Sqr((-2.0 * Log(w)) / w )
    y1 = x1 * w
    y2 = x2 * w
End Sub

0
2017-10-09 09:58



Pendekatan yang berbeda untuk masalah ini menggunakan distribusi beta (yang memiliki rentang yang keras, tidak seperti distribusi normal) dan melibatkan pemilihan parameter yang tepat sehingga distribusi memiliki mean yang diberikan dan standar deviasi (akar kuadrat dari varians). Lihat pertanyaan ini.


0
2017-07-30 23:41