在解决设计问题时,有时会用到概率算法。概率算法允许在执行过程中随机的选择下一步的计算步骤。又是可使算法大大降低复杂度,提高算法效率,但有时也可能得不到问题的全部答案。
基本概念
概率算法大致分为4类:熟知概率算法,蒙特卡洛算法,拉斯维加斯算法,舍伍德算法。这里首先介绍一下最基础的数值概率算法。
数值概率算法常用于解决数值计算的问题。该算法往往只能得到问题的近似解,并且该计算解的精度一般随着计算时间的增加而不断提高。
计算定积分
例:设f(x)=1-x^2,计算定积分I= ∫10f(x)dx 的值。
分析:要计算定积分的值的几何含义就是f(x)与x轴y轴所围得面积(设为阴影)。又因为x,y轴所围的面积为1,所以随机点落入阴影的概率(在上下线所围成的区域内)即为定积分的近似解。
假设向单位正方形中随机投入n个点(
xi
,
yi
)i=1,2,3,…n。随机点是否落入阴影区域内,可由
yi
<=f(
xi
)=1-
x2i
来判断。如果有m个点落入阴影,则概率p=m/n。
程序如下:
#include"stdio.h"
#include"math.h"
#include"stdlib.h"
#include"time.h"
double Darts(int n)
{
double x,y;
time_t t;
int i,count=0;
srand((unsigned)time(&t));
for(i=0;i<n;i++)
{
x=rand()%100/100.0; //将x,y控制在(0,1)内
y=rand()%100/100.0;
if(y<=1-pow(x,2))
count++;
}
return (double)count/(double)n;
}
main()
{
int n;
printf("Please input the accuracy\n");
scanf("%d",&n);
printf("The result is about\n");
printf("%f\n",Darts(n));
getche();
}
程序分析:
应用函数srand()和rand()产生随机数,用系统时间产生随机数的种子,这里每次产生的随机数都不一样。因为函数rand()产生的随机数返回值为整数,因此在这里先产生100以内的随机数(rand()%100),再将它除以100.0,可得到双精度的[0,1]内的随机数点。试验投点的个数由函数Darts的参数n决定,n越大,投点个数越多,精度越高。
rand()和srand():
因为rand的内部实现是用线性同余法做的,他不是真的随机数,只是因为其周期特别长,所以有一定的范围里可看成是随机的,rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。rand()产生的是假随机数字,每次执行时是相同的。(当开机那一刻rand()所产生的随机数就是定了的)若要不同,以不同的值来初始化它。初始化的函数就是srand()。
表头文件:
#include”stdlib.h”
函数原型:
void srand ((unsigned int) seed);
int rand(void)