2009-04-10 11 views
104

Math.random() * n और Random.nextInt(n) के बीच क्या अंतर है n एक पूर्णांक है?Math.random() बनाम Random.nextInt (int)

+0

मैं गणित पता नहीं है, लेकिन मुझे पता है कि FindBugs शिकायत करता है, तो आप 'का उपयोग math.random()' – finnw

+3

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

उत्तर

138

यहाँ क्यों सूर्य मंचों से "Random.nextInt(n) दोनों अधिक कुशल और Math.random() * n से कम पक्षपाती है" की the detailed explanation है पोस्ट कि जिली जुड़ा हुआ है:

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

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

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

6 से स्केल करने से पहले, Math.random() का आउटपुट एक समान वितरण से खींचे गए 2^53 संभावित मानों में से एक है।

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

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

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

+3

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

+0

इस संदर्भ में, "कम पक्षपातपूर्ण" मतलब क्या है, कृपया? –

+0

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

14

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

+16

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

26

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

0

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

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

का उपयोग कर मैथर्स यादृच्छिक: समय: मिलीसेकंड।

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% से अधिक मामलों में सत्य है। इससे यह बयान होगा यदि कथन ज्यादातर बार सच साबित होता है, जो इसे अधिक अनुमानित बनाता है। इसलिए आपके परिणाम –

+0

के पक्ष में पक्षपातपूर्ण हैं, यह टाइपो गलती है ... दूसरे उदाहरण में 128 बनाएं आपको एक ही परिणाम मिल जाएगा। –

संबंधित मुद्दे