Apakah mungkin untuk mendapatkan angka acak antara 1-100 dan mempertahankan hasil utamanya dalam kisaran 40-60? Maksud saya, itu akan keluar dari kisaran itu jarang, tetapi saya ingin itu terutama dalam kisaran itu ... Apakah mungkin dengan JavaScript / jQuery?
Saat ini saya hanya menggunakan dasar Math.random() * 100 + 1
.
javascript
algorithm
random
numbers
Darryl Huffman
sumber
sumber
Jawaban:
Cara paling sederhana adalah dengan menghasilkan dua angka acak dari 0-50 dan menambahkannya bersama.
Ini memberikan distribusi yang bias terhadap 50, dengan cara yang sama menggulirkan dua bias dadu menuju 7.
Bahkan, dengan menggunakan jumlah "dadu" yang lebih besar (seperti yang disarankan @Falco) , Anda dapat membuat perkiraan yang lebih dekat dengan kurva lonceng:
JSFiddle: http://jsfiddle.net/797qhcza/1/
sumber
Anda memiliki beberapa jawaban yang baik di sini yang memberikan solusi spesifik; izinkan saya menjelaskan untuk Anda solusi umum. Masalahnya adalah:
Solusi umum untuk masalah ini adalah mengerjakan fungsi kuantil dari distribusi yang Anda inginkan, dan kemudian menerapkan fungsi kuantil ke output sumber seragam Anda.
Fungsi kuantil adalah kebalikan dari integral fungsi distribusi yang Anda inginkan . Fungsi distribusi adalah fungsi di mana area di bawah bagian kurva sama dengan probabilitas bahwa item yang dipilih secara acak akan berada di bagian itu.
Saya memberikan contoh bagaimana melakukannya di sini:
http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/
Kode di sana ada di C #, tetapi prinsipnya berlaku untuk bahasa apa pun; harus mudah untuk menyesuaikan solusi untuk JavaScript.
sumber
Mengambil array angka, dll. Tidak efisien. Anda harus mengambil pemetaan yang mengambil angka acak antara 0 hingga 100 dan memetakan distribusi yang Anda butuhkan. Jadi dalam kasus Anda, Anda bisa mengambil untuk mendapatkan distribusi dengan nilai terbanyak di tengah rentang Anda.
f(x)=-(1/25)x2+4x
sumber
x
antara 0 dan 100 (diambil dari pertanyaan ini ):y = (Math.sin(2 * Math.PI * (x/100 - 1/4)) + 1) / 2
Saya mungkin melakukan sesuatu seperti mengatur "peluang" agar nomor diizinkan keluar "di luar batas". Dalam contoh ini, peluang 20% jumlahnya akan menjadi 1-100, jika tidak, 40-60:
fiddle: http://jsfiddle.net/kbv39s9w/
sumber
Saya perlu memecahkan masalah ini beberapa tahun yang lalu dan solusi saya lebih mudah daripada jawaban lainnya.
Saya menghasilkan 3 tebusan antara batas dan rata-rata. Ini menarik hasilnya ke arah tengah, tetapi memungkinkan sepenuhnya mencapai ekstremitas.
sumber
BellFactor
dari 3.Ini terlihat bodoh tetapi Anda dapat menggunakan rand dua kali:
sumber
Tentu itu mungkin. Buat 1-100 acak. Jika angkanya <30 maka hasilkan angka dalam kisaran 1-100 jika tidak menghasilkan dalam kisaran 40-60.
sumber
Ada banyak cara berbeda untuk menghasilkan angka acak tersebut. Salah satu cara untuk melakukannya adalah dengan menghitung jumlah dari beberapa angka acak yang seragam. Berapa banyak angka acak yang Anda jumlah dan berapa kisarannya akan menentukan bagaimana distribusi akhir akan terlihat.
Semakin banyak angka yang Anda simpulkan, semakin bias ke arah pusat. Menggunakan jumlah 1 angka acak sudah diusulkan dalam pertanyaan Anda, tetapi karena Anda perhatikan tidak bias menuju pusat kisaran. Jawaban lain mengusulkan menggunakan jumlah 2 angka acak atau jumlah 3 angka acak .
Anda bahkan bisa mendapatkan lebih banyak bias ke tengah rentang dengan mengambil jumlah angka yang lebih acak. Pada ekstrem Anda bisa mengambil jumlah 99 angka acak yang masing-masing 0 atau 1. Itu akan menjadi distribusi binomial. (Distribusi binomial dalam beberapa hal dapat dilihat sebagai versi diskrit dari distribusi normal). Secara teori ini masih dapat mencakup keseluruhan, tetapi memiliki begitu banyak bias ke pusat sehingga Anda tidak boleh berharap untuk melihatnya mencapai titik akhir.
Pendekatan ini berarti Anda dapat mengubah seberapa besar bias yang Anda inginkan.
sumber
Bagaimana dengan menggunakan sesuatu seperti ini:
Cara saya mengkodekannya memungkinkan Anda untuk mengatur beberapa variabel:
loop = jumlah hasil
mencoba = berapa kali fungsi akan mencoba untuk mendapatkan angka antara 40-60 sebelum berhenti berjalan melalui loop sementara
Bonus tambahan: Ini digunakan do !!! Keagungan yang terbaik
sumber
Anda dapat menulis fungsi yang memetakan nilai-nilai acak antara
[0, 1)
untuk[1, 100]
sesuai dengan berat badan. Pertimbangkan contoh ini:Di sini, nilai
0.95
memetakan ke nilai antara[61, 100]
.Sebenarnya kita memiliki
.05 / .1 = 0.5
, yang, ketika dipetakan[61, 100]
, menghasilkan81
.Inilah fungsinya:
sumber
Inilah solusi berbobot pada 3/4 40-60 dan 1/4 di luar rentang itu.
sumber
Ok, jadi saya memutuskan untuk menambahkan jawaban lain karena saya merasa seperti jawaban terakhir saya, dan juga sebagian besar jawaban di sini, gunakan semacam cara setengah statistik untuk memperoleh hasil tipe lonceng-lonceng. Kode yang saya berikan di bawah berfungsi dengan cara yang sama seperti ketika Anda melempar dadu. Oleh karena itu, paling sulit untuk mendapatkan 1 atau 99, tetapi paling mudah untuk mendapatkan 50.
sumber
Saya akan merekomendasikan menggunakan distribusi beta untuk menghasilkan angka antara 0-1, kemudian meningkatkannya. Ini cukup fleksibel dan dapat membuat berbagai bentuk distribusi.
Berikut sampler cepat dan kotor:
sumber
sumber
Solusi terbaik yang menargetkan masalah ini adalah yang diusulkan oleh BlueRaja - Danny Pflughoeft tetapi saya pikir solusi yang agak lebih cepat dan lebih umum juga perlu disebutkan.
Ketika saya harus menghasilkan angka acak (string, pasangan koordinat, dll.) Memenuhi dua persyaratan
Saya biasanya mulai dengan membuat array angka (string, pasangan koordinat, dll.) Memenuhi persyaratan (Dalam kasus Anda: array angka yang berisi kemungkinan lebih banyak beberapa kali.), Lalu pilih item acak dari array itu. Dengan cara ini, Anda hanya perlu memanggil fungsi acak mahal satu kali per item.
sumber
Distribusi
Larutan
Solusi Umum
sumber
Anda dapat menggunakan nomor acak pembantu untuk menghasilkan angka acak di 40-60 atau 1-100:
sumber
Jika Anda dapat menggunakan
gaussian
fungsinya, gunakan itu. Fungsi ini mengembalikan angka normal denganaverage 0
dansigma 1
.95% dari jumlah ini ada di dalam
average +/- 2*sigma
. Andaaverage = 50
, dansigma = 5
sebagainyasumber
Cara terbaik untuk melakukan itu adalah menghasilkan angka acak yang didistribusikan secara merata dalam satu set angka tertentu, dan kemudian menerapkan fungsi proyeksi ke set antara 0 dan 100 di mana proyeksi lebih mungkin mengenai angka yang Anda inginkan.
Biasanya cara matematika untuk mencapai ini adalah merencanakan fungsi probabilitas dari angka yang Anda inginkan. Kita bisa menggunakan kurva lonceng, tetapi mari kita demi perhitungan yang lebih mudah, hanya bekerja dengan parabola terbalik.
Mari kita membuat parabola sedemikian rupa sehingga akarnya berada pada 0 dan 100 tanpa mencondongkannya. Kami mendapatkan persamaan berikut:
Sekarang, semua area di bawah kurva antara 0 dan 100 mewakili set pertama kami di mana kami ingin angka yang dihasilkan. Di sana, generasi ini sepenuhnya acak. Jadi, yang perlu kita lakukan adalah menemukan batasan set pertama kita.
Batas bawah, tentu saja, 0. Batas atas adalah integral dari fungsi kami di 100, yaitu
Jadi kita tahu bahwa kita perlu membuat angka di suatu tempat antara 0 dan 166.666. Kemudian, kita hanya perlu mengambil nomor itu dan memproyeksikannya ke set kedua kita, yaitu antara 0 dan 100.
Kita tahu bahwa angka acak yang kita hasilkan adalah beberapa integral dari parabola kita dengan input x antara 0 dan 100. Itu berarti kita hanya harus berasumsi bahwa angka acak adalah hasil dari F (x), dan pecahkan untuk x.
Dalam hal ini, F (x) adalah persamaan kubik, dan dalam bentuk
F(x) = ax^3 + bx^2 + cx + d = 0
, pernyataan berikut ini benar:Memecahkan ini untuk x menghasilkan Anda angka acak aktual yang Anda cari, yang dijamin berada dalam kisaran [0, 100] dan kemungkinan jauh lebih dekat dengan pusat daripada tepi.
sumber
Jawaban ini sangat bagus . Tetapi saya ingin memposting instruksi implementasi (saya tidak ke dalam JavaScript, jadi saya harap Anda akan mengerti) untuk situasi yang berbeda.
Asumsikan Anda memiliki rentang dan bobot untuk setiap rentang:
Informasi Statis Awal, dapat di-cache:
Boundary[n] = Boundary[n - 1] + weigh[n - 1]
danBoundary[0] = 0
. Sampel sudahBoundary = {0, 1, 3, 103, 108}
Generasi nomor:
N
dari rentang [0, Jumlah semua bobot).for (i = 0; i < size(Boundary) && N > Boundary[i + 1]; ++i)
i
kisaran th dan hasilkan angka acak dalam kisaran itu.Catatan tambahan untuk optimalisasi kinerja. Kisaran tidak harus dipesan baik urutan naik atau turun, jadi untuk rentang look-up rentang yang lebih cepat yang memiliki bobot tertinggi harus diutamakan dan yang dengan bobot terendah harus berada di urutan terakhir.
sumber