Kaip generuoti atsitiktinius sveikus skaičius tam tikrame intervale „Java“?

Kaip sukurti atsitiktinę int reikšmę tam tikrame diapazone?

Bandžiau taip, bet jis neveikia:

Bandymas 1:

 randomNum = minimum + (int)(Math.random() * maximum); // Bug: 'randomNum' can be bigger than 'maximum'. 

Bandymas 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'. 
2994
12 дек. nustatė user42155 gruodžio 12 d 2008-12-12 21:20 '08, 21:20, 2008-12-12 21:20
ответ 61 atsakymas
  • 1
  • 2
  • 3

Java 1.7“ arba naujesnėje versijoje standartinis būdas tai padaryti yra toks:

 import java.util.concurrent.ThreadLocalRandom; // nextInt is normally exclusive of the top value, // so add 1 to make it inclusive int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1); 

Žr. Susiję „JavaDoc“ . Šio požiūrio privalumas yra tas, kad jums nereikia aiškiai inicijuoti java.util egzemplioriaus.Random, kuris gali būti painiavos ir klaidų šaltinis, jei naudojamas netinkamai.

Tačiau, priešingai, neįmanoma aiškiai nustatyti sėklų, todėl gali būti sunku atkurti rezultatus situacijose, kai ji yra naudinga, pavyzdžiui, bandant ar taupant žaidimų būsenas ar panašius. Tokiais atvejais galima naudoti žemiau pateiktą „1.7 Java“ metodą.

Prieš „Java 1.7“ standartinis būdas tai padaryti yra:

 import java.util.Random;  public static int randInt(int min, int max) { // NOTE: This will (intentionally) not run as written so that folks // copy-pasting have to think about how to initialize their // Random instance. Initialization of the Random instance is outside // the main scope of the question, but some decent options are to have // a field that is initialized once and then re-used as needed or to // use ThreadLocalRandom (if using at least Java 1.7). // // In particular, do NOT do 'Random rand = new Random()' here or you // will get not very good / not very random results. Random rand; // nextInt is normally exclusive of the top value, // so add 1 to make it inclusive int randomNum = rand.nextInt((max - min) + 1) + min; return randomNum; } 

Žr. Susiję „JavaDoc“ . Praktiškai java.util.Random klasė dažnai yra geriau nei java.> .

Konkrečiai, nereikia išradinėti atsitiktinių sveikųjų skaičių kartos rato, kai standartinėje bibliotekoje yra paprasta API užduočiai atlikti.

12 дек. Greg Case 12 d. Atsakymas . 2008-12-12 21:25 '08, 21:25 2008-12-12 21:25

Atkreipkite dėmesį, kad šis požiūris yra nextInt ir mažiau veiksmingas nei nextInt požiūris, ngn-wiki.ru.site/questions/1788 / ...

Vienas standartinis šablonas:

 Min + (int)(Math.random() * ((Max - Min) + 1)) 

Java Math Math.random“ () bibliotekos funkcija sukuria dvigubą reikšmę intervale [0,1) . Atkreipkite dėmesį, kad į šį intervalą neįeina 1.

Norėdami pirmiausia gauti tam tikrą reikšmių diapazoną, turite padauginti iš vertybių, kurias norite padengti, vertės.

 Math.random() * ( Max - Min ) 

Tai grąžina reikšmę intervale [0,Max-Min) , kur nėra įtraukta „Max-Min“.

Pavyzdžiui, jei norite [5,10) , turite naudoti penkias sveikasis skaičius, kad galėtumėte naudoti

 Math.random() * 5 
border=0

Tai grąžins reikšmę intervale [0,5) , kur 5 neįtraukta.

Dabar šį diapazoną reikia perkelti į diapazoną, kuriam jūs siekiate. Tai darote pridedant „Min“ reikšmę.

 Min + (Math.random() * (Max - Min)) 

Dabar jūs gausite vertę intervale [Min,Max) . Vadovaudamiesi mūsų pavyzdžiu, tai reiškia [5,10) :

 5 + (Math.random() * (10 - 5)) 

Tačiau tai vis dar neapima „ Max ir jūs gaunate dvigubą vertę. Norint gauti Max vertę, turite pridėti 1 prie savo diapazono parametro (Max - Min) ir tada trinties dešimtainę dalį, nuspaudę į int. Tai pasiekiama:

 Min + (int)(Math.random() * ((Max - Min) + 1)) 

Ir čia jūs turite. Atsitiktinis sveikasis skaičius intervale [Min,Max] arba pavyzdyje [5,10] :

 5 + (int)(Math.random() * ((10 - 5) + 1)) 
1347
12 дек. Atsakymas duotas TJ_Fischer 12 d. 2008-12-12 21:35 '08 at 9:35 2008-12-12 21:35

Naudoti:

 Random ran = new Random(); int x = ran.nextInt(6) + 5; 

Dabar sveikasis skaičius x atsitiktinis skaičius, kurio galimas rezultatas yra 5-10 .

317
04 сент. atsakymas suteiktas „ 04“ sep . 2009-09-04 07:23 '09, 7:23 am. 2009-09-04 07:23

Naudoti:

 minimum + rn.nextInt(maxValue - minvalue + 1) 
130
12 дек. Atsakymą pateikė krosenvold 12.12 . 2008-12-12 21:25 '08, 21:25 2008-12-12 21:25

Su jie įdiegė ints(int randomNumberOrigin, int randomNumberBound) metodą ints(int randomNumberOrigin, int randomNumberBound) Random klasės.

Pvz., Jei norite sukurti penkis atsitiktinius sveikus skaičius (arba vieną) intervale [0, 10], tiesiog paleiskite:

 Random r = new Random(); int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray(); int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt(); 

Pirmasis parametras nurodo tik sukurto „ IntStream (kuris yra perkrautas metodas, sukuriantis neribotą „ IntStream ).

Jei reikia atlikti kelis atskirus skambučius, galite sukurti begalinį primityvų iteratorių iš srauto:

 public final class IntRandomNumberGenerator { private PrimitiveIterator.OfInt randomIterator;  public IntRandomNumberGenerator(int min, int max) { randomIterator = new Random().ints(min, max + 1).iterator(); }  public int nextInt() { return randomIterator.nextInt(); } } 

Taip pat galite tai padaryti double ir long vertėms.

Tikiuosi, kad tai padės :)

103
26 нояб. Atsakymą pateikė Alexis C. 26 lapkričio. 2014-11-26 21:29 '14, 21:29 2014-11-26 21:29

Antrąjį kodo pavyzdį galite redaguoti:

 Random rn = new Random(); int range = maximum - minimum + 1; int randomNum = rn.nextInt(range) + minimum; 
92
12 дек. Atsakymą Billas Lizardas pateikia gruodžio 12 d. 2008-12-12 21:31 '08 at 9:31 pm 2008-12-12 21:31

Užtenka nedidelio pirmojo sprendimo pakeitimo.

 Random rand = new Random(); randomNum = minimum + rand.nextInt((maximum - minimum) + 1); 

Skaitykite daugiau apie Random

91
13 марта '15 в 1:44 2015-03-13 01:44 atsakymas pateikiamas šešioliktainis kovo 13 d. 15 val. 1:44 2015-03-13 01:44

ThreadLocalRandom yra java.util.Random klasės ekvivalentas daugiamandatėje aplinkoje. Atsitiktinis skaičiaus generavimas atliekamas vietoje kiekviename sraute. Taigi, mes turime geresnių rezultatų mažinant konfliktus.

 int rand = ThreadLocalRandom.current().nextInt(x,y); 

x, y - intervalai, pvz. (1.10)

58
13 февр. atsakymas į Andrew 13 vasario mėn 2013-02-13 02:19 '13, 2:19, 2013-02-13 02:19

Java Math.Random klasė grindžiama 0. Taigi, jei rašote kažką panašaus:

 Random rand = new Random(); int x = rand.nextInt(10); 

x bus tarp 0-9 imtinai.

Taigi, atsižvelgiant į sekančią 25 elementų array.length , kodas, skirtas atsitiktiniam skaičiui generuoti tarp 0 (masyvo bazė) ir array.length bus:

 String[] i = new String[25]; Random rand = new Random(); int index = 0; index = rand.nextInt( i.length ); 

Kadangi i.length grįžta į 25 , nextInt( i.length ) grąžina skaičių nuo 0 iki 0-24 . Kitas variantas yra su Math.Random kuris veikia taip pat.

 index = (int) Math.floor(Math.random() * i.length); 

Norėdami geriau suprasti, skaitykite forumo pranešimus atsitiktiniais intervalais (archive.org) .

56
08 янв. Atsakymą pateikė Matt R Jan 08 2009-01-08 18:04 '09 18:04 2009-01-08 18:04

Atleisk man už blaivumą, bet daugumos pasiūlytas sprendimas, t. min + rng.nextInt(max - min + 1)) , atrodo pavojingas, nes:

  • rng.nextInt(n) negali pasiekti Integer.MAX_VALUE .
  • (max - min) gali perpildyti, kai min neigiamas.

Įtikinantis sprendimas grąžins teisingus rezultatus bet kokiam min <= max viduje [ Integer.MIN_VALUE , Integer.MAX_VALUE ]. Apsvarstykite šį naivų įgyvendinimą:

 int nextIntInRange(int min, int max, Random rng) { if (min > max) { throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "]."); } int diff = max - min; if (diff >= 0  diff != Integer.MAX_VALUE) { return (min + rng.nextInt(diff + 1)); } int i; do { i = rng.nextInt(); } while (i < min || i > max); return i; } 

Nors neveiksmingas, kad sėkmės rodiklis per visą while bus 50% ar didesnis.

45
10 янв. Joel Sjöstrand atsakymas, sausio 10 d 2011-01-10 16:19 '11, 16:19, 2011-01-10 16:19

Įdomu, ar skaičiavimui tinka bet koks Apache Commons Math bibliotekos pateikiamas atsitiktinių skaičių generavimo metodas.

Pavyzdžiui: RandomDataGenerator.nextInt arba RandomDataGenerator.nextLong

27
12 дек. Atsakymas pateikiamas Chinnery 12 Dec. 2008-12-12 21:27 '08 at 9:27 pm 2008-12-12 21:27

Paimkite pavyzdį.

Tarkime, noriu sukurti numerį nuo 5 iki 10 :

 int max = 10; int min = 5; int diff = max - min; Random rn = new Random(); int i = rn.nextInt(diff + 1); i += min; System.out.print("The Random Number is " + i); 

Suprasime tai ...

Inicijuoti maksimalią vertę su mažiausia verte ir min.

Dabar turime nustatyti, kiek galimų verčių galima gauti. Šiuo pavyzdžiu bus:

5, 6, 7, 8, 9, 10

Taigi, tai bus maks. Min + 1.

t.y. 10 - 5 + 1 = 6

Atsitiktinis skaičius generuos skaičių nuo 0 iki 5 .

t.y. 0, 1, 2, 3, 4, 5

Min. Vertės pridėjimas prie atsitiktinio skaičiaus:

5, 6, 7, 8, 9, 10

Todėl gauname norimą diapazoną.

26
03 авг. atsakymas, kurį pateikė Sunil Chawla 03 rugpjūtis 2014-08-03 06:07 '14 at 6:07 2014-08-03 06:07
  rand.nextInt((max+1) - min) + min; 
23
12 дек. Michael Myers atsakymas, pateiktas gruodžio 12 d 2008-12-12 21:25 '08, 21:25 2008-12-12 21:25

Sukurkite atsitiktinį skaičių, skirtą tarp min ir max, naudodami Nextint (n) metodą, tada pridėkite minimalų skaičių rezultatui:

 Random rn = new Random(); int result = rn.nextInt(max - min + 1) + min; System.out.println(result); 
19
27 мая '15 в 13:43 2015-05-27 13:43 atsakymą gifpifas pateikia gegužės 15 d. 15 val. 13:43 2015-05-27 13:43

Čia yra naudinga klasė atsitiktinių ints generavimui diapazone su bet kokiu imtinai / išskirtinėmis ribomis:

 import java.util.Random; public class RandomRange extends Random { public int nextIncInc(int min, int max) { return nextInt(max - min + 1) + min; } public int nextExcInc(int min, int max) { return nextInt(max - min) + 1 + min; } public int nextExcExc(int min, int max) { return nextInt(max - min - 1) + 1 + min; } public int nextIncExc(int min, int max) { return nextInt(max - min) + min; } } 
19
15 февр. Garrett Hall atsakymas vasario 15 d. 2012-02-15 19:19 '12, 19:19, 2012-02-15 19:19

Jei kaulai sukasi, tai bus atsitiktinis skaičius nuo 1 iki 6 (ne nuo 0 iki 6), todėl:

 face = 1 + randomNumbers.nextInt(6); 
17
16 февр. atsakymą duoda vasario 16 d. 2010-02-16 11:50 '10 at 11:50 2010-02-16 11:50

Šie metodai gali būti patogūs naudoti:

Šis metodas grąžina atsitiktinį skaičių tarp pateiktų minimalių ir maksimalių verčių:

 public static int getRandomNumberBetween(int min, int max) { Random foo = new Random(); int randomNumber = foo.nextInt(max - min) + min; if (randomNumber == min) { // Since the random number is between the min and max values, simply add 1 return min + 1; } else { return randomNumber; } } 

ir šis metodas grąžins atsitiktinį skaičių pateiktų minimalių ir maksimalių verčių (todėl sukurtas skaičius taip pat gali būti minimalus arba maksimalus skaičius):

 public static int getRandomNumberFrom(int min, int max) { Random foo = new Random(); int randomNumber = foo.nextInt((max + 1) - min) + min; return randomNumber; } 
17
12 авг. Atsakyti Luke Taylor 12 rug. 2012-08-12 18:01 '12 at 18:01 pm 2012-08-12 18:01

Pradedant „Java 7“, jūs neturėtumėte naudoti Random . Daugumai programų atsitiktinių skaičių generatorius yra „ ThreadLocalRandom .

Šakių sujungimui ir lygiagrečiam sriegiui naudokite „ SplittableRandom .

Joshua Bloch. Efektyvi java. Trečiasis leidimas.

Pradedant „Java“ 8

Šakių sujungimui ir lygiagrečiam sriegiui naudokite „ SplittableRandom kuris paprastai yra greitesnis, turi geresnes statistines nepriklausomas ir vienodas savybes, lyginant su Random .

Norėdami sukurti atsitiktinį int diapazoną [0, 1_000]:

 int n = new SplittableRandom().nextInt(0, 1_001); 

Norėdami sukurti atsitiktinę int[100] reikšmių diapazoną diapazone [0, 1_000]:

 int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray(); 

Jei norite grąžinti atsitiktinių verčių srautą:

 IntStream stream = new SplittableRandom().ints(100, 0, 1_001); 
17
12 апр. Atsakyti Oleksandr 12 balandžio. 2018-04-12 00:54 '18 prie 0:54 2018-04-12 00:54
 int random = minimum + Double.valueOf(Math.random()*(maximum-minimun)).intValue(); 

Arba pažvelkite į „ Apache Commons“ atsitiktinius įvykius.

17
12 дек. Atsakymą pateikė user2427 12 Dec. 2008-12-12 21:28 '08 21:28 2008-12-12 21:28

Radau šį pavyzdį. Sukurti atsitiktinius skaičius :


Šiame pavyzdyje atsitiktiniai sveikieji skaičiai generuojami konkrečiame intervale.

 import java.util.Random;  public final class RandomRange { public static final void main(String... aArgs){ log("Generating random integers in the range 1..10."); int START = 1; int END = 10; Random random = new Random(); for (int idx = 1; idx <= 10; ++idx){ showRandomInteger(START, END, random); } log("Done."); } private static void showRandomInteger(int aStart, int aEnd, Random aRandom){ if ( aStart > aEnd ) { throw new IllegalArgumentException("Start cannot exceed End."); } //get the range, casting to long to avoid overflow problems long range = (long)aEnd - (long)aStart + 1; // compute a fraction of the range, 0 <= frac < range long fraction = (long)(range * aRandom.nextDouble()); int randomNumber = (int)(fraction + aStart); log("Generated : " + randomNumber); } private static void log(String aMessage){ System.out.println(aMessage); } } 

Šios klasės vykdymo pavyzdys:

 Generating random integers in the range 1..10. Generated : 9 Generated : 3 Generated : 3 Generated : 9 Generated : 4 Generated : 1 Generated : 3 Generated : 9 Generated : 10 Generated : 10 Done. 
16
07 июня '12 в 13:38 2012-06-07 13:38 Atsakymą pateikė „ Hospes “ birželio 12 d. 12 val. 13:38 2012-06-07 13:38

Tai galite pasiekti „Java 8“:

 Random random = new Random(); int max = 10; int min = 5; int totalNumber = 10; IntStream stream = random.ints(totalNumber, min, max); stream.forEach(System.out::println); 
15
20 июня '17 в 15:39 2017-06-20 15:39 Atsakymą pateikė „ Mulalo Madida “ birželio 20 d. 17 val. 15:39 2017-06-20 15:39

Kai jums reikia daug atsitiktinių skaičių, API nerekomenduoju atsitiktinės klasės. Jis turi tik per mažą laikotarpį. Išbandykite Mersenne Twister . Yra „Java“ diegimas .

15
13 дек. Atsakymas pateikiamas raupach 13 d. 2008-12-13 13:18 '08 13:18 2008-12-13 13:18
 public static Random RANDOM = new Random(System.nanoTime()); public static final float random(final float pMin, final float pMax) { return pMin + RANDOM.nextFloat() * (pMax - pMin); } 
15
13 июля '11 в 14:31 2011-07-13 14:31 atsakymas pateikiamas AZ_ liepos 13 d., „11, 14:31, 2011-07-13 14:31

Tiesiog naudokite atsitiktinę klasę:

 Random ran = new Random(); // Assumes max and min are non-negative. int randomInt = min + ran.nextInt(max - min + 1); 
14
24 дек. Atsakymą pateikė prof. Mo. 2013-12-24 16:33 '13, 16:33, 2013-12-24 16:33

Kita galimybė - tiesiog naudoti „ Apache Commons“ :

 import org.apache.commons.math.random.RandomData; import org.apache.commons.math.random.RandomDataImpl; public void method() { RandomData randomData = new RandomDataImpl(); int number = randomData.nextInt(5, 10); // ... } 
14
18 янв. atsakymas duotas gerardw 18 jan. 2012-01-18 19:15 '12 19:15 val. 2012-01-18 19:15

Štai paprastas pavyzdys, rodantis, kaip generuoti atsitiktinį skaičių iš uždarojo diapazono [min, max] ir min <= max is true

Ją galite naudoti kaip lauką skylių klasėje, taip pat turėdami visus metodus Random.class vienoje vietoje

Mėginių rezultatai:

 RandomUtils random = new RandomUtils(); random.nextInt(0, 0); // returns 0 random.nextInt(10, 10); // returns 10 random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10) random.nextInt(10, -10); // throws assert 

Šaltiniai:

 import junit.framework.Assert; import java.util.Random; public class RandomUtils extends Random {  public int nextInt(int min, int max) { Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max); if (min == max) { return max; } return nextInt(max - min + 1) + min; } } 
14
28 нояб. Atsakymas pateikiamas Jakov Mospan 28 nov. 2014-11-28 03:50 '14 at 3:50 2014-11-28 03:50

Geriau naudoti „ SecureRandom“, o ne tik atsitiktinę.

 public static int generateRandomInteger(int min, int max) { SecureRandom rand = new SecureRandom(); rand.setSeed(new Date().getTime()); int randomNum = rand.nextInt((max - min) + 1) + min; return randomNum; } 
11
26 марта '15 в 16:02 2015-03-26 16:02 atsakymą grep pateikė kovo 26 d. 15 val. 16:02 2015-03-26 16:02

Jei norite išbandyti atsakymą, naudodami aukščiausią balsų skaičių, galite naudoti šį kodą:

 public class Randomizer { public static int generate(int min,int max) { return min + (int)(Math.random() * ((max - min) + 1)); } public static void main(String[] args) { System.out.println(Randomizer.generate(0,10)); } } 

Tai tiesiog grynas ir paprastas.

11
01 сент. Abel Callejo atsakymas, pateiktas rugsėjo 1 d 2013-09-01 05:53 '13, 5:53, 2013-09-01 05:53
 private static Random random = new Random(); public static int getRandomInt(int min, int max){ return random.nextInt(max - min + 1) + min; } 

Or

 public static int getRandomInt(Random random, int min, int max) { return random.nextInt(max - min + 1) + min; } 
11
11 февр. Atsakymas, kurį pateikė Muhammad Aamir Talib , vasario 11 d. 2015-02-11 14:40 '15 at 14:40 2015-02-11 14:40
 rand.nextInt((max+1) - min) + min; 

Tai puikiai veikia.

10
22 февр. Atsakymą davė ganesh vasario 22 d. 2010-02-22 14:44 „10, 14:44 val. 2010-02-22 14:44
  • 1
  • 2
  • 3

Kiti klausimai apie žymenis arba Užduoti klausimą