ජාවා හි නිශ්චිත පරාසයක් තුළ අහඹු සංඛ්‍යා පූර්ණ ජනනය කරන්නේ කෙසේද?


3511

intනිශ්චිත පරාසයක අහඹු අගයක් ජනනය කරන්නේ කෙසේද ?

මම පහත සඳහන් දෑ අත්හදා බැලුවෙමි, නමුත් ඒවා ක්‍රියාත්මක නොවේ:

උත්සාහය 1:

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

උත්සාහය 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`.

ඔබට අහඹු සංඛ්‍යා විශාල ප්‍රමාණයක් අවශ්‍ය වූ විට, මම API හි සසම්භාවී පන්තිය නිර්දේශ නොකරමි. එයට ඇත්තේ ඉතා කුඩා කාල පරිච්ඡේදයකි. ඒ වෙනුවට මර්සෙන් ට්විටර් උත්සාහ කරන්න . නැත ජාවා ක්රියාත්මක කිරීම .
raupach

1
ඔබ නව පිළිතුරක් පළ කිරීමට පෙර, මෙම ප්‍රශ්නයට දැනටමත් පිළිතුරු 65+ ක් ඇති බව සලකන්න. කරුණාකර, ඔබගේ පිළිතුර දැනට පවතින පිළිතුරු අතර නොමැති තොරතුරු සඳහා දායක වන බවට වග බලා ගන්න.
janniks

Answers:


3807

දී ජාවා 1.7 හෝ ඊට පසු , පහත සඳහන් පරිදි මෙය කිරීමට සම්මත ක්රමය වන්නේ:

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);

අදාළ ජාවාඩොක් බලන්න . මෙම ප්‍රවේශයට java.util.Random නිදසුනක් පැහැදිලිවම ආරම්භ කිරීමට අවශ්‍ය නොවීමේ වාසිය ඇත , එය නුසුදුසු ලෙස භාවිතා කරන්නේ නම් ව්‍යාකූලත්වයට හා දෝෂයකට හේතු විය හැක.

කෙසේ වෙතත්, අනෙක් අතට බීජ පැහැදිලිව සැකසීමට ක්‍රමයක් නොමැති බැවින් ක්‍රීඩා තත්වයන් පරීක්ෂා කිරීම හෝ සුරැකීම හෝ ඒ හා සමාන ප්‍රයෝජනවත් අවස්ථාවන්හි ප්‍රති results ල ප්‍රතිනිෂ්පාදනය කිරීම දුෂ්කර විය හැකිය. එවැනි අවස්ථාවන්හිදී, පහත පෙන්වා ඇති පූර්ව ජාවා 1.7 තාක්ෂණය භාවිතා කළ හැකිය.

ජාවා 1.7 ට පෙර , මෙය කිරීමට සම්මත ක්‍රමය පහත පරිදි වේ:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
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;
}

අදාළ ජාවාඩොක් බලන්න . ප්රායෝගිකව, java.util.Random පන්තිය බොහෝ විට java.lang.Math.random () ට වඩා යෝග්ය වේ .

කාර්යය ඉටු කිරීම සඳහා සම්මත පුස්තකාලය තුළ API ජු API එකක් ඇති විට, අහඹු පූර්ණ සංඛ්‍යා උත්පාදක රෝදය ප්‍රතිනිර්මාණය කිරීමේ අවශ්‍යතාවයක් නොමැත.


43
maxඅගය ඇති ඇමතුම් Integer.MAX_VALUEසඳහා පිටාර ගැලීම කළ හැකි අතර එහි ප්‍රති a ලය a java.lang.IllegalArgumentException. ඔබට මෙය සමඟ උත්සාහ කළ හැකිය : randInt(0, Integer.MAX_VALUE). එසේම, nextInt((max-min) + 1)වඩාත්ම ඉහළ අගය ආපසු ලබා දෙන්නේ නම් (තරමක් දුර්ලභ යැයි මම සිතමි) එය නැවත පිටාර ගැලෙන්නේ නැත (මිනි සහ උපරිම ඉහළ අගයන් ඇතැයි සිතමු)? මෙවැනි තත්වයන්ට මුහුණ දෙන්නේ කෙසේද?
ඩැනියෙල්

3
@MoisheLipsker එය nextLong nextInteger ලෙස බැඳී කරන්නේ නැති බව විය යුතුය
MMM

13
ThreadLocalRandomමෙම ප්‍රශ්නය මුලින්ම ඇසීමෙන් වසර 2 1/2 කට පසුව @leventov ජාවා වෙත එක් කරන ලදී. සසම්භාවී සිද්ධිය කළමනාකරණය කිරීම ප්‍රශ්නයේ විෂය පථයෙන් පිටත බව මම සැමවිටම ස්ථිර මතයක සිටිමි.
ග්‍රෙග් කේස්

6
ඇන්ඩ්‍රොයිඩ් සසම්භාවී සසම්භාවී = නව සසම්භාවී ();
වෙබ්සර්විස්

5
E වෙබ්සර්විස් මෙය උදාහරණයේ අදහස් දැක්වීමේදී ආමන්ත්‍රණය කර ඇත. කෙටි අනුවාදය - ශ්‍රිතයට ලැබෙන සෑම ඇමතුමකටම ඔබ = නව අහඹු () නොවිය යුතුය, නැතහොත් ඔබේ ප්‍රති results ල බොහෝ අවස්ථාවන් සඳහා ප්‍රමාණවත් තරම් අහඹු නොවනු ඇත.
ග්‍රෙග් කේස්

1423

මෙම ප්‍රවේශය ප්‍රවේශයකට වඩා පක්ෂග්‍රාහී හා කාර්යක්ෂම නොවන බව සලකන්න nextInt, https://stackoverflow.com/a/738651/360211

මෙය ඉටු කිරීම සඳහා එක් සම්මත රටාවක් නම්:

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

මෙම ජාවා ගණිත පුස්තකාල කාර්යය Math.random () යන පරාසය තුළ ද්විත්ව අගය ජනනය [0,1). මෙම පරාසය 1 ඇතුළත් නොවන බව සලකන්න.

පළමුවෙන් නිශ්චිත පරාසයක අගයන් ලබා ගැනීම සඳහා, ඔබට ආවරණය කිරීමට අවශ්‍ය අගයන් පරාසයේ විශාලත්වය අනුව ගුණ කළ යුතුය.

Math.random() * ( Max - Min )

[0,Max-Min)'මැක්ස්-මින්' ඇතුළත් නොවන පරාසය තුළ මෙය අගයක් ලබා දෙයි .

උදාහරණයක් ලෙස, ඔබට අවශ්‍ය [5,10)නම්, ඔබ භාවිතා කරන පූර්ණ සංඛ්‍යා අගයන් පහක් ආවරණය කළ යුතුය

Math.random() * 5

මෙය [0,5)5 ක් ඇතුළත් නොවන පරාසය තුළ අගයක් ලබා දෙනු ඇත .

දැන් ඔබ මෙම පරාසය ඔබ ඉලක්ක කරන පරාසය දක්වා මාරු කළ යුතුය. ඔබ මෙය කරන්නේ අවම අගය එකතු කිරීමෙනි.

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

ඔබට දැන් පරාසය තුළ වටිනාකමක් ලැබෙනු ඇත [Min,Max). අපගේ ආදර්ශය අනුගමනය කිරීමෙන්, එයින් අදහස් වන්නේ [5,10):

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

නමුත්, මෙය තවමත් ඇතුළත් නොවන අතර Maxඔබට ද්විත්ව අගයක් ලැබේ. Maxඅගය ඇතුළත් කර ගැනීම සඳහා , ඔබ ඔබේ පරාසයේ පරාමිතියට 1 ක් එකතු කළ යුතු (Max - Min)අතර ඉන් පසුව int ට වාත්තු කිරීමෙන් දශම කොටස කපා දැමිය යුතුය . මෙය සිදු කරන්නේ:

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

එහි ඔබට එය තිබේ. පරාසය තුළ අහඹු පූර්ණ සංඛ්‍යාවක් [Min,Max], හෝ උදාහරණයක් ලෙස [5,10]:

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

82
සන් ප්‍රලේඛනය පැහැදිලිවම පවසන්නේ දෙගුණයක් නිපදවන Math.random () වෙනුවට ඔබට int අවශ්‍ය නම් සසම්භාවී () භාවිතා කළ යුතු බවයි.
ලිලියන් ඒ. මොරාරු

6
මෙය ඇත්ත වශයෙන්ම මීළඟ ක්‍රම සමඟ සසඳන විට stackoverflow.com/a/738651/360211
වෙස්ටන්

4
මෙම නඩුවේ “පක්ෂග්‍රාහී” යන්නෙන් අදහස් වන්නේ මරණ ද 2 ුවම 53 ^ 53 කට පසුව, සමහර සංඛ්‍යා වලට සාමාන්‍යයෙන් එක් අමතර සිදුවීමක් සිදුවනු ඇති බවයි.
සීෆලෝපොඩ්

379

භාවිත:

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

නිඛිලය xදැන් අහඹු අංකයක් විය හැකි ප්‍රති out ල 5-10ඇත.


160

භාවිත:

minimum + rn.nextInt(maxValue - minvalue + 1)

137

සමඟ ඔවුන් ක්රමය හඳුන්වා ints(int randomNumberOrigin, int randomNumberBound)දී Randomපන්ති.

උදාහරණයක් ලෙස ඔබට [0, 10] පරාසය තුළ අහඹු සංඛ්‍යා 5 ක් (හෝ තනි එකක්) උත්පාදනය කිරීමට අවශ්‍ය නම්, එසේ කරන්න:

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

පළමු පරාමිතිය මඟින් IntStreamජනනය කරන ලද ප්‍රමාණය පමණක් දක්වයි (එය අසීමිත ලෙස නිපදවන එකෙහි අධික ලෙස පටවන ලද ක්‍රමයයි IntStream).

ඔබට වෙනම ඇමතුම් කිහිපයක් කිරීමට අවශ්‍ය නම්, ඔබට ප්‍රවාහයෙන් අසීමිත ප්‍රාථමික අනුකාරකයක් සෑදිය හැකිය:

public final class IntRandomNumberGenerator {

    private PrimitiveIterator.OfInt randomIterator;

    /**
     * Initialize a new random number generator that generates
     * random numbers in the range [min, max]
     * @param min - the min value (inclusive)
     * @param max - the max value (inclusive)
     */
    public IntRandomNumberGenerator(int min, int max) {
        randomIterator = new Random().ints(min, max + 1).iterator();
    }

    /**
     * Returns a random number in the range (min, max)
     * @return a random number in the range (min, max)
     */
    public int nextInt() {
        return randomIterator.nextInt();
    }
}

ඔබට එය doubleසහ longඅගයන් සඳහාද කළ හැකිය . එය උපකාරී වේ යැයි මම බලාපොරොත්තු වෙමි! :)


1
මම ඔබට යෝජනා කරන්නේ ඔබ සසම්භාවී ඉන්ටරේටරය ක්ෂණිකව ක්‍රියාත්මක කරන ලෙසයි. ඔහුගේම පිළිතුර ගැන ග්‍රෙග් කේස්ගේ අදහස බලන්න.
නැක්සෝ 84

ඔබට හැකි නම්, මෙහි ඇති වැදගත්කම කුමක්දැයි ඔබට පැහැදිලි කළ හැකිද streamSize- මෙම ක්‍රමයේ පළමු පරාමිතිය streamSize !=0. streamSize1/2 / n ලබා දෙන්නේ නම් වෙනස කුමක්ද?
අර්ෆාන් අහමඩ්

104

ඔබගේ දෙවන කේත උදාහරණය ඔබට සංස්කරණය කළ හැකිය:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;

100

ඔබගේ පළමු විසඳුමේ සුළු වෙනස් කිරීමක් පමණක් ප්‍රමාණවත් වේ.

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

ක්‍රියාත්මක කිරීම සඳහා වැඩි විස්තර මෙතැනින් බලන්න Random


අවම <= අගය <උපරිම සඳහා, මම ගණිතයත් එසේම කළෙමි : randomNum = අවම + (int) (Math.random () * (උපරිම-අවම)); නමුත් වාත්තු කිරීම ඇත්තෙන්ම සුන්දර නොවේ;)
ඇක්සෙල් එච්

අවම වශයෙන් අවුරුදු 7 ක් ප්‍රමාද වූ අනුපිටපතක්.
මාර්ටන් බොඩෙව්ස්

71

ThreadLocalRandomjava.util.Randomබහු තෙරපුම් පරිසරය සඳහා පන්තියට සමාන වේ . අහඹු අංකයක් ජනනය කිරීම එක් එක් නූල් තුළ දේශීයව සිදු කෙරේ. එබැවින් ගැටුම් අවම කිරීමෙන් අපට වඩා හොඳ කාර්ය සාධනයක් ඇත.

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

x, y- අන්තරයන් උදා (1,10)


66

ජාවා හි Math.Randomපන්තිය 0 පදනම් වේ. එබැවින්, ඔබ මේ වගේ දෙයක් ලියන්නේ නම්:

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

x0-9ඇතුළත් කිරීම අතර වේ.

එබැවින්, පහත දැක්වෙන 25අයිතම පෙළට අනුව , 0(අරාවේ පදනම) අතර අහඹු සංඛ්‍යාවක් ජනනය කිරීමේ කේතය සහ array.length:

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

index = rand.nextInt( i.length );

i.lengthනැවත පැමිණෙන බැවින් 25, nextInt( i.length )පරාසය අතර සංඛ්‍යාවක් නැවත ලබා දෙනු ඇත 0-24. අනෙක් විකල්පය වන්නේ Math.Randomඑකම ආකාරයකින් ක්‍රියාත්මක වන දේ සමඟ ය.

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

වඩා හොඳ අවබෝධයක් සඳහා, සසම්භාවී අන්තරයන් (archive.org) සංසදය බලන්න .


WayBackMachine සංරක්ෂිත තිරපිටපත් සබැඳිය සඳහා +1 සහ පරාසයක “අහඹු” අඟල් ලබා ගැනීමට ඔබේ පිළිතුර තවමත් ප්‍රයෝජනවත් යොමු කිරීමකි.
ටැපර් 7

ඔබ දර්ශකය 0 ට
ක්ෂණිකව තැබීමට

OdeCodeConfident අහඹු අංකයේ ප්‍රති result ලයට indexවිචල්‍යය බලපාන්නේ නැත. ප්‍රති come ලය වෙනස් කිරීම ගැන කරදර නොවී ඔබ කැමති ඕනෑම ආකාරයකින් එය ආරම්භ කිරීමට ඔබට තෝරා ගත හැකිය. මෙය උපකාරී වේ යැයි සිතමි.
මැට් ආර්

හරියටම ... එය සම්පූර්ණයෙන්ම භාවිතා නොකෙරේ. මම එය කෙලින්ම int index = rand.nextInt(i.Length);
අහඹු ලෙස ආරම්භ කරමි

නැත්නම් කොහෙත්ම නැහැ. int index; \n index = rand...යමෙක් විවිධ රේඛාවල ප්‍රකාශන හා පැවරුම් වලට කැමති නම්. සමහර කේතීකරණ ප්‍රමිතීන් අනෙක් ඒවාට වඩා දැඩි (සහ පැහැදිලි අරමුණකින් තොරව) වේ.
මාර්ක් ස්ටෝර්

49

නිරාහාරව සිටීම ගැන මට සමාව දෙන්න, නමුත් බහුතරය විසින් යෝජනා කරන ලද විසඳුම, එනම්, min + rng.nextInt(max - min + 1))අනතුරුදායක බව පෙනෙන්නේ:

  • rng.nextInt(n)ළඟා විය නොහැක Integer.MAX_VALUE.
  • (max - min).ණාත්මක වන විට පිටාර ගැලීමට හේතු විය හැක min.

මෝඩ විසඳුමක් මගින් ඕනෑම කෙනෙකුට නිවැරදි ප්‍රති results ල ලබා දෙනු min <= maxඇත [ Integer.MIN_VALUE, Integer.MAX_VALUE]. පහත දැක්වෙන බොළඳ ක්‍රියාවට නැංවීම සලකා බලන්න:

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;
}

අකාර්යක්ෂම වුවද, whileලූපයේ සාර්ථකත්වයේ සම්භාවිතාව සෑම විටම 50% හෝ ඊට වැඩි වනු ඇති බව සලකන්න .


වෙනස = Integer.MAX_VALUE වන විට නීතිවිරෝධී විග්‍රහයක් විසි නොකරන්නේ ඇයි? එවිට ඔබට කාල ලූපය අවශ්‍ය නොවේ.
පාර්ලිමේන්තු මන්ත්‍රී කෝර්ස්ටාන්ජ්

3
ක්‍රියාත්මක කිරීම සැලසුම් කර ඇත්තේ ඒවායේ වෙනස MAX_VALUE ට සමාන හෝ විශාල වුව ද min <= max හි ඕනෑම අගයන් සමඟ වැඩ කිරීමටය. සාර්ථකත්වය තෙක් ලූපයක් ධාවනය කිරීම මෙම අවස්ථාවේ දී පොදු රටාවක් වන අතර, ඒකාකාර ව්‍යාප්තිය සහතික කිරීම සඳහා (අහඹු ලෙස යටින් පවතින ප්‍රභවය ඒකාකාරී නම්). Random.nextInt (int) තර්කය 2 හි බලයක් නොමැති විට එය අභ්‍යන්තරව කරයි.
ක්‍රිස්ටියන් සෙම්රාවු

44

හුදෙක් ප්‍රකාශය කිරීමෙන් එය කළ හැකිය:

Randomizer.generate(0,10); //min of zero, max of ten

පහත දැක්වෙන්නේ එහි ප්‍රභව කේතයයි

Randomizer.java

public class Randomizer {
    public static int generate(int min,int max) {
        return min + (int)(Math.random() * ((max - min) + 1));
    }
}

එය පිරිසිදු හා සරල ය.


5
මෙය අනෙක් උදාහරණයේ සංස්කරණයක් විය හැකිය, දැන් එය කීර්තිය සඳහා වූ අමූලික පිටපතකි. “වැඩි ඡන්ද ප්‍රමාණයක් සහිත පිළිතුර” පෙන්වා දීම ද සෘජු නොවේ, එය වෙනස් විය හැකිය.
මාර්ටන් බොඩෙව්ස්

1
එය නිවැරදියි a මාර්ටන් බොඩ්වේස්. මම මෙම පිළිතුර ලියන විට, ඉහත වැඩිම ඡන්ද සංඛ්‍යාවක් සහිත පිළිතුර තවමත් ඇල්ගොරිතම වැනි විසඳුමක් ලෙස ලියා ඇත. දැන්, ඉහත විසඳුම බොහෝ වෙනස් වී ඇති අතර දැන් මෙම පිළිතුර පිටපත්-බළලෙකු සේ පෙනුනි.
අබෙල් කලෙජෝ

එවැනි මූලික කේතයන් ජාවා සම්මත පුස්තකාලවල කොටසක් නොවන්නේ මන්දැයි මට නොතේරේ. මා මෙය ක්‍රියාත්මක කළ යුත්තේ ඇයි?
ලීවි එල්


31

අපි උදාහරණයක් ගනිමු.

5-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);

අපි මෙය තේරුම් ගනිමු ...

ඉහළම අගය සහිත උපරිම සහ අවම අගය සමඟ මිනි ආරම්භ කරන්න.

දැන්, අප විසින් කොපමණ අගයන් ලබා ගත හැකිද යන්න තීරණය කළ යුතුය. මෙම උදාහරණය සඳහා, එය වනුයේ:

5, 6, 7, 8, 9, 10

එබැවින්, මෙහි ගණන උපරිම වේ - මිනි + 1.

එනම් 10 - 5 + 1 = 6

අහඹු අංකය 0-5 අතර සංඛ්‍යාවක් ජනනය කරයි .

එනම් 0, 1, 2, 3, 4, 5

සසම්භාවී අංකයට අවම අගය එකතු කිරීමෙන් නිෂ්පාදනය වනු ඇත:

5, 6, 7, 8, 9, 10

එබැවින් අපි අපේක්ෂිත පරාසය ලබා ගනිමු.



26

මීලඟ (n) ක්‍රමය භාවිතා කරමින් මිනි සහ උපරිම වෙනස සඳහා අහඹු අංකයක් ජනනය කර ප්‍රති result ලයට මිනි අංකය එක් කරන්න:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);

26

මම මෙය භාවිතා කරමි:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max + 1 - min)) + min;
 }

ඔබට අවශ්‍ය නම් එය පූර්ණ සංඛ්‍යාවක් වෙත දැමිය හැකිය.


මෙම ශ්‍රිතය එකම සංඛ්‍යාවක් නැවත නැවතත් නිපදවයි. මගේ නඩුවේ එය වූයේ: 2147483647
සොක්‍රස්

අසමත් වීම: ඔබට දෙගුණයක් අවශ්‍ය ශ්‍රිතයක් ඇති අතර පසුව + 1 සිදු කරන්න? මෙය නිසැකවම අවම පුදුමයේ මූලධර්මයට පටහැනිය. ඔබ min = 0.1 සහ max = 0.2 භාවිතා කරන්නේ නම් කුමක් සිදුවේද?
මාර්ටන් බොඩෙව්ස්

ok සොක්‍රස් ක්‍රමය අමතයි new Random(ජාවාඩොක් පරික්ෂා කරන්න): "නව අහඹු සංඛ්‍යා උත්පාදක යන්ත්‍රයක් සාදයි. මෙම ඉදිකිරීම්කරු සසම්භාවී සංඛ්‍යා උත්පාදක යන්ත්‍රයේ බීජ මෙම ඉදිකිරීම්කරුගේ වෙනත් ආයාචනයකට වඩා වෙනස් විය හැකි අගයකට සකසයි." වර්තමාන කාලය බීජ ලෙස භාවිතා කිරීම බොහෝ දුරට සම්බන්ධ විය හැකිය. එම කාලය මිලි තත්පර භාවිතා කරන්නේ නම් වර්තමාන පරිගණක එකම සංඛ්‍යාවක් ජනනය කිරීමට තරම් වේගවත් වේ. නමුත් ඊට අමතරව 2147483647 Integer.MAX_VALUE; ප්‍රතිදානය පැහැදිලිවම ඔබ විසින් නියම කර නොමැති ආදානය මත රඳා පවතී.
මාර්ටන් බොඩෙව්ස්

අවසාන වශයෙන් සැබවින්ම ක්‍රියාත්මක වන එක සොයා ගත්තේය
ජෙන්සි

23

ජාවා 7 වන විට, ඔබ තවදුරටත් භාවිතා නොකළ යුතුය Random. බොහෝ භාවිතයන් සඳහා, අහඹු සංඛ්‍යා උත්පාදක යන්ත්‍රය දැන් තෝරාගෙන ඇත ThreadLocalRandom.

දෙබලක සම්බන්ධ වන තටාක සහ සමාන්තර ධාරාවන් සඳහා, භාවිතා කරන්න SplittableRandom.

ජෝෂුවා බ්ලොච්. Java ලදායී ජාවා. තෙවන සංස්කරණය.

ජාවා 8 සිට ආරම්භ වේ

දෙබලක සම්බන්ධක තටාක සහ සමාන්තර ධාරාවන් සඳහා, SplittableRandomසාමාන්‍යයෙන් වේගවත් වන භාවිතය හා සැසඳීමේදී වඩා හොඳ සංඛ්‍යානමය ස්වාධීනත්වයක් සහ ඒකාකාරී ගුණාංග ඇතRandom .

intපරාසය තුළ අහඹු ලෙස ජනනය කිරීමට[0, 1_000]:

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

int[100]පරාසය තුළ අහඹු අගයන් උත්පාදනය කිරීම[0, 1_000]:

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

අහඹු අගයන් ප්‍රවාහයක් ආපසු ලබා දීමට:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);

උදාහරණයට a ඇතුළත් වීමට හේතුවක් .parallel()තිබේද? අහඹු සංඛ්‍යා 100 ක් උත්පාදනය කිරීම සමාන්තරකරණයට වරෙන්තු කිරීමට තරම් සුළු දෙයක් නොවන බව මට පෙනේ.
ජෝන්බොට්

@ ජෝන්බොට් අදහස් දැක්වීමට ස්තූතියි, ඔබ හරි. එහෙත්, ප්‍රධාන හේතුව වූයේ API එකක් පෙන්වීමයි (ඇත්ත වශයෙන්ම, ස්මාර්ට් මාර්ගය වන්නේ parallelසැකසුම් භාවිතා කිරීමට පෙර කාර්ය සාධනය මැනීමයි ). මාර්ගය වන විට, 1_000_000මූලද්‍රව්‍ය පෙළක් සඳහා , parallelඅනුක්‍රමිකයට සාපේක්ෂව අනුවාදය මගේ යන්ත්‍රයේ 2 ගුණයකින් වේගවත් විය.
ඔලෙක්සැන්ඩර් පයිරොහෝව්


20

මෙම ක්‍රම භාවිතා කිරීමට පහසු විය හැකිය:

මෙම ක්‍රමය අහඹු අංකයක් ලබා දෙනු ඇත සපයා ඇති මිනි සහ උපරිම අගය අතරලබා දෙනු ඇත:

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;
    }
}

මෙම ක්‍රමය මඟින් සපයා ඇති මිනි සහ උපරිම අගයෙන් අහඹු අංකයක් ලබා දෙනු ඇත (එබැවින් ජනනය කරන ලද අංකය අවම හෝ උපරිම අංකය විය හැකිය):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}

// Since the random number is between the min and max values, simply add 1. මන්ද? මිනිත්තු ගණන් කරන්නේ නැද්ද? සාමාන්‍යයෙන් පරාසය [min, max) වන අතර එහිදී min ඇතුළත් වන අතර උපරිමය බැහැර කරනු ලැබේ. වැරදි පිළිතුර, ඡන්දය ප්‍රකාශ කිරීම.
මාර්ටන් බොඩෙව්ස්

GetRandomNumberBetween විසින් සපයා ඇති අන්ත ලක්ෂ්‍යයන්ගෙන් බැහැර අහඹු අංකයක් ජනනය කරන නිසා a මාටර්බොඩෙව්ස් +1 එකතු කරනු ලැබේ.
ලූක් ටේලර්

1
ප්‍රති number min + 1ලය වීමට එම සංඛ්‍යාව අනෙක් සංඛ්‍යාවට වඩා දෙගුණයක් වනු ඇත getRandomNumberBetween!
Li

19

ඩයිස් රෝල් කරන විට එය අහඹු අංක 1 සිට 6 දක්වා (0 සිට 6 දක්වා නොවේ), එබැවින්:

face = 1 + randomNumbers.nextInt(6);

19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

නැතහොත් Apache Commons වෙතින් RandomUtils වෙත බලන්න .


එය ප්‍රයෝජනවත්, නමුත් කුඩා අඩුපාඩුවක් ගැන පරෙස්සම් වන්න: ක්‍රම අත්සන් වැනි ය: ඊලඟ ඩබල් (ද්විත්ව ආරම්භක, ද්විත්ව අන්තය)
zakmck

Double.valueOf(Math.random()*(maximum-minimun)).intValue()කීමට තරමක් අපැහැදිලි (හා අකාර්යක්ෂම) ක්‍රමයකි (int)(Math.random()*(maximum-minimun))
හොල්ගර්

අවම ප්‍රතිලාභ අවම සඳහා අක්ෂර වින්‍යාසය නොගැලපීම + ද්විත්ව. අගය (Math.random () * (උපරිම - අවම)) intValue ();
රිෂිකේෂ් මිශ්‍ර

18

intsඕනෑම ඇතුළත් / සුවිශේෂී සීමාවන් සමඟ අහඹු ලෙස පරාසයක් උත්පාදනය කිරීමට ප්‍රයෝජනවත් පන්තියක් මෙන්න :

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;
    }
}

18

අහඹු අංකයක් "සංඛ්‍යා දෙකක් අතර" ජනනය කිරීමට, පහත කේතය භාවිතා කරන්න:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

මෙය ඔබට 1 (ඇතුළත්) සහ 11 (සුවිශේෂී) අතර අහඹු අංකයක් ලබා දෙයි, එබැවින් 1 එකතු කිරීමෙන් ඉහළ මායිම් අගය ආරම්භ කරන්න. 10.


18

ඔබට එය ජාවා 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);

17
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);
}

16

තවත් විකල්පයක් වන්නේ 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);
    // ...
 }

16

මට මෙම උදාහරණය හමු විය අහඹු සංඛ්‍යා ජනනය කරන්න :


මෙම උදාහරණය අහඹු සංඛ්‍යා පූර්ණ පරාසයක ජනනය කරයි.

import java.util.Random;

/** Generate random integers in a certain range. */
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);
  }
} 

මෙම පන්තියේ උදාහරණ ධාවනය:

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.

14

සසම්භාවී ලෙසට වඩා SecureRandom භාවිතා කිරීම වඩා හොඳය .

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;
}

1
මෙය එතරම් හොඳ නැත, මන්ද එය එකම මිලි තත්පරයකින් ක්‍රියාත්මක කළහොත් ඔබට එකම සංඛ්‍යාවක් ලැබෙනු ඇත, ඔබ ක්‍රමයට පිටතින් සසම්භාවී ආරම්භය සහ සෙට්සෙට් තැබිය යුතුය.
මාරකා

ඔබට බීජ අවශ්‍යයි, ඔව්, නමුත් SecureRandom භාවිතා කිරීම.
grep

මට කණගාටුයි, නමුත් වෙනස් කිරීමේ ඉල්ලීම ප්‍රතික්ෂේප කළ තැනැත්තාට ජාවා ක්‍රමලේඛනය පිළිබඳ කිසිදු හෝඩුවාවක් නොමැත එය හොඳ යෝජනාවකි, නමුත් එය වැරදියි, මන්ද එකම මිලි තත්පරයකින් ක්‍රියාත්මක කළ හොත් එය එකම සංඛ්‍යාවක් ලබා දෙයි, අහඹු ලෙස නොවේ.
මරකා

නිවැරදි විසඳුම සොයාගත හැකි කොතැනකවත් නැත, බොහෝ අය ස්ථිතික ආරම්භක කුට්ටි දන්නේ නැත ... බීජ සැකසීමට ඔබ භාවිතා කළ යුත්තේ එයයි: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
මාරකා

5
නියත වශයෙන්ම බීජ අවශ්‍ය නැත SecureRandom, එය පද්ධතිය විසින් බීජ කරනු ලැබේ. කෙලින්ම ඇමතීම setSeedඉතා භයානක ය, එය (සැබවින්ම අහඹු) බීජ දිනය සමඟ ප්‍රතිස්ථාපනය කළ හැකිය. ඕනෑම කෙනෙකුට කාලය අනුමාන කළ හැකි අතර, එම තොරතුරු සමඟ ඔවුන්ගේම අවස්ථාව උත්සාහ කර බැලීමට එය නිසැකවම හේතු නොවේ . SecureRandomSecureRandom
මාර්ටන් බොඩෙව්ස්

13

සංවෘත සිට අහඹු අංකයක් ජනනය කරන්නේ කෙසේදැයි පෙන්වන සරල නියැදියක් මෙන්න [min, max] පරාසයකින්min <= max is true

ඔබට එය සිදුරු පන්තියේ ක්ෂේත්‍රයක් ලෙස නැවත භාවිතා කළ හැකිය Random.class එක් තැනක ක්රම

ප්‍රති Results ල උදාහරණය:

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

මුලාශ්‍ර:

import junit.framework.Assert;
import java.util.Random;

public class RandomUtils extends Random {

    /**
     * @param min generated value. Can't be > then max
     * @param max generated value
     * @return values in closed range [min, max].
     */
    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;
    }
}

13
rand.nextInt((max+1) - min) + min;

මෙය හොඳින් ක්‍රියාත්මක වේ.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.