一、前情提要
其实这个方法的形成是源于《概率论与数理统计》概率定义的探究实验——抛多面体试验 — — 探索频率的统计规律性。下面以六个面为例。
二、算法实现分析
1.实验的需求分析
1)生成一组随机的概率(总合为1)代表每一个面着地的概率,由下标代表面的编号
2)据每一个面的概率模拟掷骰子并计数
2.代码实现分析
1)概率生成(宏观化)
概率在区间(0,1)又要保证总合为1,仅仅用rand()函数实现较为复杂。这里可以采用逆向思维,宏观法,先生成六个随机数,再分别将这些数除以六个数的总合,即可得每一个面的概率,储存在数组之中。
ps:rand()在 #inclulde<stdlib.h>的库中
int main(){
float prb[6]={0}; //创建每一面概率的函数,数组下标+1代表面的编号
int i=0,sum=0;
for(i=0;i<6;i++) //生成随机数,并储存
{
prb[i]=1+rand()%100;
sum+=prb[i];
}
for(i=0;i<6;i++)prb[i]/=sum;//除以总数以成概率
1.1)递归快速排序法
为了便于第二步的计算(下一步会详细说明),这里先将数组内部概率排序。这里采用了递归快速排序法(复杂度:O(nlogn))。
void QuickSort(float a[],int low,int high) //用递归法快速排序
{
int i=low ,j=high;
float temp=a[low];
while(i<j)
{
while(i<j&& temp<=a[j]) j--; //在数组的右端扫描
if(i<j)
{
a[i]=a[j];
i++;
}
while (i<j&& a[i]<=temp)i++; ///在数组的左端扫描
if(i<j)
{
a[j]=a[i];
j--;
}
}
a[i]=temp;
if(low<i)QuickSort(a,low,i-1); //对左端子集合进行递归
if(i<high)QuickSort(a,j+1,high); //对右端子集合进行递归
}
2)按概率随机生成数字
将概率的大小具象化,转化成区间的长度。在由(1)中得到的总合sum的极限长度内随机选取数字,落在的区间变是所着陆的面,用指针计数即可。
void flag(int num,float *p,float prb[]){ //判断所成的面,并计数的函数
int SUM=0;
for(int i=0;i<6;i++){
if(num<(SUM+=prb[i])){
*(p+i)+=1;
break;
}
}
}
while (t>0){ //记录每一面的次数
num=1+rand()%(sum+1);
flag(num,p,prb);
t--;
}
//以上仅为实现功能的代码,需要与上面的步骤联合才能一同运行
三、完整代码实现
void QuickSort(float a[],int low,int high) //用递归法快速排序
{
int i=low ,j=high;
float temp=a[low];
while(i<j)
{
while(i<j&& temp<=a[j]) j--;
if(i<j)
{
a[i]=a[j];
i++;
}
while (i<j&& a[i]<=temp)i++;
if(i<j)
{
a[j]=a[i];
j--;
}
}
a[i]=temp;
if(low<i)QuickSort(a,low,i-1);
if(i<high)QuickSort(a,j+1,high);
}
void flag(int num,float *p,float prb[]){ //判断所成的面,并计数的函数
int SUM=0;
for(int i=0;i<6;i++){
if(num<(SUM+=prb[i])){
*(p+i)+=1;
break;
}
}
}
int main(){
float prb[6]={0}; //创建每一面概率的函数,数组下标+1代表面的编号
float count[6]={0}; //创建计数数组
float* p=count;
int i=0,sum=0,n,num,t;
for(i=0;i<6;i++) //生成随机数,并储存
{
prb[i]=1+rand()%100;
sum+=prb[i];
}
QuickSort (prb,0,5); //获得排序后的概率表
scanf("%d",&n); //输入检测次数
t=n;
while (t>0){ //记录每一面的次数
num=1+rand()%(sum+1);
flag(num,p,prb);
t--;
}
for(i=0;i<6;i++)printf("%d %f %f\n",i,(prb[i]/sum),(count[i])/n);
}
四、小结
在处理类似于概率的问题的时候,可以不仅仅局限于区间[0,1],而可以用宏观化、具象化的方法求得随机的概率以及按概率取值。