Jak wygenerować losową int
wartość w określonym zakresie?
Próbowałem następujące, ale te nie działają:
Próba 1:
randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.
Próba 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`.
Odpowiedzi:
W Javie 1.7 lub nowszej standardowy sposób to zrobić:
Zobacz odpowiedni JavaDoc . Zaletą tego podejścia jest to, że nie trzeba jawnie inicjować instancji java.util.Random , która może być źródłem nieporozumień i błędów, jeśli zostanie użyta niewłaściwie.
Jednak z drugiej strony nie ma sposobu, aby jawnie ustawić ziarno, więc może być trudno odtworzyć wyniki w sytuacjach, w których jest to przydatne, takich jak testowanie lub zapisywanie stanów gry lub podobne. W takich sytuacjach można zastosować technikę wcześniejszą niż Java 1.7.
W wersjach wcześniejszych niż Java 1.7 standardowy sposób to zrobić:
Zobacz odpowiedni JavaDoc . W praktyce klasa java.util.Random jest często lepsza niż java.lang.Math.random () .
W szczególności nie ma potrzeby ponownego tworzenia koła losowego generowania liczb całkowitych, gdy w standardowej bibliotece znajduje się prosty interfejs API do wykonania zadania.
źródło
max
wartość jestInteger.MAX_VALUE
możliwe jest przepełnienie, skutkuje powstaniemjava.lang.IllegalArgumentException
. Można spróbować z:randInt(0, Integer.MAX_VALUE)
. Ponadto, jeślinextInt((max-min) + 1)
zwraca najwyższą wartość (zakładam, że dość rzadką), czy nie przepełni się ponownie (zakładając, że min i max są wystarczająco wysokimi wartościami)? Jak radzić sobie z tego rodzaju sytuacjami?ThreadLocalRandom
został dodany do Javy 2 i pół roku po zadaniu tego pytania. Zawsze uważałem, że zarządzanie instancją Random jest poza zakresem pytania.Pamiętaj, że to podejście jest bardziej stronnicze i mniej wydajne niż
nextInt
podejście, https://stackoverflow.com/a/738651/360211Jednym standardowym wzorcem do osiągnięcia tego jest:
Funkcja biblioteczna Java Math Math.random () generuje podwójną wartość w zakresie
[0,1)
. Zauważ, że ten zakres nie obejmuje 1.Aby najpierw uzyskać określony zakres wartości, należy pomnożyć przez wielkość zakresu wartości, które chcesz uwzględnić.
Zwraca wartość z zakresu
[0,Max-Min)
, w którym nie jest uwzględnione „Max-Min”.Na przykład, jeśli chcesz
[5,10)
, musisz podać pięć wartości całkowitych, abyś mógł użyćZwróciłoby to wartość z zakresu
[0,5)
, w którym 5 nie jest uwzględnione.Teraz musisz przesunąć ten zakres do zakresu, na który celujesz. Robisz to, dodając wartość Min.
Otrzymasz teraz wartość z zakresu
[Min,Max)
. Idąc za naszym przykładem, oznacza to[5,10)
:Ale to wciąż nie obejmuje
Max
i dostajesz podwójną wartość. Aby uwzględnićMax
wartość, musisz dodać 1 do parametru zakresu,(Max - Min)
a następnie skrócić część dziesiętną, rzutując na liczbę całkowitą. Odbywa się to poprzez:I masz to. Losowa wartość całkowita w zakresie
[Min,Max]
lub na przykład[5,10]
:źródło
Posługiwać się:
Liczba całkowita
x
jest teraz liczbą losową, z możliwym wynikiem5-10
.źródło
Posługiwać się:
źródło
Z java-8wprowadzili metodę
ints(int randomNumberOrigin, int randomNumberBound)
wRandom
klasie.Na przykład, jeśli chcesz wygenerować pięć losowych liczb całkowitych (lub jedną) z zakresu [0, 10], po prostu wykonaj:
Pierwszy parametr wskazuje tylko rozmiar
IntStream
wygenerowanego (który jest przeciążonym sposobem tego, który wytwarza nieograniczoną liczbęIntStream
).Jeśli potrzebujesz wykonać wiele osobnych wywołań, możesz utworzyć nieskończony prymitywny iterator ze strumienia:
Możesz to również zrobić dla
double
ilong
wartości. Mam nadzieję, że to pomoże! :)źródło
streamSize
- podano pierwszy parametr tej metodystreamSize !=0
. Jaka jest różnica, jeślistreamSize
podano 1/2 / n?Możesz edytować swój drugi przykład kodu, aby:
źródło
Wystarczy niewielka modyfikacja pierwszego rozwiązania.
Zobacz więcej tutaj na temat wdrażania
Random
źródło
ThreadLocalRandom
odpowiednik klasyjava.util.Random
dla środowiska wielowątkowego. Generowanie liczby losowej odbywa się lokalnie w każdym wątku. Mamy więc lepszą wydajność, redukując konflikty.x
,y
- interwały np. (1,10)źródło
Math.Random
Klasa w Javie jest 0 oparte. Jeśli więc napiszesz coś takiego:x
będzie między0-9
włącznie.Biorąc pod uwagę następującą tablicę
25
elementów, kod generujący losową liczbę pomiędzy0
(podstawą tablicy) iarray.length
powinien wyglądać następująco:Ponieważ
i.length
powróci25
,nextInt( i.length )
zwróci liczbę między zakresem0-24
. Inna opcja dotyczy tego,Math.Random
który działa w ten sam sposób.Aby lepiej zrozumieć, sprawdź post na forum Random Intervals (archive.org) .
źródło
index
Zmienna nie wpłynie na wynik liczby losowej. Możesz go zainicjować w dowolny sposób, nie martwiąc się o zmianę wyniku. Mam nadzieję że to pomoże.int index = rand.nextInt(i.Length);
int index; \n index = rand...
jeśli ktoś lubi deklaracje i zadania w różnych wierszach. Niektóre standardy kodowania są bardziej rygorystyczne (i bez wyraźnego celu) niż inne.Wybacz mi, że jestem wybredny, ale rozwiązanie sugerowane przez większość, tj.
min + rng.nextInt(max - min + 1))
Wydaje się niebezpieczne ze względu na to, że:rng.nextInt(n)
nie może dosięgnąćInteger.MAX_VALUE
.(max - min)
może powodować przepełnienie, gdymin
jest ujemne.Niezawodne rozwiązanie zwróci prawidłowe wyniki dla dowolnego
min <= max
w [Integer.MIN_VALUE
,Integer.MAX_VALUE
]. Rozważ następującą naiwną implementację:Chociaż nieefektywne, należy pamiętać, że prawdopodobieństwo sukcesu w
while
pętli zawsze będzie wynosić 50% lub więcej.źródło
Można to zrobić po prostu wykonując instrukcję:
Poniżej znajduje się jego kod źródłowy
Randomizer.java
To jest po prostu czyste i proste.
źródło
Zastanawiam się, czy którakolwiek z metod generowania liczb losowych dostarczonych przez bibliotekę Apache Commons Math pasuje do rachunku.
Na przykład:
RandomDataGenerator.nextInt
lubRandomDataGenerator.nextLong
źródło
Weźmy przykład.
Załóżmy, że chcę wygenerować liczbę między 5-10 :
Pozwól nam to zrozumieć ...
źródło
źródło
Wygeneruj liczbę losową dla różnicy min i maks przy użyciu metody nextint (n) , a następnie dodaj liczbę minimalną do wyniku:
źródło
Używam tego:
Jeśli chcesz, możesz rzucić go na liczbę całkowitą.
źródło
new Random
(sprawdź JavaDoc): „Tworzy nowy generator liczb losowych. Ten konstruktor ustawia ziarno generatora liczb losowych na wartość, która prawdopodobnie różni się od jakiegokolwiek innego wywołania tego konstruktora.” Najprawdopodobniej może to wymagać użycia aktualnego czasu jako ziarna. Jeśli ten czas zajmie milisekundy, obecne komputery są wystarczająco szybkie, aby wygenerować tę samą liczbę. Ale poza tym 2147483647 jestInteger.MAX_VALUE
; wynik zależy oczywiście od danych wejściowych, których nie określono.Joshua Bloch. Skuteczna Java. Trzecia edycja.
Począwszy od Java 8
W przypadku pul złączeń wideł i strumieni równoległych użycie,
SplittableRandom
które jest zwykle szybsze, ma lepszą statystyczną niezależność i jednolitość w porównaniu zRandom
.Aby wygenerować losową
int
w zakresie[0, 1_000]:
Aby wygenerować losową
int[100]
tablicę wartości z zakresu[0, 1_000]:
Aby zwrócić strumień losowych wartości:
źródło
.parallel()
? Wydaje mi się, że wygenerowanie 100 liczb losowych byłoby zbyt trywialne, aby uzasadnić paralelizm.parallel
przetwarzania). Nawiasem mówiąc, dla tablicy1_000_000
elementówparallel
wersja była 2 razy szybsza na moim komputerze w porównaniu z sekwencyjnym.Wystarczy użyć klasy Random :
źródło
Te metody mogą być wygodne w użyciu:
Ta metoda zwróci losową liczbę między podaną wartością minimalną i maksymalną:
i ta metoda zwróci losową liczbę z podanej wartości minimalnej i maksymalnej (więc wygenerowana liczba może być również liczbą minimalną lub maksymalną):
źródło
// Since the random number is between the min and max values, simply add 1
. Dlaczego? Nie liczy się min? Zazwyczaj zakres wynosi [min, maks.), Gdzie min jest uwzględniony, a maks. Jest wykluczony. Błędna odpowiedź, odrzucona.min + 1
będzie dwa razy bardziej prawdopodobna niż druga liczbagetRandomNumberBetween
!W przypadku rzutu kostką byłaby to liczba losowa od 1 do 6 (nie od 0 do 6), więc:
źródło
Lub spójrz na RandomUtils z Apache Commons .
źródło
Double.valueOf(Math.random()*(maximum-minimun)).intValue()
jest dość zaciemnionym (i nieefektywnym) sposobem na powiedzenie(int)(Math.random()*(maximum-minimun))
…Oto przydatna klasa do generowania losowego
ints
w zakresie z dowolną kombinacją granic włączających / wyłączających:źródło
Aby wygenerować liczbę losową „pomiędzy dwiema liczbami”, użyj następującego kodu:
Daje to liczbę losową z przedziału od 1 (włącznie) do 11 (wyłącznie), więc zainicjuj wartość upperBound, dodając 1. Na przykład, jeśli chcesz wygenerować liczbę losową od 1 do 10, zainicjuj górną liczbę od 11 zamiast 10
źródło
Możesz to zwięźle osiągnąć w Javie 8:
źródło
źródło
Inną opcją jest właśnie użycie Apache Commons :
źródło
Znalazłem ten przykład Wygeneruj losowe liczby :
Ten przykład generuje losowe liczby całkowite w określonym zakresie.
Przykładowy przebieg tej klasy:
źródło
Lepiej jest używać SecureRandom niż tylko Random.
źródło
private static int SecureRandom rand = new SecureRandom();
2:static {
3:rand.setSeed(...);
4:}
SecureRandom
, zostanie on zaszczepiony przez system. Bezpośrednie wywoływaniesetSeed
jest bardzo niebezpieczne, może zastąpić (naprawdę losowe) ziarno datą. A to z pewnością nie spowodujeSecureRandom
, ponieważ każdy może odgadnąć czas i spróbować zaszczepić własnąSecureRandom
instancję tą informacją.Oto prosta próbka, która pokazuje, jak wygenerować liczbę losową z zamkniętego
[min, max]
zakresu, natomiastmin <= max is true
Możesz użyć go ponownie jako pola w klasie dziur, również mając wszystko
Random.class
metody w jednym miejscuPrzykład wyników:
Źródła:
źródło
To działa dobrze.
źródło