c++ - <random> लिनक्स में समान संख्या उत्पन्न करता है, लेकिन विंडोज में नहीं



linux windows (2)

यहाँ क्या हो रहा है:

  • default_random_engine in libstdc ++ (GCC का मानक पुस्तकालय) minstd_rand0 , जो एक साधारण रैखिक minstd_rand0 इंजन है:

    typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0;
  • जिस तरह से यह इंजन यादृच्छिक संख्या उत्पन्न करता है वह x i + 1 = (16807x i + 0) mod 2147483647 है।

  • इसलिए, यदि बीज 1 से भिन्न होते हैं, तो अधिकांश समय पहली उत्पन्न संख्या 16807 से भिन्न होगी।

  • इस जनरेटर की रेंज [1, 2147483646] है। जिस तरह से libstdc ++ का uniform_int_distribution उसे श्रेणी [1, 100] में पूर्णांक के लिए मैप करता है, अनिवार्य रूप से यह है: एक नंबर n उत्पन्न करना। यदि संख्या 2147483600 से अधिक नहीं है, तो वापसी (n - 1) / 21474836 + 1 ; अन्यथा, एक नए नंबर के साथ फिर से प्रयास करें।

    यह देखना आसान होना चाहिए कि अधिकांश मामलों में, केवल 16807 से भिन्न होने वाले दो n s इस प्रक्रिया के तहत [1, 100] में समान संख्या प्राप्त करेंगे। वास्तव में, हर 21474836/16807 = 1278 सेकंड या 21.3 मिनट के बारे में एक के बाद एक उत्पन्न संख्या बढ़ने की उम्मीद होगी, जो आपकी टिप्पणियों से बहुत अच्छी तरह सहमत है।

MSVC का default_random_engine mt19937 , जिसमें यह समस्या नहीं है।

https://src-bin.com

नीचे दिए गए कोड का मतलब अंतराल में पाँच छद्म यादृच्छिक संख्याओं की सूची तैयार करना है [1,100]। मैं time(0) साथ default_random_engine को बीज देता हूं, जो सिस्टम का समय यूनिक्स समय में वापस करता है। जब मैं Microsoft Visual Studio 2013 का उपयोग करके विंडोज 7 पर इस कार्यक्रम को संकलित और चलाता हूं, तो यह अपेक्षित (नीचे देखें) के रूप में काम करता है। जब मैं जी ++ कंपाइलर के साथ आर्क लिनक्स में ऐसा करता हूं, हालांकि, यह अजीब व्यवहार करता है।

लिनक्स में, हर बार 5 नंबर उत्पन्न होंगे। प्रत्येक निष्पादन पर अंतिम 4 संख्याएं भिन्न होंगी (जैसा कि अक्सर होता है), लेकिन पहली संख्या समान रहेगी।

विंडोज और लिनक्स पर 5 निष्पादन से उदाहरण आउटपुट:

      | Windows:       | Linux:        
---------------------------------------
Run 1 | 54,01,91,73,68 | 25,38,40,42,21
Run 2 | 46,24,16,93,82 | 25,78,66,80,81
Run 3 | 86,36,33,63,05 | 25,17,93,17,40
Run 4 | 75,79,66,23,84 | 25,70,95,01,54
Run 5 | 64,36,32,44,85 | 25,09,22,38,13

इस रहस्य को जोड़ते हुए, कि लिनक्स पर एक-एक करके पहली बार समय-समय पर वेतन वृद्धि। उपरोक्त आउटपुट प्राप्त करने के बाद, मैंने लगभग 30 मिनट इंतजार किया और फिर से यह जानने की कोशिश की कि पहली संख्या बदल गई है और अब हमेशा 26 के रूप में उत्पन्न हो रही है। यह समय-समय पर 1 की वृद्धि करना जारी रखा है और अब 32 पर है। time(0) के बदलते मूल्य time(0)

पहला नंबर शायद ही कभी पूरे रनों में बदलता है, और फिर जब ऐसा होता है, तो 1 से बढ़ जाता है?

कोड। यह बड़े करीने से 5 नंबर और सिस्टम टाइम प्रिंट करता है:

#include <iostream>
#include <random>
#include <time.h>

using namespace std;

int main()
{
    const int upper_bound = 100;
    const int lower_bound = 1;

    time_t system_time = time(0);    

    default_random_engine e(system_time);
    uniform_int_distribution<int> u(lower_bound, upper_bound);

    cout << '#' << '\t' << "system time" << endl
         << "-------------------" << endl;

    for (int counter = 1; counter <= 5; counter++)
    {
        int secret = u(e);
        cout << secret << '\t' << system_time << endl;
    }   

    system("pause");
    return 0;
}

Answer #1

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

विंडोज यादृच्छिक संख्या बीज माउस, कीबोर्ड, नेटवर्क और दिन के समय के संग्रह से प्राप्त किया जाता है। यह दोहराने योग्य नहीं है। लेकिन यह नमक मूल्य एक ज्ञात बीज को रीसेट किया जा सकता है, जैसा कि ऊपर बताया गया है, एक प्रयोग के डिजाइन में शामिल है।

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






visual-studio-2013