boost库随机函数中的bug

本文介绍了在使用boost库生成随机数时遇到的问题,即由于使用`time(0)`初始化随机数生成器可能导致短时间内生成相同的随机数。通过在`time(0)`基础上乘以`rand()`,可以确保每次生成的随机数不同,从而得到真正的随机序列。作者提供了修改后的代码示例来解决这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}


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


这样得到的随机数才是真正的随机数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值