2013-03-03 5 views
9

मुझे आश्चर्य है कि यह प्रोग्राम की शुरुआत में केवल एक बार यादृच्छिक संख्या जनरेटर के लिए पर्याप्त है। मैं ऐसे कार्य लिखता हूं जो यादृच्छिक संख्याओं का उपयोग करते हैं। मैं फ़ंक्शन के भीतर रैंड() जनरेटर को कभी बीज नहीं देता, बल्कि मुख्य प्रविष्टि पर srand() को कॉल करना छोड़ देता हूं। जैसे मेरा प्रोग्राम इस तरह दिख सकता है:मुझे सी ++ में कितनी बार शोध किया जाना चाहिए?

void func1() 
{ 
    std::cout << "This is func1 " << std::rand() << std::endl; 
} 

void func2() 
{ 
    std::cout << "This is func2 " << std::rand() << std::endl; 
} 

int main() 
{ 
    std::srand(std::time(NULL)); 
    func1(); 
    func2(); 
    return 0; 
} 

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

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

मैं सी ++ 11 में नई सुविधाओं को जानने के लिए उत्साहित हूं, लेकिन कभी-कभी यह बहुत भ्रमित है। क्या मुझे कोई नया यादृच्छिक जेनरेटर के साथ कुछ गलत होने पर मुझे बता सकता है? या सी ++ 11 में सबसे अच्छा अभ्यास क्या हो सकता है?

+0

एक वैश्विक बीज फ़ंक्शन है जो वर्तमान समय या (डीबग मोड में) स्थिर करता है। –

उत्तर

7

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

बहु-थ्रेडेड अनुप्रयोगों में काम सौंपने के लिए उपयोग किया जाने वाला एक प्रोग्रामिंग पैटर्न thread pool है।यदि निष्पादित करने के लिए पूल में कार्यकर्ता धागे के लिए कतारबद्ध कार्य आइटम आरएनजी की आवश्यकता होती है और आप निष्पादन को रन से चलाने के लिए निर्धारक होना चाहते हैं, तो आप चाहते हैं कि प्रत्येक थ्रेड आरएनजी को फिर से बीज करने के बाद आरएनजी को फिर से बीज करे कतार

  • इस काम आइटम के लिए प्रारंभ के हिस्से के रूप में किया जा सकता
  • बीज नौकरी के लिए मानकों का एक hash function शामिल हो सकता है
  • यदि आप के बारे में यह कैसे कोडित है आप छद्म हो सकता है सावधान कर रहे हैं - यादृच्छिकता और कार्यकर्ता धागे की संख्या या आदेश की परवाह किए बिना निर्धारण जिसमें वे कतार से नौकरियां खींचते हैं।

यहाँ एक तो सवाल यह है कि इस के साथ संबंधित है: Deterministic random number generator tied to instance (thread independent)

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

+1

बहुत बहुत धन्यवाद! ऐसा लगता है कि मैं बहुत लंबे समय तक एकल थ्रेडेड अनुप्रयोगों के साथ काम कर रहा हूं। अब मुझे आश्वस्त है कि मैं बहु-थ्रेडेड अनुप्रयोगों के लिए अलग-अलग यादृच्छिक संख्या जेनरेटर रखना चाहता हूं। –

17

यह निश्चित रूप से आपके द्वारा विकसित किए जा रहे सिस्टम के समग्र लक्ष्यों पर निर्भर करेगा, लेकिन आम तौर पर आपको केवल उस प्रणाली को बीज करने की आवश्यकता होगी जिसके लिए एक बार उस सिस्टम की शुरुआत में यादृच्छिक संख्या जेनरेटर (आरएनजी) की आवश्यकता होती है।

गेम विकास में डीबगिंग और रखरखाव के लिए उस प्रणाली को अलग करने के लिए एक अलग आरएनजी प्रति सिस्टम (एआई, प्रक्रियात्मक सामग्री जनरेटर, कण, आदि) होना आम बात है।

यदि आप बीज स्टोर करते हैं तो आप बहुत कम डेटा के साथ तर्क को फिर से चला सकते हैं (केवल प्रत्येक फ्रेम से डेल्टा इनपुट की आवश्यकता होती है)। यह न केवल आपको एप्लिकेशन को डीबग करने की अनुमति देता है, बल्कि आपको उपयोगकर्ता के लिए रिकॉर्डिंग और रीप्ले सुविधाओं का समर्थन करने की अनुमति देता है। जाहिर है अगर आप एक रीप्ले मोड बना रहे थे, तो सिस्टम को प्रत्येक रीप्ले सत्र से पहले प्रत्येक सिस्टम के लिए रिकॉर्ड किए गए बीज के साथ आपूर्ति की आवश्यकता होगी।

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

+1

बहुत बढ़िया जवाब, बहुत अच्छी तरह से गोल। +1 –

+0

बहुत बहुत धन्यवाद! मैंने बहुत कुछ सीखा है। –

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