Dalam aplikasi kecil yang ditulis dalam C / C ++, saya menghadapi masalah dengan rand
fungsi dan mungkin seed:
Saya ingin menghasilkan urutan angka acak yang memiliki urutan berbeda, yaitu dengan nilai logaritma yang berbeda (basis 2). Tetapi tampaknya semua angka yang dihasilkan memiliki urutan yang sama, berfluktuasi hanya antara 2 ^ 25 dan 2 ^ 30.
Apakah karena rand()
diunggulkan dengan waktu Unix yang saat ini jumlahnya relatif besar? Apa yang saya lupakan? Saya rand()
hanya menyemai sekali di awal main()
.
rand()
untuk mengembalikan angka-angka yang terdistribusi secara seragam (dokumentasi dengan peringkat Google tinggi secara eksplisit mengatakan demikian) Saya tidak berpikir pertanyaan ini berguna untuk pembaca masa depan. Itu sebabnya pilihlah, tapi jangan biarkan itu mencegah Anda menggunakan SO.Jawaban:
Hanya ada 3% dari angka antara 1 dan 2 30 yang TIDAK antara 2 25 dan 2 30 . Jadi, ini kedengarannya normal :)
Karena 2 25 /2 30 = 2 -5 = 1/32 = 0,03125 = 3,125%
sumber
>>
bitshifting - ini akan memberi Anda angka yang lebih kecil. (Atau mengambil modulus dengan%
.)0
- dan jika setiap bit acak ...Hijau terang adalah wilayah antara 0 dan 2 25 ; hijau gelap adalah wilayah antara 2 25 dan 2 30 . Kutu adalah kekuatan 2.
sumber
Anda harus lebih tepat: Anda menginginkan nilai logaritma basis 2 yang berbeda tetapi distribusi apa yang Anda inginkan untuk ini? Fungsi standar rand () menghasilkan distribusi yang seragam, Anda harus mengubah output ini menggunakan fungsi kuantil yang terkait dengan distribusi yang Anda inginkan.
Jika Anda memberi tahu kami distribusinya maka kami dapat memberi tahu Anda
quantile
fungsi yang Anda butuhkan.sumber
Jika Anda ingin berbagai urutan besarnya, mengapa tidak coba saja
pow(2, rand())
? Atau mungkin memilih pesanan langsung sebagai rand (), seperti yang disarankan Harold?sumber
rand()
bisa naikRAND_MAX
, Anda benar-benar perlu mengukur nomor acak Anda agar hasilnya tidak melimpah ...@ C4stor membuat poin bagus. Tetapi, untuk kasus yang lebih umum dan lebih mudah dipahami untuk manusia (basis 10): untuk rentang dari 1 hingga 10 ^ n, ~ 90% dari angka adalah dari 10 ^ (n-1) hingga 10 ^ n, oleh karena itu, ~ 99% dari angka berubah dari 10 ^ (n-2) menjadi 10 ^ n. Terus tambahkan desimal sebanyak yang Anda inginkan.
Matematika lucu, jika Anda terus melakukan ini untuk n, Anda dapat melihat bahwa dari 1 hingga 10 ^ n, 99,9999 ...% = 100% dari angka berasal dari 10 ^ 0 hingga 10 ^ n dengan metode ini.
Sekarang tentang kode, jika Anda ingin nomor acak dengan urutan acak besarnya, dari 0 hingga 10 ^ n, Anda bisa melakukannya:
Hasilkan angka acak kecil dari 0 hingga n
Jika Anda mengetahui rentang yang dimiliki n, hasilkan sejumlah besar pesanan acak 10 ^ k dengan k> max {n}.
Potong angka acak yang lebih panjang untuk mendapatkan n digit angka acak besar ini.
sumber
Jawaban dasar (dan benar) sudah diberikan dan diterima di atas: ada 10 angka antara 0 dan 9, 90 angka antara 10 dan 99, 900 antara 100 dan 999, dll.
Untuk cara yang efisien secara komputasi untuk mendapatkan distribusi dengan kira - kira distribusi logaritmik, Anda ingin menggeser-kanan nomor acak Anda dengan nomor acak:
Ini tidak sempurna, tetapi jauh lebih cepat daripada komputasi
pow(2, rand()*scalefactor)
. Ini akan menjadi "kental" dalam arti bahwa distribusi akan seragam untuk angka dalam faktor 2 (seragam untuk 128 hingga 255, setengah kepadatan untuk 256 hingga 1023, dll).Berikut adalah histogram dari frekuensi angka 0 hingga 31 (dalam sampel 1M):
sumber
rand()>>(rand()&31);
, orang akan secara intuitif mengharapkan 1/32 dari angka-angka itu memiliki 32 bit, dan 1/32 dari angka-angka itu memiliki 31 bit, dan 1/32 dari angka-angka itu memiliki 30 bit, dll. Tapi itu bukan hasil yang Anda dapatkan, hanya sekitar 1/64 dari angka akan menghasilkan 32 bit, sementara hampir setengahnya harus 0. Karena matematika mental saya tidak setuju dengan pengukuran Anda, saya harus melakukan pengukuran sendiri untuk mencari ini keluar.Ada jumlah angka yang sama persis antara 0 dan 2 ^ 29 dan 2 ^ 29 dan 2 ^ 30.
Cara lain untuk melihat masalah: pertimbangkan representasi biner dari angka acak yang Anda hasilkan, probabilitas bahwa bit tertinggi adalah 1 sama dengan 1/2, dan, karena itu, Anda mendapatkan pesanan 29 dalam setengah kasus. Yang Anda inginkan adalah melihat angka yang di bawah 2 ^ 25, tetapi itu berarti 5 bit tertinggi semuanya nol, yang terjadi dengan probabilitas rendah 1/32. Kemungkinannya adalah bahwa bahkan jika Anda menjalankannya untuk waktu yang lama Anda tidak akan pernah melihat urutan di bawah 15 sama sekali (kemungkinannya adalah seperti menggulung 6 6 kali berturut-turut).
Sekarang, bagian dari pertanyaan Anda tentang benih. Tidak, seed tidak dapat menentukan rentang angka yang dihasilkan, hanya menentukan elemen awal pertama. Pikirkan rand () sebagai urutan semua angka yang mungkin ada dalam kisaran (permutasi yang telah ditentukan). Benih menentukan di mana Anda mulai menggambar angka dari urutan. Inilah mengapa jika Anda ingin keacakan (semu), Anda menggunakan waktu saat ini untuk menginisialisasi urutan: Anda tidak peduli bahwa posisi yang Anda mulai tidak terdistribusi secara seragam, yang penting adalah Anda tidak pernah memulai dari posisi yang sama.
sumber
menggunakannya
pow(2,rand())
akan memberikan jawaban dalam urutan besarnya yang diinginkan !!sumber
Jika Anda ingin menggunakan nomor acak dari layanan online yang dapat Anda gunakan wget untuk itu, Anda mungkin ingin melihat Anda juga dapat menggunakan layanan seperti random.org untuk pembuatan nomor acak Anda, Anda dapat menangkapnya menggunakan wget dan kemudian membaca angka dari file yang diunduh
http://programmingconsole.blogspot.in/2013/11/a-better-and-different-way-to-generate.html
sumber