2015-10-08 9 views
10

मुझे यह निर्धारित करने में समस्या हो रही है कि मेर्सन ट्विस्टर सी ++ 11 का कौन सा संस्करण प्रदान करता है। Mersenne twister: A 623 Dimensionally Equidistributed Uniform Pseudorandom Number Generator पर मात्सुमोतो और Nishimura एसीएम कागज को देखते हुए, लेखकों एल्गोरिथ्म, एल्गोरिथ्म के एक कार्यान्वयन प्रदान करते हैं और यह MT19937 कहते हैं।कौन सा मेर्सन ट्विस्टर सी ++ 11 प्रदान करता है?

हालांकि, जब मैं नीचे दिए गए छोटे कार्यक्रम के साथ सी ++ 11 के समान नामित जेनरेटर का परीक्षण करता हूं, तो मैं मत्सुमोतो और निशिमुरा के MT19937 द्वारा बनाई गई स्ट्रीम को पुन: उत्पन्न नहीं कर सकता। धाराएं उत्पादित पहले 32-बिट शब्द से भिन्न होती हैं।

कौन सा मेर्सन ट्विस्टर सी ++ 11 प्रदान करता है?


नीचे कार्यक्रम जीसीसी, -std=c++11 और GNU के stdlibc++ का उपयोग कर फेडोरा 22 पर चलाया गया था।

std::mt19937 prng(102013); 
for (unsigned int i = 0; i <= 625; i++) 
{ 
    cout << std::hex << prng(); 

    if(i+1 != 625) 
     cout << ","; 

    if(i && i%8 == 0) 
     cout << endl; 
} 
+0

यदि आप बूस्ट में [हेडर] (http://www.boost.org/doc/libs/release/boost/roc/lerssne_twister.hpp) देखते हैं। यादृच्छिक, वे बताते हैं * एक पूर्णांक से बीजिंग था अप्रैल 2005 में एक [कमजोरी] को संबोधित करने के लिए बदल दिया गया (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html) *।क्या यह हो सकता है कि आप उस परिवर्तन से पहले प्रकाशित एक पेपर से परिणामों की तुलना कर रहे हैं? – Praetorian

+0

@Praetorian - ठीक है, मुझे यकीन नहीं है, लेकिन मुझे विश्वास नहीं है। मैं बूस्ट का उपयोग नहीं कर रहा हूँ; बल्कि, मैं 'libstdC++' के माध्यम से जीएनयू के कार्यान्वयन का उपयोग कर रहा हूं। – jww

+0

यह http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c का उपयोग करता है। IOW, क्या @Praetorian से जुड़ा हुआ है। –

उत्तर

4

से MT19937 को देखते हुए अपने कागज से जुड़ा हुआ है और MT19937 मानक द्वारा परिभाषित ऐसा लगता है कि वे एक ही है, लेकिन कर रहे हैं की टेम्परिंग जोड़ा गया है एक अतिरिक्त परत और एक प्रारंभ गुणक

यदि हम देखो मूल्यों [rand.predef] द्वारा परिभाषित पर 26.5.5 (3) मानकों कागज द्वारा परिभाषित बनाम हम

32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253 <- standard 
w ,n ,m ,r ,a   ,u ,d   ,s,b   ,t ,c   ,l ,f 
32,624,397,31,0x9908b0df,11,   ,7,0x9d2c5680,15,0xefc60000,18,   <- paper 

है यह वह जगह है जहां अंतर से आ रही है। इसके अलावा मानक के अनुसार std::mt19937 के 10,000 वें यात्रा 399268537

+0

32-बिट संस्करण के लिए, 'd' के लिए '0xffffffff' मान का अर्थ है कि वास्तव में कोई परिवर्तन नहीं होता है। –

+0

मूल कागज 69069 गुणक के रूप में उपयोग किया जाता है (1812433253 एआर संशोधन और मानक का हिस्सा है)। – jww

+0

मैं मदद नहीं कर सकता लेकिन महसूस करता हूं कि सी ++ को * MT19937' नाम नहीं दिया जाना चाहिए क्योंकि इसका मूल * पैरामीटर का उपयोग नहीं किया गया है। 'ईएमटी 1 9 3737, 'एमटी 1 9 737', 'ईएमटी 1 9 737', आदि बेहतर विकल्प रहे होंगे। वास्तव में, ऐसा लगता है कि ["एआर" ("ऐरे" के लिए) लेखकों ने इस परिवर्तन को अलग करने के लिए उपयोग किया है] (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/ एमटी/MT2002/emt19937ar.html) मूल से। – jww

1

ऐसा लगता है सी ++ 11 Mersenne Twister with improved initialization

मैं सिर्फ मूल सी कार्यान्वयन निकाला है, और सी के साथ ++ तुलना में प्रदान करता है।

#include <iostream> 
#include <cstdio> 
#include <random> 

#define N 624 
#define M 397 
#define MATRIX_A 0x9908b0dfUL /* constant vector a */ 
#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ 
#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ 

static unsigned long mt[N]; /* the array for the state vector */ 
static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ 

void init_genrand(unsigned long s) 
{ 
    mt[0]= s & 0xffffffffUL; 
    for (mti=1; mti<N; mti++) { 
     mt[mti] = 
     (1812433253UL * (mt[mti-1]^(mt[mti-1] >> 30)) + mti); 
     mt[mti] &= 0xffffffffUL; 
    } 
} 

unsigned long genrand_int32() 
{ 
    unsigned long y; 
    static unsigned long mag01[2]={0x0UL, MATRIX_A}; 

    if (mti >= N) { /* generate N words at one time */ 
     int kk; 

     if (mti == N+1) /* if init_genrand() has not been called, */ 
      init_genrand(5489UL); /* a default initial seed is used */ 

     for (kk=0;kk<N-M;kk++) { 
      y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 
      mt[kk] = mt[kk+M]^(y >> 1)^mag01[y & 0x1UL]; 
     } 
     for (;kk<N-1;kk++) { 
      y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); 
      mt[kk] = mt[kk+(M-N)]^(y >> 1)^mag01[y & 0x1UL]; 
     } 
     y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); 
     mt[N-1] = mt[M-1]^(y >> 1)^mag01[y & 0x1UL]; 

     mti = 0; 
    } 

    y = mt[mti++]; 

    y ^= (y >> 11); 
    y ^= (y << 7) & 0x9d2c5680UL; 
    y ^= (y << 15) & 0xefc60000UL; 
    y ^= (y >> 18); 

    return y; 
} 

int main() 
{ 
    init_genrand(102013); 

    std::mt19937 prng(102013); 

    for (size_t i = 0; i < 10000; ++i) { 
     if (genrand_int32() != prng()) { 
      std::cout << "ERROR" << std::endl; 
      return 1; 
     } 
    } 

    std::cout << "OK" << std::endl; 
    return 0; 
} 
+0

की अवधि है, इसलिए ऐसा लगता है कि वे 'MT19937ar' प्रदान कर रहे हैं, न कि 'MT19937'। क्या वो सही है? – jww

+0

@jww नहीं, सही नाम 'MT19937' है। ऐसा लगता है कि 'MT19937ar' फ़ाइल का सिर्फ एक नाम है, जहां उन्होंने सरणी प्रारंभिक जोड़ा। – Stas

+0

@jww इसके अलावा, सी कार्यान्वयन की सूची देखें: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/c-lang.html वहां थे दो संस्करण (1 99 8 और 1 999) जो अब पुराने हैं। – Stas

1

मैं कहना चाहिए कि सी ++ 11 वास्तव में टेम्पलेट वर्ग के माध्यम से कई Mersenne ट्विस्टर्स प्रदान करता है: किसी को भी इन लीवर और घुंडियों पता लगाने के लिए बहादुरी है

template <class UIntType, 
      size_t word_size, 
      size_t state_size, 
      size_t shift_size, 
      size_t mask_bits, 
      UIntType xor_mask, 
      size_t tempering_u, 
      UIntType tempering_d, 
      size_t tempering_s, 
      UIntType tempering_b, 
      size_t tempering_t, 
      UIntType tempering_c, 
      size_t tempering_l, 
      UIntType initialization_multiplier> 
    class mersenne_twister_engine; 

हैं .. बेशक इन दोनों मानक मानक हैं:

using mt19937 
    = mersenne_twister_engine<uint_fast32_t, 
          32, 
          624, 
          397, 
          31, 
          0x9908b0df, 
          11, 
          0xffffffff, 
          7, 
          0x9d2c5680, 
          15, 
          0xefc60000, 
          18, 
          1812433253>; 

और 64-बिट संस्करण:

using mt19937_64 
    = mersenne_twister_engine<uint_fast64_t, 
          64, 
          312, 
          156, 
          31, 
          0xb5026f5aa96619e9, 
          29, 
          0x5555555555555555, 
          17, 
          0x71d67fffeda60000, 
          37, 
          0xfff7eee000000000, 
          43, 
          6364136223846793005>; 

मैं सोचा है यह RNGs की गुणवत्ता की जाँच ताकि लोगों को नई instantiations की कोशिश कर सकते के लिए एक टूलबॉक्स प्रदान करने के लिए अच्छा होगा।

32,624,397,31,  0x9908b0df,11,  0xffffffff,7 ,  0x9d2c5680,15,  0xefc60000,18,1812433253   <- std::mt19937 
64,312,156,31,0xb5026f5aa96619e9,29,0x5555555555555555,17,0x71d67fffeda60000,37,0xfff7eee000000000,43,6364136223846793005 <- std::mt19937_64 
w ,n ,m ,r ,a     ,u ,d     ,s ,b     ,t ,c     ,l ,f 
32,624,397,31,  0x9908b0df,11,     ,7 ,  0x9d2c5680,15,  0xefc60000,18,     <- paper 

@NathanOliver करने के लिए धन्यवाद के साथ:

यहाँ टेम्पलेट parms की तुलना है।

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