随机数

给定了一个能够生成1~n的随机函数,求一个生成1~m的随机函数。为了方便,假设n<m,m<n*n。

有一种比较通用,但不一定高效的方法是:

1、 z = n *( rand_n() - 1 )+rand_n();此时z的取值范值范围是[1,n*n],而且是等概率的取值。

2、 剩下的就是将[1,n*n]映射到[1,m]。因为m<n*n,所以只需要以m个数作为一个取值区间,从小到大进行映射,到最后的几个数不满m个,就舍弃,重新取值。

  所以,首先确定最后舍弃的那几个数的个数,re = n*n%m,

3、最后,当z的值在(n*n - re, n*n]之间的时候,重新取值。在[1,n*n-re]时,对m取余,加一即可。

int rand_m()

{

  int z;

  int re = n*n%m;

  do

  {

  z = n * ( rand_n() - 1 ) + rand_n();

  } while(z > n*n - re)

  return  z%m + 1;

}

这种方法,采用舍弃一部分不符合要求的数值的方式,原则上舍弃的数值的比例越少越好,最差的情况是舍弃约50%的数值。比如z的范围是[1,10],m是[1,6],那么7,8,9,10都是要舍弃的。

posted on 2016-05-22 11:40  冷月无声1988  阅读(131)  评论(0编辑  收藏  举报

导航