(算法)关于随机数的生成

题目:

1、一个函数fun()均匀返回0和1,各自的概率是50%,利用这个函数实现一个函数,使之返回 1的概率为3/4,0的概率为1/4。

2、假如有一个函数rand5能等概率生成1 - 5 之间的整数,如何利用rand5来实现rand7?rand7函数的要求是能够等概率生成1 - 7之间的整数。

思路:

  • C++的随机函数rand()和srand():

  所在的头文件:<stdlib.h>

  函数一:int   rand(void); 
      从srand   (seed)中指定的seed开始,返回一个[seed,   RAND_MAX(0x7fff))间的随机整数。 

  函数二:void   srand(unsigned   seed); 
      参数seed是rand()的种子,用来初始化rand()的起始值。 

  如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间), srand((unsigned) time(NULL)); 

  • 题目1:

  思路有很多,

  例如fun()+fun(),0,1相加可以得到3个值,0+0=0;0+1=1;1+0=1;1+1=2,以0为界分成两类,等于0为0,大于0为1,则新生成0的概率为1/4,新生成1的概率为3/4;

  例如fun()*fun(),0,1相乘可以得到2个值,0*0=0;0*1=0;1*0=0;1*1=1,同样分成两类,等于0为1,等于1为0,则新生成0的概率为1/4,新生成1的概率为3/4;

  还有其他方法,例如pow(fun(),fun()),fun()-fun()等等,只要能找到1:3的一个分界即可。

  • 题目2:

  第二题不能直接通过rand5()基本运算得到1-7的一个均匀分布,例如rand5()+rand5()得不到1-10之间的均匀分布。生成6(2+4,4+2,3+3)的概率大于生成1(0+1,1+0)的概率。

  既然不能通过运算得到结果,我们可以构造一个更大的数据范围,例如7的倍数。如何构造呢?通过两个rand5()来生成两个独立分布,独立意味着不重复,可以很容易想到通过(rand5()-1)*5和rand5()-1来生成两个独立均匀分布,第一个生成0,5,10,15,20的均匀分布,第二个生成0,1,2,3,4的均匀分布,将两者相加,即(rand5()-1)*5+rand5()-1就可以得到0-24的一个均匀分布,取7的倍数个数,例如21个,即0-20,再加上1就得到1-21的均匀分布,进而%7就得到rand7()。

  切记不能通过rand5()*6-6来做,因为我们需要的是两个独立的分布。

  还有一个方法,从二进制的角度来思考,生成1-7的均匀分布,在二进制中,只需三位,如果每一位0,1的生成也是均匀的话(通过rand5()可以得到),那么就可以得到0-7的均匀分布,生成0时不予考虑即可以得到1-7的均匀分布,具体参考代码。

代码:

题目1:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int fun(){
    return rand()%2;
}

int fun2(){
    int i=fun()+fun();
    if(i>0)
        return 1;
    else
        return 0;
}
/*
int fun2(){
    int i=fun()*fun();
    if(i==0)
        return 1;
    else
        return 0;
}
*/
int main()
{
    int sum_1=0;
    int sum_0=0;
    srand((unsigned)time(0));
    for(long long i=0;i<999999;i++){
        if(fun2()==1)
            sum_1++;
        else
            sum_0++;
    }
    cout<<sum_1<<":"<<sum_0<<endl;
    cout<<(float)sum_1/sum_0<<endl;
    return 0;
}

  

题目2:

#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int rand5(){
    return rand()%5+1;
}

// generate 0,1
int rand01(){
    int i=rand5();
    if(i>4)
        return rand01();
    return i%2;
}

int rand7_1(){
    int i;
    while(true){
        // generate 0-24
        i=(rand5()-1)*5+rand5()-1;
        if(i<21)
            return i%7+1;
    }
}

int rand7_2(){
    int i;
    // generate 0-7
    i=(rand01()<<2)+(rand01()<<1)+rand01();
    if(i==0)
        i=rand7_2();
    return i;
}

int main()
{
    srand((unsigned)time(0));
    int A[7]={0,0,0,0,0,0,0};
    int B[7]={0,0,0,0,0,0,0};
    for(long long i=0;i<99999999;i++){
        A[rand7_1()-1]++;
        B[rand7_2()-1]++;
    }
    for(int i=0;i<7;i++)
        cout<<A[i]<<" ";
    cout<<endl;
    for(int i=0;i<7;i++)
        cout<<B[i]<<" ";
    cout<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/AndyJee/p/4600431.html