隨機數

給定了一個可以生成1~n的隨機函數,求一個生成1~m的隨機函數。爲了方便,假設n<m,m<n*n。函數

有一種比較通用,但不必定高效的方法是:方法

一、 z = n *( rand_n() - 1 )+rand_n();此時z的取值範值範圍是[1,n*n],並且是等機率的取值。while

二、 剩下的就是將[1,n*n]映射到[1,m]。由於m<n*n,因此只須要以m個數做爲一個取值區間,從小到大進行映射,到最後的幾個數不滿m個,就捨棄,從新取值。生成

  因此,首先肯定最後捨棄的那幾個數的個數,re = n*n%m,return

三、最後,當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都是要捨棄的。

相關文章
相關標籤/搜索