• C++生成随机数—生成任意范围内的等概率随机数方法


    原文:

    http://www.pc6.com/infoview/Article_50245.html

    http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html

    http://www.verydemo.com/demo_c92_i78997.html

     

     

    rand()函数返回0到RAND_MAX之间的伪随机数(pseudorandom)。RAND_MAX常量被定义在stdlib.h头文件中。其值等于32767,或者更大。 

    srand()函数使用自变量n作为种子,用来初始化随机数产生器。只要把相同的种子传入srand(),然后调用rand()时,就会产生相同的随机数序列。因此,我们可以把时间作为srand()函数的种子,就可以避免重复的发生。如果,调用rand()之前没有先调用srand(),就和事先调用srand(1)所产生的结果一样。

    产生随机数的用法 
    1) 给srand()提供一个种子,它是一个unsigned int类型; 
    2) 调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到RAND_MAX之间); 
    3) 根据需要多次调用rand(),从而不间断地得到新的随机数; 
    4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。

    0~RAND_MAX之间的随机数程序

    #include <iostream> 
    #include <stdlib.h> 
    #include <time.h>  
    using namespace std;  
    int main() 
    {  
    srand((unsigned)time(NULL));  
    for(int i = 0; i < 10;i++ )  
            cout << rand() << ' ';  
    cout << endl;  
    return 0; 
    }

    产生一定范围随机数的通用表示公式 
    要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 
    要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 
    要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 
    通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 
    要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。 
    要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。 

    BUT

    ————————————————————————————————————————————————

    假如你想用C++来生成0——N-1之间的随机数,你会怎么做?你可能会说,很简单,看:

    srand( (unsigned)time( NULL ) );
    rand() % N;

    仔细想一下,这个结果是随机的吗(当然,我们不考虑rand()函数的伪随机性)?

    不是的,因为rand()的上限是RAND_MAX,而一般情况下,RAND_MAX并不是N的整数倍,那么如果RAND_MAX % = r,则0——r之间的数值的概率就要大一些,而r+1——N-1之间的数值的概率就要小一些。还有,如果N > RAND_MAX,那该怎么办?

    一种非常简单的方式,那就是使用

    random_shuffle( RandomAccessIterator _First, RandomAccessIterator _Last ).

    例如,生成0——N-1之间的随机数,可以这么写

    #include 
    #include

    long myrandom( long N )
    {
          std::vector vl( N ); // 定义一个大小为N的vector
           for ( long i=0; i
           {
                   vl[i] = i;
           }

           std::random_shuffle( vl.begin(), vl.end() );

           return (*vl.begin());
    }

    random_shuffle 还有一个三参数的重载版本

    random_shuffle( RandomAccessIterator _First, RandomAccessIterator _Last, RandomNumberGenerator& _Rand )

    第三个参数可以接受一个自定义的随机数生成器来把前两个参数之间的元素随机化。

    这个方法的缺陷就是,如果只是需要一个随机数的话,当N很大时,空间消耗很大!

     
     
    ——————————————————————————————————————
     
     

    ------解决方案--------------------------------------------------------
    取10到20间的随机数应该这样写
    a[i]= 10+ (rand()% 11);

    一般的如果你希望取得 a到b之间(b>a,包含a和b)的随机数,
    可这样写:
     a[i]= a + (rand()% (b-a+1)); 
    ------解决方案--------------------------------------------------------
    假如0..9共10个元素随机划分为0..2共3块:
    第0块,从0..10-3随机选出比如5,即0..5归第0块
    第1块,从5+1..10-2随机选出比如7,即6,7归第1块
    第2块,从7+1..10-1,即8,9归第2块。

    现在有一个问题是,如果 N 大于RAND_MAX,应该怎么处理?

    这里N=135534747, 需要划分为10个片段,应该怎么随机划分?

     https://www.zhihu.com/question/24297923

    使用C++11 最好的解决方案。

  • 相关阅读:
    3D Computer Grapihcs Using OpenGL
    转:认识MyBean
    转:MyBean的安装
    转:MyBean简介
    Delphi常用关键字用法详解
    红鱼儿
    uniGUI-shuiying
    转:RTC搭建android下三层应用程序访问服务器MsSql-客户端
    转:RTC搭建android下三层应用程序访问服务器MsSql-服务器端
    转(Delphi 新窑洞):使用delphi 开发多层应用(十七)使用RTC web 服务器返回JSON
  • 原文地址:https://www.cnblogs.com/xingzifei/p/6635340.html
Copyright © 2020-2023  润新知