了解统一随机数生成

时间:2014-10-01 19:29:35

标签: algorithm random

我正在阅读一个关于从rand5()生成rand7()的问题,我似乎还没有理解它。建议的解决方案显示为here

        int i;
        do
        {
          i = 5 * (rand5() - 1) + rand5();  // i is now uniformly random between 1 and 25
        } while(i > 21);
        // i is now uniformly random between 1 and 21
        return i % 7 + 1;  // result is now uniformly random between 1 and 7

我理解这种方法,但我不明白为什么范围必须从1到21.我的解决方案是:

        int i;
        do
        {     
          i = (rand5()-1) + rand5();  // i is now uniformly random between 1 and 9
        } while(i > 7); 
        // i is now uniformly random between 0 and 6
        return i+1;

我还没有能够说服自己,上面提到的方法并不奏效。你能不能给我一个比其他人更多的数字的例子,让我的方法不均匀?为什么需要乘数为5?

2 个答案:

答案 0 :(得分:2)

当您添加两个均匀分布的随机数时,结果将不再均匀分布。考虑结果表:

    1  2  3  4  5
  ---------------
1 | 1  2  3  4  5
2 | 2  3  4  5  6
3 | 3  4  5  6  7
4 | 4  5  6  7  8
5 | 5  6  7  8  9

计算表中5的数量,并计算1和9的数量。问题应该是显而易见的。

通过将一个随机数乘以范围并添加第二个,您可以保持每个数字的贡献独立。恰好有25种不同的结果,每种结果的概率为1/25。

答案 1 :(得分:1)

  

你们能给我一个比其他人更多的数字的例子,让我的方法不均匀吗?

当然可以。使用您的方法,范围中间附近的数字比最后的数字更可能出现;例如,5出现的可能性是1的5倍。

有1种方法可以制作1。

  • (1 - 1)+ 1 = 1

有两种方法可以制作2。

  • (1 - 1)+ 2 = 2
  • (2 - 1)+ 1 = 2

有3种方法可以制作3。

  • (1 - 1)+ 3 = 3
  • (2 - 1)+ 2 = 3
  • (3 - 1)+ 1 = 3

有4种方法可以制作4。

  • (1 - 1)+ 4 = 4
  • (2 - 1)+ 3 = 4
  • (3 - 1)+ 2 = 4
  • (4 - 1)+ 1 = 4

有5种方法可以制作5。

  • (1 - 1)+ 5 = 5
  • (2 - 1)+ 4 = 5
  • (3 - 1)+ 3 = 5
  • (4 - 1)+ 2 = 5
  • (5 - 1)+ 1 = 5

有4种方法可以制作6。

  • (2 - 1)+ 5 = 6
  • (3 - 1)+ 4 = 6
  • (4 - 1)+ 3 = 6
  • (5 - 1)+ 2 = 6

有3种方法可以制作7。

  • (3 - 1)+ 5 = 7
  • (4 - 1)+ 4 = 7
  • (5 - 1)+ 3 = 7

有两种方法可以制作8。

  • (4 - 1)+ 5 = 8
  • (5 - 1)+ 4 = 8

有一种方法可以制作9。

  • (5 - 1)+ 5 = 9