假设我有一个返回随机位的函数,是否可以编写一个在一定范围内统一生成随机数并始终终止的函数?
我知道如何做到这一点,以便它(并且可能会)终止。我只是想知道是否可以写一个保证终止的(并且它不一定非常有效。它有什么复杂性?
以下是不总是终止版本的代码
int random(int n)
{
while(true)
{
int r = 0;
for (int i = 0; i < ceil(log(n)); i++)
{
r = r<<1;
r = r|getRandomBit();
}
if(r<n)
{
return r;
}
}
}
答案 0 :(得分:2)
我认为这会奏效:
假设您要生成[a,b]
使用二进制基数在范围r
中生成分数[0,1}
。这意味着生成一些表单0.x1x2x3....
,其中每个x
使用随机函数为0或1。
完成后,您可以通过计算[0,b-a]
轻松生成ceil(r*(b-a))
范围内的数字,然后只需添加a
即可获得范围[a,b]
中的数字}
答案 1 :(得分:1)
如果范围的大小不是2的幂,则除了通过拒绝采样之外,您无法获得完全均匀的分布。然而,你可以通过从大范围内采样一次,然后将较小的范围划分为一个,来尽可能接近均匀。
例如,虽然您无法在1到10之间进行均匀采样,但您可以通过选择10个随机位来轻松地在1到1024之间进行采样,并找出将其公平划分为大约相同大小的10个区间的某种方式
选择其他位会使您在选择中必须看到的最大错误(从真正均匀性)减半...因此,当您选择更多位时,错误会呈指数级下降。