离散ziggurat算法python实现_SLAM的数学基础(3):⼏种
常见的概率分布的实。。。
分布,在计算机学科⾥⼀般是指概率分布,是概率论的基本概念之⼀。分布反映的是随机或某个系统中的某个变量,它的取值的范围和规律。
常见的分布有:⼆项分布、泊松分布、正态分布、指数分布等,下⾯对它们进⾏⼀⼀介绍。
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<<:endl>
std::cout<< "Total:" << sum_of_times <<:endl>
}
结果为:
323,1199,2310,2631,1951,1103,367,97,18,1,
Total: 10000
拿到Python⾥⾯⽤图表看⼀下:
importnumpy as npfrom scipy importstatsimportmatplotlib.pyplot as pltdefshow_binom_rvs(): n= np.array([323,1199,2310,2631,1951,1103,367,97,18,1])
plt.plot(n)
plt.show()
show_binom_rvs()
显⽰为:
我们再来⽤Python的numpy和scipy的库来验证⼀下:
importnumpy as npfrom scipy importstatsimportmatplotlib.pyplot as pltdefcalc_binom_rvs(): binom_rvs= stats.binom.rvs(n=10,p=0.3,size=10000)
plt.hist(binom_rvs, bins=10)
plt.show()
calc_binom_rvs()
得到结果图⽚:
可以看到两次的图形包络是近似的。
泊松分布
在⽇常⽣活中,我们经常会遇到⼀些事情,这些事情发⽣的频率⽐较固定,但是发⽣的时间是不固定的,泊松分布就是⽤来描述单位时间内随机事件的发⽣概率。⽐如:知道⼀个医院平均每⼩时有3个⼩孩出⽣,那么下⼀个⼩时出⽣2个⼩孩的概率是多少?
泊松分布的PMF可以写作:
其中,t为连续时间长度,k为事件发⽣的次数,λ为发⽣事件的数学期望(如单位时间内发⽣事件的均值),e为⾃然底数。
就上⾯的例⼦,知道⼀个医院平均每⼩时有3个⼩孩出⽣,那么下⼀个⼩时出⽣2个⼩孩的概率是多少?⽤C++实现:
#include #include#include
double calc_poisson(int k, intlambda)
{doubleresult;
result= pow(lambda, k) * exp(-lambda);int factorial = 1;for(int i = 1; i <= k; i++)
{
factorial*=i;
}result= result /factorial;returnresult;
}intmain()
{
std::cout<< std::fixed << std::setprecision(8) << calc_poisson(2, 3) <<:endl>
}
结果是:0.22404181
⽤Python验证:
importnumpy as npfrom scipy importstatsimportmatplotlib.pyplot as pltdefcalc_poisson(): lambd= 3k= 2y=stats.poisson.pmf(k,lambd)printy
calc_poisson()
结果是:0.224041807655
下⾯再⽤C++实现⽣成泊松随机数,并⽤Python检验:
C++实现:
#include
#include
#include
#include
#include
#include
double binary_random()
{
double rand_number = (rand() % 100);
rand_number /= 100;
return rand_number;
}
int calc_poisson(int lambda)
{
int k = 0;
python生成1到100之间随机数
double p = 1.0;
double l = exp(-lambda);
while(p >= l)
{
double r = binary_random();
p *= r;
k++;
}
return (k - 1);
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。