有没有办法给一个范围内的均匀分布的随机数转换成另一种范围的均匀分布的随机数省吃俭用?
让我解释一下我所说的“节俭”是什么意思。
在给定范围内生成随机数的典型方法(例如 r ? [0..10) )是采用一些固定的随机位,比如说 31,这会产生小于 2147483648 的非负随机数。然后确保该值小于 2147483640(因为 2147483648 不能被 10 整除,因此可能导致分布不均)。如果该值大于或等于 2147483640,则将其丢弃并重试(获取接下来的 31 个随机位等)。如果 value 小于 2147483640,则只返回除以 10 的余数。这种方法每个十进制数字至少消耗 31 位。由于理论极限是log 2 (10) = 3.321928...,相当浪费。
我们可以改进这一点,如果我们使用 4 位而不是 31。在这种情况下,我们将消耗 4 × 1.6 = 6.4 位每个十进制数字。这样比较节俭,但离理想还差得很远。
public int nextDit() {
int result;
do {
result = next4Bits();
} while (result >= 10);
return result;
}
Run Code Online (Sandbox Code Playgroud)
我们可以尝试一次生成 3 个十进制数字。由于 1024 与 1000 非常接近,因此原始源随机数被拒绝的概率小于前一种情况。一旦我们生成了 3 个十进制数字,我们就返回 1 个数字并保留其余的 2 个数字。
像下面这样
private int …Run Code Online (Sandbox Code Playgroud)