以相同的概率生成数字

时间:2016-02-23 09:54:58

标签: algorithm probability

给你一个函数让我们说bin()将以相等的概率生成0或1。现在给你一系列连续的整数说[a,b](包括a和b)。

写一个函数说rand()使用bin()以相等的概率生成范围[a,b]内的数字

4 个答案:

答案 0 :(得分:5)

您需要的洞察力是您的bin()函数返回单个二进制数字,或者" bit"。调用它一次会给你0或1.如果你调用它两次,你得到两个位b0b1,可以合并为b1 * 2 + b0,给你一个0,1,2或3概率相等。如果您三次调用它,则会得到三位b0b1b2。把它们放在一起,你得到b2 * 2^2 + b1 * 2 + b0,给你一个{0,1,2,3,4,5,6,7}的成员,概率相等。等等,尽可能多。

您的范围[a,b]的值为m = b-a+1。您只需要足够的位来生成介于0和2^n-1之间的数字,其中n是使2^n-1大于或等于m的最小值。然后,只需将该设置缩放为从a开始,就可以了。

所以,让我们说你得到了范围[20,30]。那里有11个数字,从20到30(含)。 11大于8(2 ^ 3),但小于16(2 ^ 4),因此您需要4位。使用bin()生成四位b0b1b2b3。将它们组合在一起x = b3 * 2^3 + b2 * 2^2 + b1 * 2 + b0。您将获得0到15之间的结果x。如果x&gt; 11然后生成另外四位。当x <= 11时,您的答案为x + 20

答案 1 :(得分:2)

帮助,但没有代码:

  • 您可以轻松地将范围[0,2 ** n]移至[a,a + 2 ** n]
  • 您可以轻松地从[0,2 ** n-1]
  • 产生相等的概率
  • 如果您需要的数字不是2的幂,只需生成最多2 ** n的数字,如果超过您需要的数字则重新滚动

答案 2 :(得分:1)

减去数字以计算出你的范围:

Decimal: 20 - 10 = 10
Binary : 10100 - 01010 = 1010

计算出需要多少位来表示:4

对于其中的每一个,生成随机1或0:

num_bits = 4
rand[num_bits]
for (x = 0; x < num_bits; ++x)
  rand[x] = bin()

在此之后我们说rand [] = [0,1,0,0]。将此号码添加回您的范围的开头。

Binary: 1010 + 0100 = 1110
Decimal: 10 + 4 = 14

答案 3 :(得分:0)

您可以随时将范围[a,b]更改为[0,b-a],表示X = b - a。然后你可以定义一个函数rand(X),如下所示:

function int rand(X){
   int i = 1;
   // determine how many bits you need (see above answer for why)
   while (X < 2^i) {
      i++;
   }
   // generate the random numbers
   Boolean cont = true;
   int num = 0;
   while (cont == true) {
      for (j = 1 to i) {
         // this generates num in range [0,2^i -1] with equal prob
         // but we need to discard if num is larger than X
         num = num + bin() * 2^j;
      }
      if (num <= X) { cont = false}
   }
   return num;
}