EPI_PrimitiveTypes_No.004_UniformRandom

问题简述

给一个2面的硬币,要求设计一个算法来模拟6面骰子。
Follow Up:如何模拟任意[a, b]的均匀随机情况?其中a

思路阐述

首先明白一点,[a,b]的随机就等价于[0,b-a]的随机。
2面硬币只能产生0和1两种结果,N次之后可以产生一个N位的二进制数。例如3次之后可以随机出[0,7]的均匀随机情况。也就是说,如果b-a=2^N-1,那么抛N次硬币即可。
那么当b-a≠2^N-1呢?
考虑6面骰子,3次之后可能会有2个不符合的结果,因为6面骰子对应范围是[0,5],也就是说6和7这两个结果是不能用的。因此,采取策略如下:

  • 抛3次硬币,假如结果在[0,5]内,直接使用结果;
  • 假如结果是6或者7,则再抛3次硬币,直至产生有效结果。

推广至[0, b-a],也很类似。代码:

public static int uniformRandom(int lowerBound, int upperBound) {
    int numberOfOutcomes = upperBound - lowerBound + 1, result;
    do {
        result = 0;
        for (int i = 0; (1 << i) < numberOfOutcomes; ++i) {
            // zeroOneRandom() is the provided random number generator.
            result = (result << 1)|zeroOneRandom();
        }
    } while (result >= numberOfOutcomes);
    return result + lowerBound;
}

总结

其实说穿了就很简单,但如果没遇到过,不一定一下子能想出来。

你可能感兴趣的:(EPI_PrimitiveTypes_No.004_UniformRandom)