Math.random () बनाम random.nextInt (int)


135

पूर्णांक कहां Math.random() * nऔर किसके बीच का अंतर है?Random.nextInt(n)n


मुझे गणित का पता नहीं है, लेकिन मुझे पता है कि Math.random()
फाइंडबग्स

3
याद रखें कि रैंडम का कोई स्थिर तरीका नहीं है, इसलिए उपयोग करें: (नया रैंडम ())। nextInt (n))। गणित के लिए एक समान पूर्णांक उपयोग उत्पन्न करने के लिए: Math.floor ((Math.random () * n) +1);
दिमित्री डेवले

जवाबों:


169

यहाँ इस बात की विस्तृत व्याख्या है कि " सूर्य मंचों से Random.nextInt(n)अधिक Math.random() * n" दोनों की तुलना में अधिक कुशल और कम पक्षपाती क्यों है, जो गिल्ली से जुड़ा हुआ है:

Math.random () random.nextDouble () का आंतरिक रूप से उपयोग करता है।

Random.nextDouble () एक डबल उत्पन्न करने के लिए दो बार रैंडम.नेक्स्ट () का उपयोग करता है जिसमें लगभग समान रूप से बिट्स को अपने मंटिसा में वितरित किया जाता है, इसलिए इसे समान रूप से 0 से 1- (2 ^ -53) में वितरित किया जाता है।

Random.nextInt (n) रैंडम.नेक्स्ट () औसत से दो बार से कम-का उपयोग करता है- यह एक बार उपयोग करता है, और यदि प्राप्त मूल्य अधिकतम अधिकतम n n से अधिक है तो इसे फिर से कोशिश करता है, अन्यथा रिटर्न मान modulo n है (यह) MAX_INT वितरण को कम करने के उच्चतम मान के ऊपर मानों को रोकता है), इसलिए मान को लौटाया जाता है जो समान रूप से 0 से n-1 की सीमा में वितरित किया जाता है।

6 से स्केलिंग से पहले, Math.random () का उत्पादन एक समान वितरण से तैयार 2 ^ 53 संभावित मूल्यों में से एक है।

6 से स्केलिंग संभव मानों की संख्या में परिवर्तन नहीं करती है, और एक इंट में कास्टिंग तब इन मूल्यों को छह 'बाल्टियों' (0, 1, 2, 3, 4, 5) में से एक में बाध्य करती है, प्रत्येक बाल्टी में या तो सीमा शामिल होती है। 1501199875790165 या संभावित मानों में से 1501199875790166 (6 के रूप में 2 ^ 53 का परित्याग नहीं है)। इसका मतलब है कि पर्याप्त संख्या में पासा रोल (या पक्षों की पर्याप्त संख्या के साथ एक मरना) के लिए, डाई खुद को बड़ी बाल्टियों के प्रति पक्षपाती दिखाएगा।

आप इस प्रभाव को दिखाने के लिए बहुत लंबे समय तक लुढ़कते हुए पासे का इंतजार कर रहे होंगे।

Math.random () को भी लगभग दो बार प्रसंस्करण की आवश्यकता होती है और सिंक्रनाइज़ेशन के अधीन है।


3
Random.nextInt और nextDouble भी सिंक्रनाइज़ेशन के अधीन हैं।
एड्रिनोस

इस संदर्भ में, "कम पक्षपाती" का क्या अर्थ है, कृपया?
ツXocΦ epe Пepeúpa '

2
@ ツXocΦ epe Пepeúpa ę इसका सीधा सा अर्थ है कि कुछ संख्या दूसरों की तुलना में अधिक होने की संभावना है। जैसा कि इसमें कुछ संख्याओं को दूसरों पर डालने का पक्षपाती है (इसलिए पूरी तरह से यादृच्छिक नहीं है या बड़े नमूने का आकार एक समान है)
ford प्रीफेक्ट

1
ध्यान दें कि उस थ्रेड रिपोर्ट की अंतिम टिप्पणी: "जिस पूर्वाग्रह का वर्णन किया गया था, वह 2 ^ 53 में एक हिस्सा है, लेकिन उपयोग किए गए PRNG की अधिकतम चक्र लंबाई केवल 2 ^ 48 है। इसलिए आप जो देखेंगे, वह डेटा है। अंतर्निहित PRNG का वितरण, पूर्वाग्रह नहीं। " यह इस तथ्य की ओर इशारा करता है कि दो विधियाँ समतुल्य हैं
डिजिटल भ्रम

1
@ ツXocΦ epe Пepeúpa 6with 5एक पासा क्यूब पर बदलें : यह "5-पक्षपाती" होगा। आप पासा फेंक सकते हैं इससे पहले कि आप नोटिस करें कि पासा में कुछ गड़बड़ है। आपको यह देखने के लिए मजबूर किया जाता है कि एक यादृच्छिक जनरेटर के साथ कुछ गलत होने से पहले आप पूरी तरह से परीक्षा दे सकते हैं।
दविद होर्वाथ

27

एक और महत्वपूर्ण बिंदु यह है कि रैंडम.नेक्स्टइंट (एन) दोहराए जाने योग्य है क्योंकि आप एक ही बीज के साथ दो रैंडम ऑब्जेक्ट बना सकते हैं । यह Math.random () के साथ संभव नहीं है।


14

Https://forums.oracle.com/forums/thread.jspa?messageID=6594485龵 के अनुसार Random.nextInt(n)दोनों अधिक कुशल और कम पक्षपाती हैMath.random() * n


19
मैं वास्तव में उनके कुछ पोस्ट को उद्धृत करने और यहां थोड़ा संक्षेप में प्रस्तुत करने की सलाह दूंगा। लिंक आपके उत्तर का पूरक होना चाहिए।
jjnguy

0

इस उदाहरण के अनुसार Random.nextInt(n)कम पूर्वानुमानित आउटपुट है तो Math.random () * n। [एक क्रमबद्ध सरणी की तुलना में तेजी से क्रमबद्ध सरणी के अनुसार] [1] मुझे लगता है कि हम रैंडम कह सकते हैं ।nextInt (एन) की भविष्यवाणी करना मुश्किल है

रैंडमक्लैस का उपयोग: समय: 328 मील।

मेमैथसैंड्रैम का उपयोग: समय: 187 मील।

package javaFuction;
import java.util.Random;
public class RandomFuction 
{
    static int array[] = new int[9999];
    static long sum = 0;
    public static void usingMathsRandom() {
        for (int i = 0; i < 9999; i++) {
         array[i] = (int) (Math.random() * 256);
       }

        for (int i = 0; i < 9999; i++) {
            for (int j = 0; j < 9999; j++) {
                if (array[j] >= 128) {
                    sum += array[j];
                }
            }
        }
    }

    public static void usingRandomClass() {
        Random random = new Random();
        for (int i = 0; i < 9999; i++) {
            array[i] = random.nextInt(256);
        }

        for (int i = 0; i < 9999; i++) {
            for (int j = 0; j < 9999; j++) {
                if (array[j] >= 128) {
                    sum += array[j];
                }
            }

        }

    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        usingRandomClass();
        long end = System.currentTimeMillis();
        System.out.println("usingRandomClass " + (end - start));
        start = System.currentTimeMillis();
        usingMathsRandom();
        end = System.currentTimeMillis();
        System.out.println("usingMathsRandom " + (end - start));

    }

}

1
दूसरे लूप में आप> = 50 की जांच करते हैं, जो 50% से अधिक मामलों में सही है। इसका कारण यह होगा कि अगर बयान ज्यादातर समय सच होता है, जो इसे अधिक अनुमानित बनाता है। इसलिए आपके परिणाम आपके उत्तर के पक्षपाती हैं
न्यूरॉन

यह टाइपो गलती है ... दूसरे उदाहरण में 128 बनाओ आप एक ही परिणाम प्राप्त करेंगे।
जतिन गोयल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.