Bagaimana cara menghasilkan int
nilai acak dalam rentang tertentu?
Saya sudah mencoba yang berikut ini, tetapi itu tidak berhasil:
Percobaan 1:
randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.
Percobaan 2:
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum = minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.
Jawaban:
Di Jawa 1.7 atau lebih baru , cara standar untuk melakukan ini adalah sebagai berikut:
Lihat JavaDoc yang relevan . Pendekatan ini memiliki keuntungan karena tidak perlu menginisialisasi secara eksplisit contoh java.util.Random , yang dapat menjadi sumber kebingungan dan kesalahan jika digunakan secara tidak tepat.
Namun, sebaliknya tidak ada cara untuk mengatur benih secara eksplisit sehingga sulit untuk mereproduksi hasil dalam situasi di mana itu berguna seperti menguji atau menyimpan status permainan atau serupa. Dalam situasi tersebut, teknik pra-Jawa 1.7 yang ditunjukkan di bawah ini dapat digunakan.
Sebelum Java 1.7 , cara standar untuk melakukan ini adalah sebagai berikut:
Lihat JavaDoc yang relevan . Dalam praktiknya, kelas java.util.Random sering lebih disukai daripada java.lang.Math.random () .
Secara khusus, tidak perlu menemukan kembali roda pembangkitan bilangan bulat acak ketika ada API langsung dalam pustaka standar untuk menyelesaikan tugas.
sumber
max
nilainyaInteger.MAX_VALUE
dimungkinkan melimpah, menghasilkan ajava.lang.IllegalArgumentException
. Anda dapat mencoba dengan:randInt(0, Integer.MAX_VALUE)
. Juga, jikanextInt((max-min) + 1)
mengembalikan nilai paling tinggi (sangat jarang, saya berasumsi) tidak akan meluap lagi (seandainya min dan maks adalah nilai yang cukup tinggi)? Bagaimana cara menghadapi situasi seperti ini?ThreadLocalRandom
ditambahkan ke Java 2 1/2 tahun setelah pertanyaan ini pertama kali ditanyakan. Saya selalu berpendapat bahwa manajemen instance Acak berada di luar ruang lingkup pertanyaan.Perhatikan bahwa pendekatan ini lebih bias dan kurang efisien daripada
nextInt
pendekatan, https://stackoverflow.com/a/738651/360211Satu pola standar untuk mencapai ini adalah:
The Java Math fungsi library Math.random () menghasilkan nilai ganda dalam kisaran
[0,1)
. Perhatikan kisaran ini tidak termasuk 1.Untuk mendapatkan rentang nilai tertentu terlebih dahulu, Anda perlu mengalikan dengan besarnya rentang nilai yang ingin Anda liput.
Ini mengembalikan nilai dalam rentang
[0,Max-Min)
, di mana 'Max-Min' tidak termasuk.Misalnya, jika Anda ingin
[5,10)
, Anda harus mencakup lima nilai integer sehingga Anda gunakanIni akan mengembalikan nilai dalam rentang
[0,5)
, di mana 5 tidak termasuk.Sekarang Anda perlu menggeser rentang ini ke kisaran yang Anda targetkan. Anda melakukan ini dengan menambahkan nilai Min.
Anda sekarang akan mendapatkan nilai dalam rentang tersebut
[Min,Max)
. Mengikuti contoh kita, itu berarti[5,10)
:Tapi, ini masih belum termasuk
Max
dan Anda mendapatkan nilai ganda. UntukMax
memasukkan nilai, Anda perlu menambahkan 1 ke rentang parameter Anda(Max - Min)
dan kemudian memotong bagian desimal dengan melakukan casting ke int. Ini dicapai melalui:Dan begitulah. Nilai integer acak dalam rentang
[Min,Max]
, atau per contoh[5,10]
:sumber
Menggunakan:
Bilangan bulat
x
sekarang adalah angka acak yang memiliki kemungkinan hasil5-10
.sumber
Menggunakan:
sumber
Dengan java-8mereka memperkenalkan metode
ints(int randomNumberOrigin, int randomNumberBound)
diRandom
kelas.Misalnya jika Anda ingin menghasilkan lima bilangan bulat acak (atau satu) di kisaran [0, 10], lakukan saja:
Parameter pertama menunjukkan hanya ukuran yang
IntStream
dihasilkan (yang merupakan metode kelebihan yang menghasilkan tidak terbatasIntStream
).Jika Anda perlu melakukan beberapa panggilan terpisah, Anda dapat membuat iterator primitif tak terbatas dari aliran:
Anda juga dapat melakukannya untuk
double
danlong
menghargai. Saya harap ini membantu! :)sumber
streamSize
- parameter pertama dari metode ini diberikanstreamSize !=0
. Apa perbedaannya jikastreamSize
1/2 / n diberikan?Anda dapat mengedit contoh kode kedua Anda ke:
sumber
Cukup modifikasi kecil dari solusi pertama Anda sudah cukup.
Lihat lebih lanjut di sini untuk implementasi
Random
sumber
ThreadLocalRandom
setara dengan kelasjava.util.Random
untuk lingkungan multithreaded. Menghasilkan nomor acak dilakukan secara lokal di masing-masing utas. Jadi kami memiliki kinerja yang lebih baik dengan mengurangi konflik.x
,y
- interval misalnya (1,10)sumber
The
Math.Random
kelas dalam Java adalah 0 berbasis. Jadi, jika Anda menulis sesuatu seperti ini:x
akan berada di antara0-9
inklusif.Jadi, mengingat
25
item array berikut , kode untuk menghasilkan angka acak antara0
(basis array) danarray.length
akan menjadi:Karena
i.length
akan kembali25
,nextInt( i.length )
akan mengembalikan angka di antara kisaran0-24
. Pilihan lainnya adalahMath.Random
yang bekerja dengan cara yang sama.Untuk pemahaman yang lebih baik, lihat posting forum Interval Acak (archive.org) .
sumber
index
Variabel tidak akan memengaruhi hasil angka acak. Anda dapat memilih untuk menginisialisasi dengan cara apa pun yang Anda inginkan tanpa harus khawatir mengubah hasilnya. Semoga ini membantu.int index = rand.nextInt(i.Length);
int index; \n index = rand...
jika seseorang menyukai deklarasi dan penugasan pada baris yang berbeda. Beberapa standar pengkodean lebih ketat (dan tanpa tujuan yang jelas) daripada yang lain.Maafkan saya karena teliti, tetapi solusi yang disarankan oleh mayoritas, yaitu
min + rng.nextInt(max - min + 1))
, tampaknya berbahaya karena fakta bahwa:rng.nextInt(n)
tidak dapat dicapaiInteger.MAX_VALUE
.(max - min)
dapat menyebabkan kelebihan ketikamin
negatif.Solusi yang sangat mudah akan memberikan hasil yang benar untuk semua yang ada
min <= max
dalam [Integer.MIN_VALUE
,Integer.MAX_VALUE
]. Pertimbangkan implementasi naif berikut:Meskipun tidak efisien, perhatikan bahwa probabilitas keberhasilan dalam
while
loop akan selalu 50% atau lebih tinggi.sumber
Itu bisa dilakukan dengan hanya melakukan pernyataan:
Di bawah ini adalah kode sumbernya
Randomizer.java
Itu bersih dan sederhana.
sumber
Saya bertanya-tanya apakah ada salah satu metode menghasilkan angka acak yang disediakan oleh perpustakaan Apache Commons Math akan sesuai dengan tagihan.
Misalnya:
RandomDataGenerator.nextInt
atauRandomDataGenerator.nextLong
sumber
Mari kita ambil contoh.
Misalkan saya ingin menghasilkan angka antara 5-10 :
Mari kita pahami ini ...
sumber
sumber
Hasilkan angka acak untuk perbedaan min dan maks dengan menggunakan metode nextint (n) dan kemudian tambahkan angka min ke hasilnya:
sumber
Saya menggunakan ini:
Anda bisa melemparkannya ke Integer jika mau.
sumber
new Random
(periksa JavaDoc): "Membuat generator nomor acak baru. Konstruktor ini mengatur seed dari generator nomor acak ke nilai yang sangat mungkin berbeda dari permintaan lain dari konstruktor ini." Sangat mungkin hanya melibatkan menggunakan waktu saat ini sebagai benih. Jika waktu itu menggunakan milidetik maka komputer saat ini cukup cepat untuk menghasilkan angka yang sama. Namun selain itu 2147483647 adalahInteger.MAX_VALUE
; output jelas tergantung pada input, yang belum Anda tentukan.Joshua Bloch. Jawa yang efektif. Edisi ketiga.
Mulai dari Jawa 8
Untuk cabang gabungan garpu dan aliran paralel, gunakan
SplittableRandom
yang biasanya lebih cepat, memiliki kemandirian statistik yang lebih baik dan sifat keseragaman dibandingkan denganRandom
.Untuk menghasilkan acak
int
dalam kisaran[0, 1_000]:
Untuk menghasilkan
int[100]
array nilai acak dalam rentang[0, 1_000]:
Untuk mengembalikan Stream nilai acak:
sumber
.parallel()
? Sepertinya saya seperti menghasilkan 100 angka acak akan terlalu sepele untuk menjamin paralelisme.parallel
pemrosesan). By the way, untuk array1_000_000
elemen,parallel
versi itu 2 kali lebih cepat pada mesin saya dibandingkan dengan berurutan.Cukup gunakan kelas Acak :
sumber
Metode ini mungkin nyaman digunakan:
Metode ini akan mengembalikan angka acak antara nilai minimum dan maksimum yang disediakan:
dan metode ini akan mengembalikan angka acak dari nilai min dan max yang disediakan (sehingga angka yang dihasilkan juga bisa berupa angka min atau max):
sumber
// Since the random number is between the min and max values, simply add 1
. Mengapa? Tidak dihitung? Biasanya kisarannya adalah [min, maks) di mana min disertakan dan maks dikecualikan. Jawaban salah, ditolak.min + 1
akan dua kali lipat dari angka yang akan dihasilkangetRandomNumberBetween
!Dalam hal menggulirkan dadu itu akan menjadi angka acak antara 1 hingga 6 (bukan 0 hingga 6), jadi:
sumber
Atau lihat RandomUtils dari Apache Commons .
sumber
Double.valueOf(Math.random()*(maximum-minimun)).intValue()
adalah cara yang sangat membingungkan (dan tidak efisien) untuk mengatakan(int)(Math.random()*(maximum-minimun))
...Berikut adalah kelas yang membantu untuk menghasilkan acak
ints
dalam kisaran dengan kombinasi batas inklusif / eksklusif:sumber
Untuk menghasilkan angka acak "di antara dua angka", gunakan kode berikut:
Ini memberi Anda angka acak di antara 1 (inklusif) dan 11 (eksklusif), jadi inisialisasi nilai upperBound dengan menambahkan 1. Misalnya, jika Anda ingin menghasilkan angka acak antara 1 hingga 10 maka inisialisasi angka upperBound dengan 11 alih-alih 10.
sumber
Anda dapat mencapainya secara ringkas di Java 8:
sumber
sumber
Opsi lain hanya menggunakan Apache Commons :
sumber
Saya menemukan contoh ini Menghasilkan angka acak :
Contoh ini menghasilkan bilangan bulat acak dalam rentang tertentu.
Contoh menjalankan kelas ini:
sumber
Lebih baik menggunakan SecureRandom daripada hanya Acak.
sumber
private static int SecureRandom rand = new SecureRandom();
2:static {
3:rand.setSeed(...);
4:}
SecureRandom
, itu akan diunggulkan oleh sistem. Memanggil secara langsungsetSeed
sangat berbahaya, mungkin mengganti benih (benar-benar acak) dengan tanggal. Dan itu tentu saja tidak akan menghasilkanSecureRandom
, karena siapa pun dapat menebak waktu dan mencoba dan menyemaiSecureRandom
contoh mereka sendiri dengan informasi itu.Berikut adalah contoh sederhana yang menunjukkan cara menghasilkan angka acak dari
[min, max]
rentang tertutup , sementaramin <= max is true
Anda dapat menggunakannya kembali sebagai bidang dalam kelas lubang, juga memiliki semua
Random.class
metode di satu tempatContoh hasil:
Sumber:
sumber
Ini bekerja dengan baik.
sumber