码迷,mamicode.com
首页 > 其他好文 > 详细

关于随机数分布器的问题

时间:2014-11-11 22:40:48      阅读:351      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   使用   sp   for   div   on   

今天看C++Primer介绍的随机数,准备使用一下,结果出现点小问题,就是每次运行程序获得的首个随机数都是一样的。

(已使用time作为随机数种子,按理说应该至少每秒产生的随机数都是不一样的)

int main()
{
    default_random_engine e(time(0));
    uniform_int_distribution<unsigned> u(0,99);
    cout<<u(e)<<endl;
    
}

如果直接输出e()那么会产生0-2147483646之间的随机数,程序每次运行,至少每秒运行产生的随机数都不一样。

但是用了分布器之后,u(e)输出的第一个值总是一样的。通过手动传入种子,可以知道相近的种子产生的第一个随机值

也是相近的,那分布器到底对原始值做了怎样的压缩呢?

int main()
{
    default_random_engine e;
    uniform_int_distribution<unsigned> u(0,99);
    for(size_t i = 0; i < 100000; ++i)
    {
        e.seed(i);
        if(u(e) != 0)
        {
            cout<<i<<endl;
            break;
        }
    }

    cout<<"0-9:"<<12778.0/60.0<<endl;
    cout<<"0-99:"<<1278.0/60.0<<endl;
    cout<<"0-999:"<<128.0/60.0<<endl;
}

程序输出i的值为1278,也就是说种子0-1277产生的随机数经过u(0,99)压缩后得到的都是0,呃,那么也就是说

如果用time(0)作为种子,产生0-99之间的随机数,可能程序最多在1277秒内产生的第一个随机值都是一样的。

如果程序运行一次,关掉,再运行一次,结果却一样。。。

其它测试:0-9 12777秒; 0-999 127秒

这应该是生成器算法的问题吧,相近的种子产生相近的随机值,分布器对一定范围的随机值压缩成一个值。。。

结果就是一段时间内的首个随机值都一样。。。真杯具

解决办法,丢掉第一个值,呃。那么换个生成器试试

int main()
{
    mt19937 e(time(0));
    uniform_int_distribution<unsigned> u(0,99);
    cout<<u(e);
}

这次的结果还算可以接受,每次都不一样了,搜了一下mt19937的介绍,结果msdn上有

typedef mersenne_twister_engine<unsigned int, 32, 624, 397,
    31, 0x9908b0df,
    11, 0xffffffff,
    7, 0x9d2c5680,
    15, 0xefc60000,
    18, 1812433253> mt19937;


typedef mersenne_twister_engine<unsigned long long, 64, 312, 156,
    31, 0xb5026f5aa96619e9ULL,
    29, 0x5555555555555555ULL,
    17, 0x71d67fffeda60000ULL,
    37, 0xfff7eee000000000ULL,
    43, 6364136223846793005ULL> mt19937_64;

噢,原来是梅森螺旋算法啊~,当时想用的时候不知道尖括号里都该填什么,这下有两个现成的可用了。

 

关于随机数分布器的问题

标签:style   blog   io   color   使用   sp   for   div   on   

原文地址:http://www.cnblogs.com/eaxebx/p/4090565.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!