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

题目:

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;
}
时间: 2024-10-14 06:24:31

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

机器学习算法中随机数的生成

numpy,sklearn提供随机数据生成功能,我们可以自己生成适合某一种模型的数据,用随机数据来清洗,归一化,转换,然后选择模型与算法做拟合和预测. 1.numpy随机数据生成API numpy比较适合用来生产一些简单的抽样数据.API都在random类中,常见的API有: (1).rand(d0, d1, ...,dn)用来生成d0xd1x...dn维的数组.数组的值在[0, 1]之间. (2).randn(d0, d1, ...,dn),也是用来生成d0xd1x...dn维的数组.不过数组

JavaScript算法题之–随机数的生成

JavaScript算法题之–随机数的生成 需求描述:从一组有序的数据中生成一组随机并且不重复的数,类似于简单的抽奖程序的实现. 先来生成一个有序的数组: 1 var arr = [], 2     length = 100, 3     i = 0; 4   5 for( ; i < length; i++ ){ 6     arr.push( i ); 7 } 从一个长度为 100 的有序数组中随机拿出 10 个随机的数,并且不能有重复. 方法1:随机抽取法 01 var gRandomAr

【来写个2048吧】—— 移动算法与随机数字生成

一.移动算法 其实2048的移动算法蛮简单,看代码很容易明白,就不多说了. 向左滑动 //左滑动 bool GameScene:: doLeft () { //判断有没有发生移动 bool isMove = false ; for ( int y = 0 ; y < 4; y++) { for ( int x = 0 ; x < 4; x++) { for ( int x1 = x +1 ; x1 < 4; x1++) { if ( cardArr [x1 ][ y]-> getN

浅谈随机数的生成

Part0:随机数的性质 随机数一般来说符合下面这几个性质. (马尔科夫性)\(1.\)它产生时后面那个数与前面的毫无关系. (不确定性)\(2.\)给定样本的一部分和随机算法,无法推出样本的剩余部分. (不可再现性)\(3.\)其随机样本不可重现. 另外还要说一下统计学伪随机数概念. 统计学伪随机性.统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,"10""01""00""11"四者数量大致相等

Linux真随机数的生成

今天看<白帽子讲WEB安全>一书,看到笔者谈到Linux如何实现真随机数生成,感觉非常有用,记录下来 #include<iostream> using namespace std; #include<unistd.h> #include<fcntl.h> #include<cmath> int main() { int randoms=open("/dev/random",O_RDONLY); int randomn; rea

java 随机数的生成

生成10个不小于100000的6位数 public static void main(String[] args) { Random random = new Random(); for (int i=0;i<10;i++) { System.out.println("第=="+i+"个邀请码"+(random.nextInt(899999)+100000)); } } 结果: 第==0个邀请码536686 第==1个邀请码161397 第==2个邀请码685

重复造轮子之RSA算法(一) 大素数生成

出于无聊, 打算从头实现一遍RSA算法 第一步, 大素数生成 Java的BigInteger里, 有个现成的方法 public static BigInteger probablePrime(int bitLength, Random rnd) { bitLength是期望生成的素数的二进制位数, rnd是随机数发生器 函数注释表明, 这个方法的返回值为合数的概率为2^-100 生成100个1024位的素数, 耗时13471ms 但是显然我不打算直接使用这个函数, 要做就从最底层做起! 目前的做

机器学习算法的随机数据生成

在学习机器学习算法的过程中,我们经常需要数据来验证算法,调试参数.但是找到一组十分合适某种特定算法类型的数据样本却不那么容易.还好numpy, scikit-learn都提供了随机数据生成的功能,我们可以自己生成适合某一种模型的数据,用随机数据来做清洗,归一化,转换,然后选择模型与算法做拟合和预测.下面对scikit-learn和numpy生成数据样本的方法做一个总结. 1. numpy随机数据生成API numpy比较适合用来生产一些简单的抽样数据.API都在random类中,常见的API有:

相邻不重复随机数的生成及优化

生成相邻不重复随机数是之前抽奖插件的遗留问题,在之前的文章中已经简单说过,但没有更好的解决方案.经过一个多月的修改,抽奖插件已经趋于完善,在此分享一下这个问题的解决方法.以下是最初的方法,但是会出现一个单独的全局变量,整体而言稍显多余,不算完美. // 产生相邻不重复的随机数,n 为随机数个数 var b = 0; function random(n) { var a = Math.floor(Math.random() * n); if (a == b) { return random(n);