´ë¹®    
FindPage  |  TitleIndex  |  UserPreferences  |  [http]me2day  |  redpixel
RecentChanges
 


Mersenne Twister ¾Ë°í¸®Áò

Contents

1 Mersenne Twister¶õ?
2 Mersenne TwisterÀÇ °³¼±µÈ ÃʱâÈ­ ¹öÀü
2.1 ¼Ò°³
2.2 ´Ù¿î·Îµå
2.3 Ãß°¡»çÇ×
3 FAQ
3.1 Want a half open interval [0,1) instead of closed interval [0,1].
3.2 Need more than 32 bits accuracy.
3.3 To use as a random source for encryption.
3.4 Want a uniform discrete distribution among the integers 0..N-1, e.g. a dice in the case of N=6.
3.5 A seed of 32-bit is too small. We want a larger space for initial seeds.

1 Mersenne Twister¶õ? #

Mersenne Twister(MT) ´Â 1996~7³â¿¡ Makoto Matsumoto¿Í Takuji Nishimura¿¡ ÀÇÇØ ¹ßÇ¥µÈ ÀÇ»ç ³­¼ö »ý¼º±â¸¦ ¸»ÇÕ´Ï´Ù. MT´Â ´ÙÀ½°ú °°Àº ÀåÁ¡À» °¡Áö°í ÀÖ½À´Ï´Ù.
  • ±âÁ¸ÀÇ ´Ù¾çÇÑ »ý¼º±âÀÇ °áÁ¡µéÀ» °í·ÁÇÏ¿© µðÀÚÀεǾú½À´Ï´Ù.
  • ¾Ë°í¸®ÁòÀÌ C ¾ð¾î·Î ÄÚµùµÇ¾îÀÖÀ¸¸ç, ÀÚÀ¯·Ó°Ô ´Ù¿î·Îµå °¡´ÉÇÕ´Ï´Ù. BSD ¶óÀ̼¾½º¸¦ µû¸£¸ç, »ó¾÷ÀûÀÌµç ¾î¶°ÇÑ ¿ëµµ·Îµç »ç¿ëÀÌ °¡´ÉÇÕ´Ï´Ù.
  • ¾î¶°ÇÑ ´Ù¸¥ ±âÁ¸ ±¸ÇöµÈ »ý¼º±âº¸´Ùµµ µ¿ÀÏºÐÆ÷(equidistribution)¿¡ À־ ÈξÀ ¸Õ ±¸°£°ú ÈξÀ ³ôÀº Á¤·ÄºÎÇϸ¦ °¡Áö°í ÀÖ½À´Ï´Ù. (2^19937 - 1)ÀÇ ¹üÀ§¸¦ °¡Áö°í ÀÖ´Ù°í Áõ¸íµÇ¾îÀÖÀ¸¸ç, 623Â÷¿øÀÇ µ¿ÀÏºÐÆ÷ ¼Ó¼ºÀ» º¸ÁõÇÕ´Ï´Ù.)
  • »ý¼º¼Óµµ°¡ ºü¸¨´Ï´Ù. (ºñ·Ï ½Ã½ºÅÛ¿¡ ÀÇÁ¸Çϱä ÇÏÁö¸¸, MT´Â ÆÄÀÌÇÁ¶óÀÎÀ̳ª ij½Ã ¸Þ¸ð¸®¸¦ °¡Áø ½Ã½ºÅÛ»ó¿¡¼­ ¶§¶§·Î Ç¥ÁØ ANSI-C ¶óÀ̺귯¸®º¸´Ù ºü¸£´Ù°í º¸°íµÇ°í ÀÖ½À´Ï´Ù.)
  • ¸Þ¸ð¸®ÀÇ È¿À²ÀûÀÎ »ç¿ë. (mt19937.c ±¸ÇöÄÚµå´Â µ¿ÀÛÇϴµ¥ ÀÖ¾î ´ÜÁö 624 word¸¸ ¼Ò¸ðÇÕ´Ï´Ù.)
  • ÆÄÀ̼± ½ºÅ©¸³Æ®¿¡¼­´Â ±âº» random ¸ðµâ¿ë ¾Ë°í¸®ÁòÀ¸·Î¼­ »ç¿ëµÇ°í ÀÖ½À´Ï´Ù. Áï, ÆÄÀ̼± »ç¿ëÀÚ´Â ±×³É random ¸ðµâÀ» »ç¿ëÇÏ½Ã¸é µË´Ï´Ù.
  • boost::random ¿¡¼­ ±âº» ¾Ë°í¸®ÁòÀ¸·Î Æ÷ÇԵǾîÀÖ½À´Ï´Ù.

2 Mersenne TwisterÀÇ °³¼±µÈ ÃʱâÈ­ ¹öÀü #

2.1 ¼Ò°³ #

MTÀÇ ¸ðµç ÀÌÀü ¹öÀü¿¡¼­ÀÇ ÃʱâÈ­ ·çƾ¿¡´Â, seed»óÀÇ ÃÖ»óÀ§ ºñÆ®(most significant bit)°¡ »óÅ º¤ÅÍ(state vector)¿¡ Àß ¹Ý¿µµÇÁö ¾Ê´Â´Ù´Â ÀÛÀº ¹®Á¦Á¡ÀÌ Á¸ÀçÇÕ´Ï´Ù.

We should have noticed this when an [http]important caution on initializing tt800 (a small cousin of MT19937) was raised by MJeff Szuhay in the world-known random-number homepage [http]pLab, or when MDick van Albada taught us that the older initialization scheme may yield just nearly "shifted" sequence and sent us [http]mtRand.tgz, his nicely improved C++code (2000/5/24). The both phenomena arise from the same problem, namely that if two initial states are too near with respect to the Hamming distance, then the corresponding output sequences are close to each other.

This type of defficiency becomes very clear by a report by Martin Kretschmar , who initialized the state vector with many zeroes, or some bit-pattern. ÀÌ·¸°Ô ÇÏ¸é ³­¼öÀûÀÌÁö ¾ÊÀº ºÎºÐÀº ¿À·§µ¿¾È ³²¾ÆÀÖ°Ô µË´Ï´Ù.

¿©±â ÀÌ·¯ÇÑ °áÁ¡À» ÇØ°áÇÏ´Â MT19937ÀÇ »õ·Î¿î Ç¥ÁØ ÄÚµå, mt19937ar.c(arÀº ARray¸¦ ÀǹÌÇÕ´Ï´Ù)¸¦ °Ô½ÃÇÕ´Ï´Ù. ÀÌ ÄÚµå´Â seed·Î¼­ ÀÓÀÇÀÇ ±æÀÌÀÇ ¹è¿­À» Çã°¡ÇÏ´Â ¶Ç´Ù¸¥ ÃʱâÈ­ºÎºÐÀ» Æ÷ÇÔÇϰí ÀÖ½À´Ï´Ù.
  • ÀÌÀüÀÇ ÃʱâÈ­ ·çƾµé ´ë½Å¿¡ init_genrand(seed)À» »ç¿ëÇϽñ⠹ٶø´Ï´Ù.
  • 32ºñÆ® ±æÀ̺¸´Ù ´õ ±ä ÃʱâÈ­ seed¸¦ ÇÊ¿ä·ÎÇÏ´Â »ç¿ëÀÚ´Â, ÃʱâÈ­½Ã seed°ªÀ¸·Î¼­ ÀÓÀÇÀÇ ±æÀÌÀÇ ¹è¿­À» ¹Þ¾ÆµéÀÌ´Â init_by_array()À» »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.
  • [0,1)À̳ª 53ºñÆ® Á¤¹Ðµµ ½Ç¼öµîµî°ú °°Àº ½Ç¼ö ¹öÀüÀÌ ÀÌÁ¦ »ç¿ë°¡´ÉÇÕ´Ï´Ù.

2.2 ´Ù¿î·Îµå #

ÀÌ ¹öÀüÀº °ø°³ÀÔ´Ï´Ù. À̰ÍÀº BSD ¶óÀ̼¾½º¸¦ µû¸¥´Ù´Â °ÍÀ» ÀǹÌÇϸç, »ó¾÷Àû ¿ëµµ·Î¼­ÀÇ ¼öÁ¤À̳ª »ç¿ëÀ» Çã°¡ÇÑ´Ù´Â ¶æÀÔ´Ï´Ù.

2.3 Ãß°¡»çÇ× #

  • Those who needs speed: all the five real-versions make a function call to the integer version genrand_int(), which makes them slower than the previous versions. If you maximize your compiler's optimization level, it often develops the function call into "inline". If it does not, and if you need speed, then copy the code of genrand_int into the necessary functions, and add by hand your requiring transformation from integer to real.

  • A faster version considering Shawn Cokus's code is also available (2002/Feb./11). gzipped tar-file of Cokus-type code with simplification and speed-up by Matthew Bellew: [http]mt19937ar-cok.tgz.

3 FAQ #

3.1 Want a half open interval [0,1) instead of closed interval [0,1]. #

In the last "return()" in the function genrand(), (double)y is divided by (unsigned long)0xffffffff, i.e. 2^32-1. If you change this to 2^32, the output is distributed in [0,1). How to construct the real constant 2^32 depends on your system, but for example
double zzz = ((double)((unsigned long) 0x80000000))*2;
sets the real 2^32 into zzz. We guess there is a smarter way: let us know.

A master course student Sin Tanaka at the electoric engineering department of Keio University suggested to obtain a real 2^{-32} as a real constant. The corresponding code is included on the main page.

(2002/Jan.8th added) Isaku Wada gave a nice comment on this. For [0,1], replace the last return with
return y*(1.0/4294967295.0); /* reals */
and for [0,1), replace the last return with
return y*(1.0/4294967296.0); /* reals: [0,1)-interval */ 
Since most compilers compute the constant when it is compiled, so this code runs with the same speed with the standard C codes, and portability and readability are better.

3.2 Need more than 32 bits accuracy. #

Concatenate two successive 32-bit integers to get a 64-bit integer.

Isaku Wada again gave us a good comment. Using integer version's genrand() twice as follows:
double random(void) 
{ 
unsigned long a=genrand()>>5, b=genrand()>>6; 
return(a*67108864.0+b)*(1.0/9007199254740992.0); 
} 
This gives a uniform randomnumber in [0,1) with 53-bit precision.

3.3 To use as a random source for encryption. #

The sequence is, as it is, not cryptographically secure. However, if you use an appropriate Secure Hashing Algorithm (non-invertible function compressing several words into one word), then you may use them. To be precise, in the existing encryption methods with a linear pseudorandom generator (like GFSR), to replace the generator with the large period MT is valid. In this case, you may need more than 2^32-1 initial seeds. The initializing routine sgenrand(seed) of MT is a mere linear-congruential generator. If you do not use sgenrand, then the actual initial seed consist of the 19937 bits = the 19968 bits of the array mt0..623 minus the lower 31 bits of mt[0]. Help: we are not experts in this area. Please let us know appropriate references and knowledges on cryptographically secure generators.

3.4 Want a uniform discrete distribution among the integers 0..N-1, e.g. a dice in the case of N=6. #

If the application is not sensitive to the rounding off error, then please multiply N to [0,1)-real uniform random numbers and take the integer part (this is sufficient for most applications). Caution: never use [0,1]-real version. If one does, then a hard-to-find bug creeps in that 0xffffffff occurs once in about 4.2 billion generations hence returns N. (Isaku Wada pointed out, added on 2002/Jan.8th.) In the very rare case that the rounding off error of real numbers does matter, then generate random integers, take the minimum integer with N<=2^n, take the most significant n bits and discard the numbers greater than or equal to N.

3.5 A seed of 32-bit is too small. We want a larger space for initial seeds. #

Seed space of 622 words of 32-bit integers is available. For example, in mt19937.c, there is an array named mt[N]. Read the code of sgenrand(), then you will find that the seed word is passed to mt[0], and then mt[1], mt[2], ... are filled by a random number generator. You may put the value 0xffffffff to mt[0], and use all the rest mt[1]...mtN-1 as 622 words' seed space. Every initial value is safe. Some versions of mt implements the array in a converse way, so carefully read the code if you use other versions.


EditText | FindPage | DeletePage | LikePages

Powered by MoniWiki
xhtml1 | css2 | any browser | rss
Last modified 2004-02-26 03:56:44
Loading 0.3171 sec