सवाल जावा में एक विशिष्ट सीमा के भीतर मैं यादृच्छिक पूर्णांक कैसे उत्पन्न करूं?


मैं एक यादृच्छिक कैसे उत्पन्न करूं? 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`.

2903
2017-12-12 18:20


मूल




जवाब:


में जावा 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 उदाहरण, जो गलत तरीके से उपयोग किए जाने पर भ्रम और त्रुटि का स्रोत हो सकता है।

हालांकि, इसके विपरीत बीज को स्पष्ट रूप से सेट करने का कोई तरीका नहीं है, इसलिए उन परिस्थितियों में परिणाम पुन: उत्पन्न करना मुश्किल हो सकता है जहां यह उपयोगी है जैसे खेल राज्यों या इसी तरह की जांच या सहेजना। उन परिस्थितियों में, नीचे दिखाए गए पूर्व-जावा 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 ()

विशेष रूप से, कार्य को पूरा करने के लिए मानक लाइब्रेरी के भीतर सीधी एपीआई होने पर यादृच्छिक पूर्णांक पीढ़ी के पहिये को फिर से शुरू करने की कोई आवश्यकता नहीं है।


3260
2017-12-12 18:25



कहां कॉल के लिए max मूल्य है Integer.MAX_VALUE ओवरफ्लो करना संभव है, जिसके परिणामस्वरूप ए java.lang.IllegalArgumentException। आप इसके साथ प्रयास कर सकते हैं: randInt(0, Integer.MAX_VALUE)। इसके अलावा यदि nextInt((max-min) + 1) सबसे अधिक मूल्य लौटाता है (काफी दुर्लभ, मुझे लगता है) यह फिर से बहना नहीं होगा (न्यूनतम मानना ​​और अधिकतम पर्याप्त मूल्य हैं)? इस तरह की स्थितियों से निपटने के लिए कैसे? - Daniel
यह लंबे समय तक काम नहीं करता है - momo
@MoisheLipsker यह होना चाहिए कि अगली लंबी अगली इंटीजर के रूप में बाध्य नहीं है - momo
@leventov ThreadLocalRandom इस प्रश्न को पहले पूछे जाने के बाद जावा 2 1/2 साल में जोड़ा गया था। मैं हमेशा दृढ़ राय का रहा हूं कि यादृच्छिक उदाहरण का प्रबंधन प्रश्न के दायरे से बाहर है। - Greg Case
एंड्रॉइड रैंडम रैंड = नया रैंडम (); - Webserveis


ध्यान दें कि यह दृष्टिकोण अधिक पक्षपातपूर्ण और कम से कम कुशल है 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))

1324
2017-12-12 18:35



सूर्य प्रलेखन स्पष्ट रूप से कहता है कि आपको बेहतर यादृच्छिक () का उपयोग करना चाहिए यदि आपको Math.random () की बजाय int की आवश्यकता है जो एक डबल उत्पन्न करता है। - Lilian A. Moraru
यह वास्तव में अगली विधियों की तुलना में पक्षपातपूर्ण है stackoverflow.com/a/738651/360211 - weston


उपयोग:

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

पूर्णांक x अब यादृच्छिक संख्या है जिसके संभावित परिणाम हैं 5-10


311
2017-09-04 04:23





उपयोग:

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

122
2017-12-12 18:25





साथ में  उन्होंने विधि पेश की ints(int randomNumberOrigin, int randomNumberBound) में Random कक्षा।

उदाहरण के लिए यदि आप सीमा [0, 10] में पांच यादृच्छिक पूर्णांक (या एक एकल) उत्पन्न करना चाहते हैं, तो बस करें:

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 मान।

आशा करता हूँ की ये काम करेगा! :)


99
2017-11-26 18:29



मैं सुझाव दूंगा कि आप केवल एक बार यादृच्छिक इटरेटर को तुरंत चालू करें। अपने स्वयं के उत्तर पर ग्रेग केस टिप्पणी देखें। - Naxos84
यदि आप कर सकते हैं, तो क्या आप समझा सकते हैं कि इसका क्या महत्व है streamSize - इस विधि का पहला param streamSize !=0। यदि अंतर है तो क्या अंतर है streamSize 1/2 / एन दिया गया है? - Erfan Ahmed Emon
मीठे समाधान, विशेष रूप से धारा वर्ग। - cen


आप अपना दूसरा कोड उदाहरण इस प्रकार संपादित कर सकते हैं:

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

90
2017-12-12 18:31





आपके पहले समाधान का बस एक छोटा सा संशोधन पर्याप्त होगा।

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

कार्यान्वयन के लिए यहां और देखें Random


89
2018-03-12 22:44



न्यूनतम <= value <अधिकतम के लिए, मैंने मैथ के साथ ऐसा ही किया: randomNum = न्यूनतम + (int) (Math.random () * (अधिकतम-न्यूनतम)); लेकिन कास्टिंग देखना वास्तव में अच्छा नहीं है;) - AxelH


Multreadreaded वातावरण के लिए java.util.Random कक्षा के ThreadLocalRandom समकक्ष। एक यादृच्छिक संख्या उत्पन्न करना प्रत्येक धागे में स्थानीय रूप से किया जाता है। तो संघर्षों को कम करके हमारे पास बेहतर प्रदर्शन है।

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

एक्स, वाई - अंतराल उदा। (1,10)


54
2018-02-12 23:19



भगवान के लिए यह जवाब स्वीकार किया जाना चाहिए। यह भी देखें लिखने का कोई कारण है new Random() जावा 8 के बाद से? - leventov
@leventov यह स्वीकार्य उत्तर नहीं हो सकता है, यह कार्यान्वयन केवल समर्थन करता है => लॉलीपॉप - Relm
लोगों को थोड़ी देर के लिए लॉलीपॉप के लिए विकास करना चाहिए, ऐसा करने में विफलता, बस बाजार को डूबती है। वाहक को अद्यतन करने के लिए मजबूर करने के लिए अपने ऐप्स को नए एपीआई का समर्थन करें। - Martin Marconcini


Math.Random कक्षा में जावा 0-आधारित है। तो, अगर आप ऐसा कुछ लिखते हैं:

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

x बीच होगा 0-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)


53
2018-01-08 15:04



यादृच्छिक अंतराल लिंक मर चुका है। - Tapper7
@ Tapper7 ने संग्रहीत संस्करण को इंगित करने के लिए लिंक अपडेट किया। - Matt R
रास्ते के लिए +1 बैकमैचिन संग्रह स्क्रीनशॉट लिंक और आपका उत्तर अभी भी "यादृच्छिक" इंक w / श्रेणी में प्राप्त करने के लिए उपयोगी संदर्भ है। - Tapper7
यह मुझे परेशान करता है कि आप सूचकांक 0 को तत्काल क्यों करते हैं। - AjahnCharles
@CodeConfident द index परिवर्तनीय यादृच्छिक संख्या के परिणाम को प्रभावित नहीं करेगा। आप परिणामों को बदलने के बारे में चिंता किए बिना इसे किसी भी तरह से शुरू करना चुन सकते हैं। उम्मीद है की यह मदद करेगा। - Matt R