2011-04-03 20 views
16

मुझे एक यादृच्छिक संख्या जनरेटर के साथ मदद की ज़रूरत है जो मैं बना रहा हूं।जब मैं बीज सेट करता हूं तो जावा यादृच्छिक हमेशा एक ही संख्या देता है?

public int random(int i){ 
    Random randnum = new Random(); 
    randnum.setSeed(123456789); 
    return randnum.nextInt(i); 
} 

जब मैं किसी अन्य वर्ग से इस विधि कॉल (आदेश एक यादृच्छिक संख्या उत्पन्न करने के लिए), यह हमेशा एक ही नंबर देता है: मेरे कोड इस प्रकार हैं (एक वर्ग बुलाया संख्या के अंदर) है। उदाहरण के लिए यदि मैं करना चाहता था:

System.out.println(numbers.random(10)); 
System.out.print(numbers.random(10)); 

यह हमेशा एक ही संख्या को प्रिंट करता है उदा। 5 5. मुझे ऐसा करने के लिए क्या करना है कि यह दो अलग-अलग संख्याओं को प्रिंट करता है उदा। 5 8

यह अनिवार्य है कि मैंने बीज निर्धारित किया।

धन्यवाद

+3

प्रत्येक बार जब आप फ़ंक्शन को कॉल करते हैं तो एक नया रैंडम ऑब्जेक्ट न बनाएं। इसे एक निजी चर के रूप में रखें और इसे केवल – Rob

+0

पर तुरंत चालू करें आप बीज को क्या सेट कर रहे हैं? –

+0

मैन्युअल रूप से बीज को सेट करने की अनुशंसा नहीं की जाती है जबतक कि आपको पता न हो कि इसका क्या अर्थ है। – m0skit0

उत्तर

36

आप पूरी कक्षा के पार Random() उदाहरण साझा करने के लिए की जरूरत है:

public class Numbers { 
    Random randnum; 

    public Numbers() { 
     randnum = new Random(); 
     randnum.setSeed(123456789); 
    } 

    public int random(int i){ 
     return randnum.nextInt(i); 
    } 
} 
32

आप हमेशा बीज सेट हैं, तो आप हमेशा एक ही जवाब मिल जाएगा। यही वह बीज है जो बीज करता है।

3

प्रत्येक बार जब आप एक नया यादृच्छिक संख्या चाहते हैं, तो स्टार्टअप पर बीज सेट करें।

2

तुम क्या प्रयोग कर रहे हैं, एक यादृच्छिक संख्या जनरेटर नहीं है, यह एक छद्म यादृच्छिक संख्या जनरेटर है। पीआरएनजी के छद्म-यादृच्छिक संख्याओं के अनुक्रम उत्पन्न होते हैं, बीज अनुक्रम में प्रारंभिक बिंदु का चयन करता है (एक पीआरएनजी एक या कई अनुक्रम उत्पन्न कर सकता है)।

1

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

यदि आप बीज नहीं डालते हैं, तो पहला बीज एक चर स्रोत (आमतौर पर सिस्टम समय) से लिया जाएगा।

आमतौर पर, बीज के साथ एक मूल्य का उपयोग सटीक मानों को दोहराने के लिए किया जाएगा (उदाहरण के लिए, परीक्षण के लिए)। बजाय बीज के बिना रैंडम का प्रयोग करें।

2

क्या आपको अपने random(int i) विधि के अंदर new Random() बनाने की आवश्यकता है? यदि आप इसे इस तरह से करने के लिए तैयार हैं, तो आप इसका उपयोग कर सकते हैं, आप बीज को वर्तमान समय में सेट कर सकते हैं, हालांकि यह असफल साबित नहीं है, क्योंकि आप अपने numbers.random(10) को इतनी तेजी से कॉल कर सकते हैं कि यह एक जैसा होगा बीज। आप शायद नैनोसेकंड्स (System.nanoTime() मुझे लगता है कि कोशिश कर सकते हैं? और अगर सेटसिड केवल int स्वीकार करता है, तो मुझे लगता है कि गुणा करें)।

यदि आपको ऐसा करने की अनुमति है, तो मैं आपको सुझाव दूंगा कि, के बाहर आपकी यादृच्छिक घोषित करना है। यदि आप अपने यादृच्छिक चर को instanciate, कहते हैं, अपने number वर्ग कन्स्ट्रक्टर, आप किसी भी बीज सेट कर सकते हैं और जब भी आप अपनी विधि को कॉल करते हैं तो यह आपको एक नया नंबर देगा। (यदि आप निरंतर बीज का उपयोग करते हैं तो वे आपके आवेदन को पुनरारंभ करते समय संख्याओं के समान सेट होंगे, हालांकि, आप इस मामले में भी अपने बीज के रूप में समय का उपयोग कर सकते हैं)।

अंत में, अंतिम समस्या तब हो सकती है जब आप एक ही समय में कई number कक्षाएं घोषित करें। वे सभी एक ही यादृच्छिक बीज होंगे और आपको यादृच्छिक संख्याओं का एक ही सेट देंगे। यदि ऐसा होता है, तो आप अपनी मुख्य कक्षा में static Random बना सकते हैं और इसे अपनी संख्या कक्षा में कॉल कर सकते हैं। यह उन दो वर्गों को जोड़ेगा, लेकिन यह काम करेगा।एक और विकल्प आपके number वर्ग कन्स्ट्रक्टर को बढ़ते मूल्य को भेजना होगा, प्रत्येक number के लिए आप तत्काल हैं, और बीज के रूप में पास किए गए मान का उपयोग करें।

दूसरा विकल्प आपके लिए अच्छा होना चाहिए, हालांकि, अगर आपको ऐसा करने की अनुमति है।

12

आपके द्वारा देखे जाने वाले दो मुद्दे हैं। पहला यह है कि कोड एक यादृच्छिक उदाहरण के लिए बीज मान सेट करता है। दूसरा यह है कि उदाहरण विधि "यादृच्छिक" एक नई रैंडम ऑब्जेक्ट का उदाहरण देती है और फिर तुरंत अपने बीज को उसी बीज के साथ सेट करती है। इन दोनों के संयोजन की गारंटी है कि, मेरे समान मूल्य के लिए, विधि "यादृच्छिक" हमेशा एक ही मान वापस कर देगी और बीज हमेशा उत्पन्न होने वाले क्रम में यह पहला होगा।

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

public class RandomDemo { // arbitrary example class name 
    // lots of class related stuff may be here... 

    // still inside the class scope... 
    // private is a good idea unless an external method needs to change it 
    private Random randnum = new Random(123456789L); 
    // the seed guarantees it will always produce the same sequence 
    // of pseudo-random values when the next methods get called 
    // for unpredicable sequences, use the following constructor instead: 
    // private Random randnum = new Random(); 

    // lots of code may be here... 

    // publicly exposed instance method for getting random number 
    // from a sequence determined by seed 123456789L 
    // in the range from 0 through i-1 
    public int randnum(int i) { 
     // don't set the seed in here, or randnum will return the exact same integer 
     // for the same value of i on every method call 
     // nextInt(i) will give the next value from randnum conforming to range i 
     return randnum.nextInt(i); 
    } // end randnum 

    // lots of more code may be here... 

} // end class RandDemo 

उपर्युक्त आपको आपकी सटीक समस्या का सटीक समाधान देगा जैसा कि कहा गया है। हालांकि, एक अनिवार्य बीज का उपयोग असामान्य लगता है, यह क्या करता है।

यदि यह एक क्लास प्रोजेक्ट या सॉफ़्टवेयर परीक्षण के लिए है जहां अनुक्रम को अनुमानित और दोहराने योग्य होना है, तो बीज को निश्चित मान पर सेट करना समझ में आता है। अन्यथा, बीज को कुछ पूर्व निर्धारित मूल्य पर सेट करने की वैधता पर सवाल उठाएं। निम्नलिखित यादृच्छिक, रैंडम के लिए बीज और बीज की आपूर्ति के लिए प्रावधान क्यों है, इसके बारे में और बताता है।

Random() 

और

Random(long seed) 

और एक उदाहरण विधि

setSeed(long seed) 

है कि सभी एक यादृच्छिक उदाहरण से प्राप्त संख्या के अनुक्रम को प्रभावित:

रैंडम दो कंस्ट्रक्टर्स है। उदाहरण के विधि,

setSeed(long seed) 

सेट एक ही स्थिति में हो गया होता यह सिर्फ निर्माता तर्क के रूप में एक ही बीज के साथ instanced किया गया था करने के लिए रैंडम वस्तु। बीज मूल्य के केवल कम-आदेश 48 बिट्स का उपयोग किया जाता है।

यदि कोई रैंडम ऑब्जेक्ट बीज के बिना इंस्टॉलेशन किया जाता है, तो बीज मिलिसेकंड में सिस्टम समय के समान ही होगा। यह सुनिश्चित करता है कि, जब तक कि दो रैंडम ऑब्जेक्ट्स को एक ही मिलीसेकंड में इंस्टॉल नहीं किया जाता है, तो वे अलग-अलग छद्म-यादृच्छिक अनुक्रम उत्पन्न करेंगे। बीज मूल्य के केवल कम आदेश 48 बिट्स का उपयोग किया जाता है। यह अप्रत्याशित छद्म-यादृच्छिक अनुक्रम का कारण बनता है। प्रत्येक बार जब कोई अगली विधि कॉल करता है तो यादृच्छिकता का एक नया उदाहरण प्राप्त करने के लिए संसाधनों की गणना करना आवश्यक और अपर्याप्त नहीं है।

यादृच्छिक के बीज पैरामीटर प्रदान किए जाते हैं ताकि कोई एक यादृच्छिक वस्तु उत्पन्न कर सके जो एक अनुक्रम उत्पन्न करता है जो दोहराने योग्य है। किसी दिए गए बीज के लिए, अगली विधियों में मूल्यों का क्रम उसी बीज होने पर गारंटी दी जाती है जब भी उस बीज का उपयोग किया जाता है।यह ऐसे सॉफ़्टवेयर का परीक्षण करने के लिए उपयोगी है जो छद्म-यादृच्छिक अनुक्रमों का उपयोग करने जा रहे हैं जहां परिणाम अनुमानित और दोहराने योग्य हैं। यह ऑपरेशन में विभिन्न अप्रत्याशित छद्म-यादृच्छिक अनुक्रम बनाने के लिए उपयोगी नहीं है।

कथन "यह अनिवार्य है कि मैंने बीज सेट किया" रैंडम ऑब्जेक्ट के छद्म-यादृच्छिक अनुक्रमों की किसी भी अप्रत्याशितता को अस्वीकार करता है। क्या यह एक क्लास प्रोजेक्ट या सॉफ़्टवेयर टेस्ट के लिए है जहां प्रोग्राम को उसी इनपुट के लिए परिणाम समान होना चाहिए?

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

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