在给定统一随机数生成器的情况下生成随机数

Generating random numbers given a uniform random number generator

本文关键字:情况下 随机数 随机数生成器      更新时间:2023-10-16

我被要求使用random(0,1)ab之间生成一个随机数。CCD_ 4生成介于0和1之间的均匀随机数。

我回答

(a+(((1+random(0,1))*b))%(b-a))

我的面试官对我在这段表达中使用b并不满意:

(((1+random(0,1))*b))

然后我试着把答案改成:

int*z=(int*)malloc(sizeof(int));
(a+(((1+random(0,1))*(*z)))%(b-a));

后来,问题变为从random(1,5)生成random(1,7)。我的回复是:

A = rand(1,5)%3
B = (rand(1,5)+1)%3
C = (rand(1,5)+2)%3
rand(1,7) = rand(1,5)+ (A+B+C)%3

我的答案正确吗?

我想您混淆了随机整数生成器和随机浮点数生成器。在C++中,rand()生成0到32K之间的随机整数。因此,为了生成从1到10的随机数,我们写rand()%10+1。因此,为了生成从整数a到整数b的随机数,我们写rand()%(b-a+1)+a。

面试官告诉你,你有一个从0到1的随机生成器。它的意思是浮点数生成器。

如何从数学上得到答案:

  1. 将问题转换为一个简单的形式,使下界为0
  2. 通过乘法缩放范围
  3. 重新切换到所需范围

例如:生成R以使

a <= R <= b.  
Apply rule 1, we get a-a <= R - a <= b-a 
                       0 <= R - a <= b - a.  

把R-a看作R1。如何生成R1,使R1的范围从0到(b-a)?

R1 = rand(0, 1) * (b-a)   // by apply rule 2.

现在用R代替R1-一个

R - a = rand(0,1) * (b-a)    ==>   R = a + rand(0,1) * (b-a)

===第二个问题-没有解释===

我们有1<=R1<=5

==>   0 <= R1 - 1             <= 4
==>   0 <= (R1 - 1)/4         <= 1
==>   0 <= 6 * (R1 - 1)/4     <= 6
==>   1 <= 1 + 6 * (R1 - 1)/4 <= 7

因此,Rand(1,7)=1+6*(Rand(1,5)-1)/4

随机(a,b)来自随机(0,1):

random(0,1)*(b-a)+a

随机(a,b)中的随机(c,d):

(random(a,b)-a)/(b-a)*(d-c)+c

或者,简化为您的情况(a=1,b=5,c=1,d=7):

random(1,5) * 1.5 - 0.5

(注意:我假设我们谈论的是浮点值,舍入误差可以忽略不计)

random(a,b) from random(c,d) = a + (b-a)*((random(c,d) - c)/(d-c))

没有?

[随机(0,1)*(b-a)]+a,我认为会给出随机数b/w a&b([随机(1,5)-1]/4)*6+1应给出范围(1,7)内的随机结块我不确定以上情况是否会破坏均匀分布。。

我的答案正确吗?

我认为有一些问题。

首先,我假设random()返回一个浮点值,否则,要使用random(0,1)生成更大范围的数字的任何有用分布,都需要重复调用以生成一个可使用的比特池。

我还假设C/C++是预期的平台,因为这个问题是这样标记的。

考虑到这些假设,您的答案中的一个问题是C/C++不允许在浮点类型上使用%运算符。

但是,即使我们想象%算子被一个以合理的方式用浮点自变量执行模运算的函数所取代,仍然存在一些问题。在你最初的答案中,如果b(或者在你第二次尝试中分配的未初始化的*z——我认为这是一种奇怪的获得任意值的方式,或者是其他什么目的?)为零(比如ab的范围是(-5, 0)),那么你的结果肯定是不一致的。结果总是b

最后,我当然不是统计学家,但在你的最终答案中(从random(1.5)生成random(1,7)),我非常确信A+B+C是不均匀的,因此会在结果中引入偏差。

我认为有一个更好的答案。有一个值(概率->零)溢出,因此模数就在那里。

  1. 取区间[0,1]中的一个随机数 x

  2. 将您的upper_bound(可能是一个参数)增加一。

  3. 计算 (int(random() / (1.0 / upper_bound)) % upper_bound) + 1 + lower_bound

这应该在您想要的间隔中返回一个数字。

给定随机(0,5),您可以通过以下方式生成随机(0,7)

A=随机(0.5)*随机(0.5现在A的范围是0-25

如果我们简单地取A的模7,我们可以得到随机数,但它们不是真正随机的,因为对于22-25的A值,在模运算后会得到1-4个值,因此从范围(0,25)得到模7会使输出偏向1-4。这是因为7不能平分25:小于或等于25的7的最大倍数是7*3=21,而21-25的不完整范围内的数字将导致偏差。

解决这个问题最简单的方法是丢弃这些数字(从22-25),然后继续打平,直到出现合适范围内的数字。

显然,当我们假设我们想要随机整数时,这是真的。

然而,要获得随机浮点数,我们需要相应地修改范围,如以上帖子所述。