JAVA梅森旋转随机算法_梅森旋转算法

概念

梅森旋转算法(Mersenne twister),可以快速产生高质量的伪随机数,修正了古典随机数发生算法的很多缺陷。

常见的两种为基于32位的 MT19937和基于64位的 MT19937-64。

由于梅森旋转算法是利用线性反馈移位寄存器(LFSR)产生随机数的,

对于LFRS有结论:一个 $k$ 位的移位寄存器,选取合适的特征多项式(即加1为本原多项式)时,取得最大周期 $2^k-1$.

而MT19937梅森旋转算法的周期为 $2^{19937}-1$(正如算法名,这是一个梅森素数),说明它是一个19937级的线性反馈移位寄存器,梅森旋转算法是利用线性反馈寄存器一直进行移位旋转,因此实际上 MT19937-32只需要用32位就能做到。它能做到在 $1 \leq k\leq 623$ 都可以均匀分布。

注:梅森素数:如果形如 $2^n-1$ 的数是一个素数,则称之为梅森素数。

算法步骤

整个算法主要分为三个阶段:

第一阶段:获得基础的梅森旋转链;

第二阶段:对于旋转链进行旋转算法;

第三阶段:对于旋转算法所得的结果进行处理;

算法实现的过程中,参数的选取取决于梅森素数,故此得名。

实现

使用MT19937算法生成范围在 $[2^{32}-1]$ 的均匀分布的32位整数。

#include #include#include#include

using namespacestd;boolisInit;intindex;

unsignedint MT[624]; //624 * 32 - 31 = 19937

void srand(intseed)

{

printf("seed:%d\n", seed);

index= 0;

isInit= 1;

MT[0] =seed;//对数组的其它元素进行初始化

for(int i = 1; i < 624; i++)

{

unsignedint t = 1812433253 * (MT[i - 1] ^ (MT[i - 1] >> 30)) +i;

MT[i]= t & 0xffffffff; //取最后的32位赋给MT[i]

}

}voidgenerate()

{for(int i = 0; i < 624; i++)

{//2^31 = 0x80000000//2^31-1 = 0x7fffffff

unsigned int y = (MT[i] & 0x80000000) + (MT[(i + 1) % 624] & 0x7fffffff);

MT[i]= MT[(i + 397) % 624] ^ (y >> 1);if (y & 1)

MT[i]^= 2567483615;

}

}

unsignedintRand()

{if(!isInit)

srand((int)time(NULL));if(index == 0)

generate();

unsignedint y =MT[index];

y= y ^ (y >> 11); //y右移11个bit

y = y ^ ((y << 7) & 2636928640); //y左移7个bit与2636928640相与,再与y进行异或

y = y ^ ((y << 15) & 4022730752); //y左移15个bit与4022730752相与,再与y进行异或

y = y ^ (y >> 18); //y右移18个bit再与y进行异或

index = (index + 1) % 624;returny;

}

intmain()

{int cnt = 0;for(int i = 0; i < 1000000; i++)

{if(Rand() & 1) cnt++;

}

cout<

}

应用

梅森旋转算法是R、Python、Ruby等的默认伪随机数产生器。从C++11开始,C++也可以使用这个算法。

例如C++11中:

#include #include

using namespacestd;intmain()

{

random_device rd;//可视为真随机数,但Windows下调用的rand_s就不是了

mt19937 mt(rd());for(int i = 0; i < 10; i++)

cout<< mt() <

}

参考链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值