boost库随机函数中的bug

来源:互联网 发布:ubuntu 14.04 启动器 编辑:程序博客网 时间:2024/05/19 09:11
boost库随机函数中的bug

最近几天用到随机数比较多,网上搜索发现boost库中有很多很好用的库函数,于是就下载,安装配置了。
以下是原始的生成随机数的程序:
/* parent process*/#include <iostream>#include <fstream>#include <algorithm>#include <stdlib.h>#include <stdio.h>#include <string>#include <boost/random.hpp>#include <boost/random/uniform_int.hpp>#include <boost/random/cauchy_distribution.hpp>#include <boost/random/normal_distribution.hpp>#include <boost/random/uniform_real.hpp>#include <string.h>using namespace std;void Rand_Select_Particle( int base, int *result, double *real, int num, int population_size ){    boost::mt19937 gen(time(0));    boost::uniform_int<> unif_int( 0, population_size-1 );    boost::variate_generator< boost::mt19937&, boost::uniform_int<> > unif_dist_int( gen, unif_int );    boost::uniform_real<> unif_real( 0, population_size-1 );    boost::variate_generator< boost::mt19937&, boost::uniform_real<> > unif_dist_real( gen, unif_real );    int i, temp,j;    int *temp_res = new int[num+1];    temp_res[0] = base;    bool flag = true;    for( i = 0; i < num; ++i )    {        real[i] = unif_dist_real();        while(1)        {            temp = unif_dist_int();            flag = true;            for( j = 0; j < i+1; ++j)            {                if( temp == temp_res[j] )                {                    flag = false;                    break;                }            }            if( flag )            {                temp_res[i+1]=result[i] = temp;                break;            }        }    }    delete []temp_res;}int main(int argc, char *argv[]){    int *result = new int [3];    double *real = new double[3];    for( int i = 0; i < 10; ++i )    {        Rand_Select_Particle(i, result, real, 3, 10 );        cout<<result[0]<<"\t"<<result[1]<<"\t"<<result[2]<<endl;        cout<<real[0]<<"\t"<<real[1]<<"\t"<<real[2]<<endl;    }    delete []result;    delete []real;    return 0;}
运行上面的程序,得到的结果如下图:

很奇怪的是,每次循环下来,无论是随机整数,还是随机浮点数,得到的结果都是相同的。分析原因是:随机生成器generator初始化:
boost::mt19937 gen(time(0))
用的是time()函数,而time函数得到的是当前的系统时间,是以秒为单位的,因此当程序运行时间很短时,没有达到0.5秒的话,time函数得到的值是不变的,因而也导致了generator没变,从而导致生成的随机数不变。所以提醒各位用boost随机库的童鞋,boost的随机函数有时候表现的并不是我们所想的。对于大程序而言,boost库是比较可靠的,对于小程序,boost表现并不一定好。因此,大家要慎重选择。
这里给大家提供一个解决方案:就是在time函数上乘上一个随机数,这个随机数利用系统的随机函数库生成,代码如下:
/* parent process*/#include <iostream>#include <fstream>#include <algorithm>#include <stdlib.h>#include <stdio.h>#include <string>#include <boost/random.hpp>#include <boost/random/uniform_int.hpp>#include <boost/random/cauchy_distribution.hpp>#include <boost/random/normal_distribution.hpp>#include <boost/random/uniform_real.hpp>#include <string.h>using namespace std;void Rand_Select_Particle( int base, int *result, double *real, int num, int population_size ){    boost::mt19937 gen(time(0)*rand());    boost::uniform_int<> unif_int( 0, population_size-1 );    boost::variate_generator< boost::mt19937&, boost::uniform_int<> > unif_dist_int( gen, unif_int );    boost::uniform_real<> unif_real( 0, population_size-1 );    boost::variate_generator< boost::mt19937&, boost::uniform_real<> > unif_dist_real( gen, unif_real );    int i, temp,j;    int *temp_res = new int[num+1];    temp_res[0] = base;    bool flag = true;    for( i = 0; i < num; ++i )    {        real[i] = unif_dist_real();        while(1)        {            temp = unif_dist_int();            flag = true;            for( j = 0; j < i+1; ++j)            {                if( temp == temp_res[j] )                {                    flag = false;                    break;                }            }            if( flag )            {                temp_res[i+1]=result[i] = temp;                break;            }        }    }    delete []temp_res;}int main(int argc, char *argv[]){    int *result = new int [3];    double *real = new double[3];    for( int i = 0; i < 10; ++i )    {        Rand_Select_Particle(i, result, real, 3, 10 );        cout<<result[0]<<"\t"<<result[1]<<"\t"<<result[2]<<endl;        cout<<real[0]<<"\t"<<real[1]<<"\t"<<real[2]<<endl;    }    delete []result;    delete []real;    return 0;}


利用以上程序,得到的结果如图


这样得到的随机数才是真正的随机数。
0 0