Advertisement
Guest User

MersenneTwister Algorithm

a guest
Sep 19th, 2015
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.28 KB | None | 0 0
  1. public class MersenneTwister : Random
  2.     {
  3.         private const int N = 624;
  4.         private const int M = 397;
  5.         private const uint MatrixA = 0x9908b0df;
  6.         private const uint UpperMask = 0x80000000;
  7.         private const uint LowerMask = 0x7fffffff;
  8.         private const uint TemperingMaskB = 0x9d2c5680;
  9.         private const uint TemperingMaskC = 0xefc60000;
  10.  
  11.         private static uint TEMPERING_SHIFT_U(uint y)
  12.         {
  13.             return (y >> 11);
  14.         }
  15.  
  16.         private static uint TEMPERING_SHIFT_S(uint y)
  17.         {
  18.             return (y << 7);
  19.         }
  20.  
  21.         private static uint TEMPERING_SHIFT_T(uint y)
  22.         {
  23.             return (y << 15);
  24.         }
  25.  
  26.         private static uint TEMPERING_SHIFT_L(uint y)
  27.         {
  28.             return (y >> 18);
  29.         }
  30.         private readonly uint[] _mt = new uint[N];
  31.         private short _mti;
  32.         private static readonly uint[] _mag01 = { 0x0, MatrixA };
  33.         public MersenneTwister(uint seed)
  34.         {
  35.             _mt[0] = seed & 0xffffffffU;
  36.             for (_mti = 1; _mti < N; ++_mti)
  37.             {
  38.                 _mt[_mti] = (69069 * _mt[_mti - 1]) & 0xffffffffU;
  39.             }
  40.         }
  41.         public MersenneTwister()
  42.             : this(4357)
  43.         {
  44.         }
  45.  
  46.         protected uint GenerateUInt()
  47.         {
  48.             uint y;
  49.             if (_mti >= N)
  50.             {
  51.                 short kk = 0;
  52.  
  53.                 for (; kk < N - M; ++kk)
  54.                 {
  55.                     y = (_mt[kk] & UpperMask) | (_mt[kk + 1] & LowerMask);
  56.                     _mt[kk] = _mt[kk + M] ^ (y >> 1) ^ _mag01[y & 0x1];
  57.                 }
  58.  
  59.                 for (; kk < N - 1; ++kk)
  60.                 {
  61.                     y = (_mt[kk] & UpperMask) | (_mt[kk + 1] & LowerMask);
  62.                     _mt[kk] = _mt[kk + (M - N)] ^ (y >> 1) ^ _mag01[y & 0x1];
  63.                 }
  64.  
  65.                 y = (_mt[N - 1] & UpperMask) | (_mt[0] & LowerMask);
  66.                 _mt[N - 1] = _mt[M - 1] ^ (y >> 1) ^ _mag01[y & 0x1];
  67.  
  68.                 _mti = 0;
  69.             }
  70.             y = _mt[_mti++];
  71.             y ^= TEMPERING_SHIFT_U(y);
  72.             y ^= TEMPERING_SHIFT_S(y) & TemperingMaskB;
  73.             y ^= TEMPERING_SHIFT_T(y) & TemperingMaskC;
  74.             y ^= TEMPERING_SHIFT_L(y);
  75.             return y;
  76.         }
  77.  
  78.         public virtual uint NextUInt()
  79.         {
  80.             return this.GenerateUInt();
  81.         }
  82.  
  83.         public virtual uint NextUInt(uint maxValue)
  84.         {
  85.             return (uint)(this.GenerateUInt() / ((double)uint.MaxValue / maxValue));
  86.         }
  87.  
  88.         public virtual uint NextUInt(uint minValue, uint maxValue)
  89.         {
  90.             if (minValue >= maxValue)
  91.             {
  92.                 throw new ArgumentOutOfRangeException();
  93.             }
  94.  
  95.             return (uint)(this.GenerateUInt() / ((double)uint.MaxValue / (maxValue - minValue)) + minValue);
  96.         }
  97.  
  98.         public override int Next()
  99.         {
  100.             return this.Next(int.MaxValue);
  101.         }
  102.  
  103.         public override int Next(int maxValue)
  104.         {
  105.             if (maxValue <= 1)
  106.             {
  107.                 if (maxValue < 0)
  108.                 {
  109.                     throw new ArgumentOutOfRangeException();
  110.                 }
  111.                 return 0;
  112.             }
  113.             return (int)(this.NextDouble() * maxValue);
  114.         }
  115.  
  116.         public override int Next(int minValue, int maxValue)
  117.         {
  118.             if (maxValue < minValue)
  119.             {
  120.                 throw new ArgumentOutOfRangeException();
  121.             }
  122.             else if (maxValue == minValue)
  123.             {
  124.                 return minValue;
  125.             }
  126.             else
  127.             {
  128.                 return this.Next(maxValue - minValue) + minValue;
  129.             }
  130.         }
  131.  
  132.         public override void NextBytes(byte[] buffer)
  133.         {
  134.             int bufLen = buffer.Length;
  135.             if (buffer == null)
  136.             {
  137.                 throw new ArgumentNullException();
  138.             }
  139.             for (int idx = 0; idx < bufLen; ++idx)
  140.             {
  141.                 buffer[idx] = (byte)this.Next(256);
  142.             }
  143.         }
  144.  
  145.         public override double NextDouble()
  146.         {
  147.             return (double)this.GenerateUInt() / ((ulong)uint.MaxValue + 1);
  148.         }
  149.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement