खोज…


टिप्पणियों

कुछ भी वास्तव में यादृच्छिक नहीं है और इस प्रकार javadoc उन संख्याओं को छद्म आयामी कहता है। उन संख्याओं को एक छद्म आयामी संख्या जनरेटर के साथ बनाया जाता है।

छद्म यादृच्छिक संख्याएँ

जावा प्रदान करता है, utils पैकेज के हिस्से के रूप में, एक बुनियादी छद्म-यादृच्छिक संख्या जनरेटर, जिसे उचित रूप से Random नाम दिया गया है। इस ऑब्जेक्ट का उपयोग छद्म-यादृच्छिक मान उत्पन्न करने के लिए किया जा सकता है क्योंकि अंतर्निहित संख्यात्मक डेटाटिप्स ( int , float , आदि) में से कोई भी। आप इसका उपयोग एक यादृच्छिक बूलियन मान, या बाइट्स का एक यादृच्छिक सरणी उत्पन्न करने के लिए कर सकते हैं। एक उदाहरण का उपयोग इस प्रकार है:

import java.util.Random;  

...
  
Random random = new Random();
int randInt = random.nextInt();
long randLong = random.nextLong();

double randDouble = random.nextDouble(); //This returns a value between 0.0 and 1.0
float randFloat = random.nextFloat(); //Same as nextDouble

byte[] randBytes = new byte[16];
random.nextBytes(randBytes); //nextBytes takes a user-supplied byte array, and fills it with random bytes. It returns nothing.

नोट: यह वर्ग केवल काफी कम गुणवत्ता वाले छद्म यादृच्छिक संख्याओं का उत्पादन करता है, और कभी भी क्रिप्टोग्राफिक संचालन या अन्य स्थितियों के लिए यादृच्छिक संख्या उत्पन्न करने के लिए उपयोग नहीं किया जाना चाहिए जहां उच्च गुणवत्ता वाली यादृच्छिकता महत्वपूर्ण है (इसके लिए, आप SecureRandom वर्ग का उपयोग करना चाहेंगे) जैसा कि नीचे उल्लेख किया गया है)। "सुरक्षित" और "असुरक्षित" यादृच्छिकता के बीच अंतर के लिए एक स्पष्टीकरण इस उदाहरण के दायरे से परे है।

विशिष्ट रेंज में छद्म यादृच्छिक संख्या

Random nextInt(int bound) विधि एक ऊपरी अनन्य सीमा को स्वीकार करता है, यानी एक संख्या जो लौटाया गया यादृच्छिक मान से कम होना चाहिए। हालाँकि, केवल nextInt पद्धति एक बाउंड को स्वीकार करती है; nextLong , nextDouble आदि नहीं।

Random random = new Random();
random.nextInt(1000); // 0 - 999

int number = 10 + random.nextInt(100); // number is in the range of 10 to 109

जावा 1.7 में शुरू होने पर, आप ThreadLocalRandom ( स्रोत ) का भी उपयोग कर सकते हैं। यह वर्ग एक थ्रेड-सुरक्षित PRNG (छद्म-यादृच्छिक संख्या जनरेटर) प्रदान करता है। ध्यान दें कि इस वर्ग की nextInt विधि ऊपरी और निचले दोनों को स्वीकार करती है।

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
ThreadLocalRandom.current().nextInt(min, max + 1);

ध्यान दें कि आधिकारिक दस्तावेज में कहा गया है कि nextInt(int bound) अजीब चीजें कर सकती है जब bound 2 30 +1 (जोर जोड़ा) के पास हो:

एल्गोरिथ्म थोड़ा मुश्किल है। यह उन मूल्यों को अस्वीकार करता है, जिनके परिणामस्वरूप असमान वितरण होता है (इस तथ्य के कारण कि 2 ^ 31 n द्वारा विभाज्य नहीं है)। किसी मूल्य को अस्वीकार किए जाने की संभावना n पर निर्भर करती है। सबसे खराब स्थिति n = 2 ^ 30 + 1 है, जिसके लिए अस्वीकार की संभावना 1/2 है, और लूप समाप्त होने से पहले पुनरावृत्तियों की अपेक्षित संख्या 2 है।

दूसरे शब्दों में, एक बाध्य वसीयत को निर्दिष्ट करना (थोड़ा) nextInt विधि के प्रदर्शन को कम करता है, और यह प्रदर्शन में कमी अधिक स्पष्ट हो जाएगी क्योंकि bound अधिकतम आधे nextInt मान के करीब पहुंचता है।

क्रिप्टोग्राफिक रूप से सुरक्षित छद्म आयामी संख्या उत्पन्न करना

Random और ThreadLocalRandom रोज़मर्रा के उपयोग के लिए पर्याप्त हैं, लेकिन उनके पास एक बड़ी समस्या है: वे एक रैखिक बधाई जनरेटर पर आधारित हैं, एक एल्गोरिथ्म जिसका आउटपुट आसानी से भविष्यवाणी की जा सकती है। इस प्रकार, ये दो वर्ग क्रिप्टोग्राफिक उपयोगों (जैसे प्रमुख पीढ़ी) के लिए उपयुक्त नहीं हैं।

एक java.security.SecureRandom का उपयोग उन स्थितियों में किया जा सकता है जहाँ PRNG एक ऐसे आउटपुट के साथ है जिसकी भविष्यवाणी करना बहुत कठिन है। इस वर्ग के उदाहरणों द्वारा बनाई गई यादृच्छिक संख्याओं का पूर्वानुमान करना वर्ग को क्रिप्टोग्राफिक रूप से सुरक्षित करने के लिए पर्याप्त रूप से लेबल करना है।

import java.security.SecureRandom;
import java.util.Arrays;

public class Foo {
    public static void main(String[] args) {
        SecureRandom rng = new SecureRandom();
        byte[] randomBytes = new byte[64];
        rng.nextBytes(randomBytes); // Fills randomBytes with random bytes (duh)
        System.out.println(Arrays.toString(randomBytes));
    }
}

क्रिप्टोग्राफी द्वारा सुरक्षित किया जा रहा है इसके अलावा, SecureRandom की तुलना में, 2 160 की एक विशाल अवधि है Random 2 48 की रों अवधि। यह तुलना में काफी धीमी होने का एक दोष यह है Random और इस तरह के रूप में अन्य रैखिक PRNGs Mersenne ट्विस्टर और Xorshift तथापि,।

ध्यान दें कि SecureRandom कार्यान्वयन मंच और प्रदाता दोनों पर निर्भर है। डिफ़ॉल्ट SecureRandom (द्वारा दिए गए SUN में प्रदाता sun.security.provider.SecureRandom ):

  • यूनिक्स जैसी प्रणालियों पर, /dev/random / और / /dev/urandom से डेटा के साथ वरीयता प्राप्त।
  • विंडोज पर, CryptoAPI में CryptGenRandom() लिए कॉल के साथ वरीयता प्राप्त।

डुप्लिकेट के बिना यादृच्छिक संख्या का चयन करें

/**
 * returns a array of random numbers with no duplicates
 * @param range the range of possible numbers for ex. if 100 then it can be anywhere from 1-100
 * @param length the length of the array of random numbers
 * @return array of random numbers with no duplicates.
 */
public static int[] getRandomNumbersWithNoDuplicates(int range, int length){
    if (length<range){
        // this is where all the random numbers
        int[] randomNumbers = new int[length];
        
        // loop through all the random numbers to set them
        for (int q = 0; q < randomNumbers.length; q++){
            
            // get the remaining possible numbers
            int remainingNumbers = range-q;
            
            // get a new random number from the remainingNumbers
            int newRandSpot = (int) (Math.random()*remainingNumbers);
            
            newRandSpot++;
            
            // loop through all the possible numbers
            for (int t = 1; t < range+1; t++){
                
                // check to see if this number has already been taken
                boolean taken = false;
                for (int number : randomNumbers){
                    if (t==number){
                        taken = true;
                        break;
                    }
                }
                
                // if it hasnt been taken then remove one from the spots
                if (!taken){
                    newRandSpot--;
                    
                    // if we have gone though all the spots then set the value
                    if (newRandSpot==0){
                        randomNumbers[q] = t;
                    }
                }
            }
        }
        return randomNumbers;
    } else {
        // invalid can't have a length larger then the range of possible numbers
    }
    return null;
}

विधि लूपिंग द्वारा काम करती है हालांकि एक सरणी जिसमें अनुरोधित लंबाई का आकार होता है और संभव संख्याओं की शेष लंबाई पाता है। यह उन संभावित नंबरों की एक नई संख्या सेट करता है newRandSpot और उस नंबर को बिना छोड़े हुए नंबर के भीतर पाता है। यह रेंज के माध्यम से लूपिंग करता है और यह देखने के लिए जांचता है कि क्या वह नंबर पहले ही लिया जा चुका है।


उदाहरण के लिए यदि रेंज 5 है और लंबाई 3 है और हमने पहले ही नंबर 2 चुन लिया है। तब हमारे पास 4 शेष संख्याएँ हैं, इसलिए हमें 1 और 4 के बीच एक यादृच्छिक संख्या मिलती है और हम किसी भी संख्या पर सीमा (5) को छोड़ देते हैं। हम पहले से ही (2) का उपयोग कर चुके हैं।

अब मान लेते हैं कि अगला नंबर 1 और 4 के बीच चुना गया है। 3. पहले लूप पर हमें 1 मिलता है, जिसे अभी तक नहीं लिया गया है, इसलिए हम 1 को 3 से निकाल सकते हैं। 2 अब दूसरे लूप पर हम 2 प्राप्त करते हैं जो लिया गया है इसलिए हम कुछ नहीं करते। हम इस पैटर्न का पालन करते हैं जब तक कि हम 4 तक नहीं पहुंच जाते हैं जहां एक बार हम 1 हटा देते हैं तो यह 0 हो जाता है इसलिए हम नए रैंडम नम्बर को 4 पर सेट करते हैं।

एक निर्दिष्ट बीज के साथ यादृच्छिक संख्या उत्पन्न करना

//Creates a Random instance with a seed of 12345.
Random random = new Random(12345L);

//Gets a ThreadLocalRandom instance
ThreadLocalRandom tlr = ThreadLocalRandom.current();

//Set the instance's seed.
tlr.setSeed(12345L);

यादृच्छिक संख्याओं को उत्पन्न करने के लिए एक ही बीज का उपयोग करना हर बार एक ही संख्याओं को लौटाएगा, इसलिए यदि आप डुप्लिकेट संख्याओं को समाप्त नहीं करना चाहते हैं तो हर Random उदाहरण के लिए एक अलग बीज सेट करना एक अच्छा विचार है।

Long पाने का एक अच्छा तरीका जो हर कॉल के लिए अलग है। System.currentTimeMillis() :

Random random = new Random(System.currentTimeMillis());
ThreadLocalRandom.current().setSeed(System.currentTimeMillis());

अपाचे-आम lang3 का उपयोग करके यादृच्छिक संख्या उत्पन्न करना

हम सिंगल लाइन का उपयोग करके यादृच्छिक संख्या उत्पन्न करने के लिए org.apache.commons.lang3.RandomUtils का उपयोग कर सकते हैं।

int x = RandomUtils.nextInt(1, 1000);

nextInt(int startInclusive, int endExclusive) विधि nextInt(int startInclusive, int endExclusive) एक सीमा लेती है।

Int के अलावा, हम इस वर्ग का उपयोग करके यादृच्छिक long , double , float और bytes उत्पन्न कर सकते हैं।

RandomUtils वर्ग में निम्नलिखित RandomUtils शामिल RandomUtils

static byte[] nextBytes(int count) //Creates an array of random bytes.
static double nextDouble() //Returns a random double within 0 - Double.MAX_VALUE
static double nextDouble(double startInclusive, double endInclusive) //Returns a random double within the specified range.
static float nextFloat() //Returns a random float within 0 - Float.MAX_VALUE
static float nextFloat(float startInclusive, float endInclusive) //Returns a random float within the specified range.
static int nextInt() //Returns a random int within 0 - Integer.MAX_VALUE
static int nextInt(int startInclusive, int endExclusive) //Returns a random integer within the specified range.
static long nextLong() //Returns a random long within 0 - Long.MAX_VALUE
static long nextLong(long startInclusive, long endExclusive) //Returns a random long within the specified range.


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow