百日算法-随机数概率推移

120 阅读1分钟

百日算法-随机数概率推移

有这样一个题目,给定的 函数 F(x) 中的数列 15 是等概率的,要求不得使用其他随机处理函数,利用 F(x) 使得数列 07 也是等概率的。

对于这样的问题,我们需要想办法,构建一个 0,1 的等概率的发生器。通过该发生器,就可以拼出一个等概率的任意数列。

首先我们需要验证,我们上面的这个猜想,获取的随机数 0,1 的概率都是相同的,各占一半,概率应该是 1/2。

🚂 代码示例:

基本实现就是,先根据之前的 0 ~ 1 的等概率随机数,获取 1 ~ 5 的等概率随机数,然后调用循环只暴露非3 的数,并根据等比例的条件返回,就得到了 等概率的 0 与 1

#include <iostream>
#include "random/countRandom.h"
#include "random/RandomNumberToFunction.h"
#include "probability/SeriesToProbability.h"
​
using namespace std;
​
int main() {
​
    SeriesToProbability seriesToProbability;
    int count = 0;
    for (int i = 0; i < 1000000; ++i) {
        if (seriesToProbability.getProbability() == 0)
            count++;
    }
    cout << "概率= " << (double) count / 1000000 << endl;
}
/**
* @author peggy
* @data 2023/2/16 22:35
*///
// Created by peggy on 2023/2/16.
//#include "SeriesToProbability.h"/**
 * 1-5 的等概率 求出 1-7 的等概率返回
 * @param attay
 * @param legth
 */
int SeriesToProbability::getProbability() {
    int num;
    do {
        //直到当前获取的随机数不是三的时候跳出,否则继续循环,调用 getNumber() 方法获取随机数
        num = getNumber();
    } while (num == 3);
    return num < 3 ? 0 : 1;
}
/**
 * 获取 1-5 的等概率的数
 * @return 
 */
int SeriesToProbability::getNumber() {
​
    return (int) (randomNumber.getMyRumber() * 5) + 1;
}

输出的结果

概率= 0.499987

Process finished with exit code 0

好!有了上面的等概率的基础,那么我们就可以得到,任何范围内的等概率数了,具体的实现步骤如下图所示。

✈️ 如下图所示

🛁 代码案例:

#include <iostream>
#include "random/countRandom.h"
#include "random/RandomNumberToFunction.h"
#include "probability/SeriesToProbability.h"
​
using namespace std;
​
int main() {
​
    SeriesToProbability seriesToProbability;
​
    //初始化一个统计的每个数出现的次数数组
    int arry[8] = {0, 0, 0, 0, 0, 0, 0, 0};
​
    for (int i = 0; i < 1000000; i++) {
        //将每一个数出现一次,次数 +1
        arry[seriesToProbability.getBINToDEC()]++;
    }
    for (int i = 0; i < 8; ++i) {
        //最终的概率
        cout << "arry[" << i << "]=" << (double) arry[i] / 1000000 << endl;
    }
}
/**
* @author peggy
* @data 2023/2/16 22:35
*///
// Created by peggy on 2023/2/16.
//#include "SeriesToProbability.h"/**
 * 1-5 的等概率 求出 1-7 的等概率返回
 * @param attay
 * @param legth
 */
int SeriesToProbability::getProbability() {
    int num;
    do {
        //直到当前获取的随机数不是三的时候跳出,否则继续循环,调用 getNumber() 方法获取随机数
        num = getNumber();
    } while (num == 3);
    return num < 3 ? 0 : 1;
}
/**
 * 获取 1-5 的等概率的数
 * @return
 */
int SeriesToProbability::getNumber() {
​
    return (int) (randomNumber.getMyRumber() * 5) + 1;
}
/**
 * 将获取的二进制位进行右移,转化为一个整数并返回
 * @return
 */
int SeriesToProbability::getBINToDEC() {
    return (this->getProbability()<<2)+(this->getProbability()<<1)+(this->getProbability()<<0);
}

🏳️‍🌈 输出结果:

arry[0]=0.12496 arry[1]=0.124628 arry[2]=0.124925 arry[3]=0.125301 arry[4]=0.124866 arry[5]=0.125361 arry[6]=0.124823 arry[7]=0.125136

Process finished with exit code 0

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天