分布,在计算机学科里一般是指概率分布,是概率论的基本概念之一。分布反映的是随机或某个系统中的某个变量,它的取值的范围和规律。
常见的分布有:二项分布、泊松分布、正态分布、指数分布等,下面对它们进行一一介绍。
PS:本文中谈到的PDF、PMF、CDF均为公认的缩写方式:
PDF:概率密度函数(probability density function);
PMF:概率质量函数(probability mass function);
CDF:累积分布函数(cumulative distribution function)。
二项分布
说起二项分布,离不开伯努利实验,二项分布就是重复N次的伯努利实验(伯努利实验,是指一种只有两种相反结果的随机试验,比如抛硬币,结果只有正面和反面;又比如投篮,只有投中和没有投中两种结果)。它的PMF可写作:
其中k为在n次实验中命中的次数,成功的概率为p。
二项分布的CDF可以写作:
例子:抛10次硬币,有2次正面朝上的概率是多少?下面分别用C++实现和用numpy证明结果
C++实现:
#include #include#include
double calc_binomial(int n, int k, doublep)
{if(n < 0 || k < 0)return 0.0;
std::vector< std::vector< double > > binomials((n + 1), std::vector< double >(k + 1));
binomials[0][0] = 1.0;for(int i = 1; i < (n + 1); ++i)
binomials[i][0] = (1.0 - p) * binomials[i - 1][0];for(int j = 1; j < (k + 1); ++j)
binomials[0][j] = 0.0;for(int i = 1; i < (n + 1); ++i)for (int j = 1; j < (k + 1); ++j)
binomials[i][j]= (1.0 - p) * binomials[i - 1][j] + p * binomials[i - 1][j - 1];returnbinomials[n][k];
}intmain()
{
std::cout<< std::fixed << std::setprecision(8) << calc_binomial(10, 2, 0.50) <<:endl>
}
结果为:0.04394531
Python实现:
importnumpy as npfrom scipy importstatsimportmatplotlib.pyplot as pltdefcalc_binomial():
n= 10p= 0.5k= 2binomial=stats.binom.pmf(k,n,p)printbinomial
calc_binomial()
结果为:0.0439453125
反之,知道投10次硬币朝上的平均概率为0.3(即平均有3次朝上),试着从10000次实验中找出规律。
用C++实现:
#include #include#include#include#include#include
int gen_binomial_rand(int n, doublep)
{int k = 0;for(int i = 0; i < n; i++)
{double current_probability = ((double)rand() / (double)RAND_MAX);if(current_probability
{
k++;
}
}returnk;
}intmain()
{
srand((unsigned)time(NULL));int gn = 10;double gp = 0.3;int times = 10000;int sum_of_times = 0;
std::vector< int >result(gn);for(int t = 0; t < times; t++)
{int single_result =gen_binomial_rand(gn, gp);if(single_result
{
result[single_result]++;
}
}
std::cout<<:endl i="0;" gn>
{
sum_of_times+=result[i];
std::cout<< result[i] << ",";
}
std::cout<