2015-09-23 7 views
5

मैं libstdc साथ ++ इस कार्यक्रम की कोशिश की है, libC++ और dinkumware:रैंडम उत्पादन कार्यान्वयन के बीच अलग अलग

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <random> 
#include <functional> 
#include <limits> 

int main() 
{ 
    std::vector<int> v(10); 

    std::mt19937 rand{0}; 
    std::uniform_int_distribution<> dist(
     1, 10 
    ); 

    std::generate_n(v.begin(), v.size(), 
     std::bind(dist, rand)); 

    for (auto i : v) 
     std::cout << i << " "; 
} 

आउटपुट क्रमशः है:

6 6 8 9 7 9 6 9 5 7 

6 1 4 4 8 10 4 6 3 5 

5 10 4 1 4 10 8 4 8 4 

उत्पादन प्रत्येक रन के लिए संगत है, लेकिन आप कर सकते हैं के रूप में देखो, वे अलग हैं। के बारे में बताएं?

+4

आप समान मूल्यों का उत्पादन करने के लिए * यादृच्छिक संख्या पीढ़ी * के भिन्न कार्यान्वयन की अपेक्षा क्यों करते हैं? – lisyarus

+6

समझाओ * क्या *? रनों के बीच एकता? या कार्यान्वयन के बीच असंगतता?एक ही बीज से विभिन्न छद्म-यादृच्छिक अनुक्रमों का उत्पादन करने के लिए विभिन्न कार्यान्वयन की अनुमति है। यह वही है जो आपने देखा था। – AnT

+0

सटीक वही एल्गोरिदम उसी बीज को दिए गए समान मानों का उत्पादन करना चाहिए, है ना? आपके तर्क समझ में नहीं आता है। – user5368921

उत्तर

7

कोईuniform_int_distribution<> के लिए आवश्यक कार्यान्वयन आवश्यक है। [rand.dist.general] निर्दिष्ट करता है कि:

प्रत्येक निर्दिष्ट वितरण का उत्पादन करने के लिए एल्गोरिदम कार्यान्वयन-परिभाषित हैं।

सब [rand.dist.uni.int] राज्यों है:

एक uniform_int_distribution यादृच्छिक संख्या वितरण यादृच्छिक पूर्णांकों i, a <= i <= b, निरंतर असतत संभावना समारोह P(i | a, b) = 1/(b − a + 1) के अनुसार वितरित पैदा करता है।

प्रत्येक कार्यान्वयन इस वितरण को प्राप्त करने के लिए स्वतंत्र है जो यह चाहता है। जो आप देख रहे हैं वह स्पष्ट रूप से तीन अलग-अलग कार्यान्वयन है।

+0

वाह। यह बेहद अनूठा है। मैंने यह भी उम्मीद की होगी कि एक ही बीज को प्रत्येक लगातार कॉल का मूल्य अच्छी तरह से परिभाषित किया गया हो। कौन सी सी ++ 11 यादृच्छिक संख्या एल्गोरिदम उस व्यवहार को परिभाषित करता है (यदि कोई है)? – David

+0

मानक परिभाषित करता है कि कैसे '[rand.eng.mers] 'में मेर्सन ट्विस्टर लागू किया जाना चाहिए। – user5368921

+0

@ user5368921 हाँ, गलत छेद शुरू कर दिया। – Barry

2

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

उदाहरण के लिए, एक त्वरित परीक्षण:

#include <random> 
#include <iostream> 

int main() { 
    std::mt19937 r; 

    for (int i=0; i<10000-2; i++) 
     r(); 
    for (int i=0; i<3; i++) 
     std::cout << r() << "\n"; 
} 

... हर (हाल) संकलक के साथ समान परिणाम दिखाता है मैं अपने पास रखें:

1211010839 
4123659995 
725333953 

उन तीन की दूसरी आवश्यक मूल्य है मानक द्वारा।

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

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

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