采用概率算法,估计整数子集1~n的大小

在估计一个集合的势(大小)时,如果不要求很高的精确度,却要求较快的运算效率。我们推荐使用概率算法来求解。

设X是具有n个元素的集合,我们有回放地随机,均匀和独立地从X中选取元素,设k是出现第1次重复之前所选出的元素数目,则当n足够大时,k的期望值趋近为β√n,

这里β=√(π/2),利用此结论可以得出估计|X|的概率算法:n=2k2

 

算法伪代码如下:

SetCount (X)
SetCount (X) {
              k ← 0; S ← Ф;
              a ← uniform(X);
              do {
                     k++;
                     S ← S∪{a}; a ← uniform(X);
              } while (a ∉S)
              return 2k2/π;
         }
 

C语言描述如下:

#include<stdio.h>
#include<math.h>
#include<stdlib.h> 
#include<time.h>
#define N 100000
a[N]={0};
void main()
{
  unsigned int a[N];
  unsigned int i,j,n,k=0;
  unsigned int uniform;
 srand( (unsigned)time(NULL));
 printf(" 输入集合大小:");
 scanf("%d",&n);

 for(i=0;i<n;i++)
 {uniform=rand()*rand()%n;
  a[i]=uniform;
     for(j=0;j<i;j++)
     {
      if(a[j]==a[i])  goto  result;
     }
 }

result: k=i;
printf("计算结果为%5.0f, 真实值为%d\n",2*k*k/3.14,n);
}

 

执行结果如下:

结论:

1:此方法适用于快速计算集合的势(大小),不适用于精确计算

2:本文执行结果为作者筛选后的结果。在执行过程中还是会出现一些不好的结果,但此概率计数不失为一个好方法。

 

posted @ 2012-10-24 19:11  俞则人  阅读(2173)  评论(0编辑  收藏  举报