2012-09-07 14 views
5

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

मेरा सवाल है: सी ++ 2011 के साथ बीज कैसे उत्पन्न करें?

+0

मुझे लगता है कि एकल cored वास्तुकला पर संख्या छद्म यादृच्छिक होगा, आप 1,2,3,4,5,6,7,8 की तरह नंबर जेनरेट होता है और सीपीयू के माध्यम से क्रमिक रूप से जा रहा प्रक्रियाओं होगा बस क्या ले लिया अगला और यह 'रैंड() की तरह कार्य करेगा; रैंड (;) वापसी रैंड(); ' – Vyktor

उत्तर

6

अपने मुख्य धागे में, एक अच्छे यादृच्छिक स्रोत से एक एकल बीज (या बीज अनुक्रम) निकालें (उदाहरण के लिए लिनक्स पर /dev/urandom से)। उस डेटा का उपयोग बीज को एक रूट रूट पीआरएनजी में करें। फिर अपने थ्रेड-स्थानीय पीआरएनजी के लिए बीज मान उत्पन्न करने के लिए PRNG का उपयोग करें।

#include <random> 
#include <vector> 

typedef std::mt19937 rng_type; 
std::uniform_int_distribution<rng_type::result_type> udist; 

int main() 
{ 
    rng_type rng; 

    // seed rng first, and store the result in a log file: 
    rng_type::result_type const root_seed = get_seed(); 
    rng.seed(root_seed); 

    // make thread seeds: 
    std::vector<rng_type::result_type> seeds(NUMBER_OF_THREADS); 
    for (auto & n : seeds) { n = udist(rng); } 

    // make threads... 
} 

<random> में यादृच्छिक संख्या इंजन इंटरफ़ेस तुम दोनों एक एकल पूर्णांक से और पूर्णांकों का एक अनुक्रम से बीज की सुविधा देता है। यदि आप अतिरिक्त यादृच्छिकता चाहते हैं, तो आप कई सौ पूर्णांक के अनुक्रम से mt19937 बीज कर सकते हैं।

0

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

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

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

6

सी ++ 11 std::random_device प्रदान करता है ताकि स्रोत उपलब्ध होने पर गैर-निर्धारक यादृच्छिक संख्या प्रदान किया जा सके। यह सुनिश्चित करने के लिए कि यह अच्छा है, आपको अपने कार्यान्वयन की जांच करनी होगी। libC++ डिफ़ॉल्ट रूप से/dev/urandom का उपयोग करता है। libstdC++ भी करता है यदि मैक्रो _GLIBCXX_USE_RANDOM_TR1 परिभाषित किया गया है। दुर्भाग्य से विजुअल स्टूडियो का कार्यान्वयन गैर-निर्धारिती नहीं है। संपादित करें: वीएस2012 के रूप में उनके कार्यान्वयन विंडोज की क्रिप्टोग्राफी सेवाओं का उपयोग करता है।

यदि std::random_device यादृच्छिकता के एक गैर-निर्धारिती स्रोत तक पहुंच प्रदान करता है (आमतौर पर/dev/urandom एक क्रिप्टोग्राफिक पीआरएनजी का उपयोग करता है) तो यह स्वतंत्र बीज पैदा करने के लिए पर्याप्त होना चाहिए।

#include <random> 

int main() { 
    std::random_device r; 
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; 
    std::mt19937 engine(seed); 

} 

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

std::random_device r; 
std::vector<std::mt19937> engines; 

int engines = 50; 
for (int i = 0; i < engines; ++i) { 
    std::seed_seq s{r(), r(), r(), r(), r(), r(), r(), r()}; 
    engines.emplace_back(s); 
} 

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

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

std::random_device r; 
std::vector<std::uint_least32_t> data; 
std::generate_n(back_inserter(data), 624, std::ref(r)); 

std::seed_seq seed(begin(data), end(data)); 

std::mt19937 engine(seed); // 'fully' seeded mt19937 
+2

+1 'std :: random_device' का उल्लेख करने के लिए +1। – ildjarn

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