C++ 给定均匀随机数生成器生成随机数
我被要求使用C++ 给定均匀随机数生成器生成随机数,c++,c,algorithm,C++,C,Algorithm,我被要求使用random(0,1)在a和b之间生成一个随机数random(0,1)生成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
random(0,1)
在a
和b
之间生成一个随机数random(0,1)
生成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
我的答案正确吗
random(a,b) from random(c,d) = a + (b-a)*((random(c,d) - c)/(d-c))
否?随机(a,b)来自随机(0,1):
随机(c,d)来自随机(a,b):
或者,根据您的情况简化(a=1,b=5,c=1,d=7):
(注意:我假设我们讨论的是浮点值,舍入误差可以忽略不计)[random(0,1)*(b-a)]+a,我认为会给出随机数b/w a和b。
([随机(1,5)-1]/4)*6+1应给出范围(1,7)内的随机数
我不确定上述情况是否会破坏均匀分布
我的答案正确吗
random(a,b) from random(c,d) = a + (b-a)*((random(c,d) - c)/(d-c))
我认为有一些问题
首先,我假设random()
返回一个浮点值-否则,要使用random(0,1)
生成更大范围的数字的任何有用分布,需要重复调用以生成一个要使用的位池
我还将假设C/C++是预期的平台,因为问题被标记为这样
鉴于这些假设,您的答案的一个问题是C/C++不允许在浮点类型上使用%
运算符
但是,即使我们设想将%
运算符替换为以合理的方式执行带浮点参数的模运算的函数,仍然存在一些问题。在您最初的回答中,如果b
(或者在您第二次尝试中分配的未初始化*z
——我假设这是一种获取任意值的奇怪方式,或者是其他意图?)为零(假设a
和b
的范围为(-5,0)
),那么你的结果肯定是不一致的。结果总是b
最后,我当然不是统计学家,但在你的最终答案中(从random(1.5)
生成random(1,7)
),我非常确定A+B+C
是非均匀的,因此会在结果中引入偏差。给定random(0,5)你可以用以下方式生成random(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),并继续打成平局,直到出现合适范围内的数字
显然,当我们假设需要随机整数时,这是正确的
然而,要获得随机浮点数,我们需要按照上面的文章所述相应地修改范围。我认为您混淆了随机整数生成器和随机浮点数生成器。在C++中,RAND()生成0到32 K之间的随机整数。因此,为了生成从1到10的随机数,我们写rand()%10+1。同样地,为了生成从整数a到整数b的随机数,我们写rand()%(b-a+1)+a 面试官告诉你你有一个从0到1的随机发生器。它的意思是浮点数生成器 如何从数学上得到答案:
a <= R <= b.
Apply rule 1, we get a-a <= R - a <= b-a
0 <= R - a <= b - a.
现在用R-a代替R1
R - a = rand(0,1) * (b-a) ==> R = a + rand(0,1) * (b-a)
==第二个问题-无需解释====
我们有1我认为有一个更好的答案。有一个值(概率->零)溢出,因此模数存在
x
(int(random()/(1.0/上限))%上限)+1+下限
这应该会在您想要的时间间隔内返回一个数字。请格式化代码,我已经向您展示了如何不必提及您的潜在雇主。我把你的问题改了一点,然后格式化,在继续更新之前,请考虑复习我的编辑。<代码> RAND(1,7):= RAND(1,5) Works.类似:当你说“A和B之间包含”时,你是指<代码> B/C>是一个可能的返回值吗?我猜
random(0,1)
总是返回一个小于1的值?这会让事情变得特别棘手。不。首先,从[c,d]映射到[0,1],然后从[0,1]映射到[a,b]。您在第一步中缺少了一个random-c
;我永远记不起什么时候你应该加一个来获得正确的端点。@Dennis:fenceposts只有在我们谈论整数范围时才会成为一个问题。有理数/实数范围的宽度仅为端点之间的差值,而不管该范围是否包含任何端点、一个端点或两个端点(即,该范围是开放的、半开放的还是闭合的)。只有整数(或其他非稠密集)的端点的开放性才影响范围的长度。-1给出了一个完全错误的答案。为什么两个均匀随机数的乘积是一致的?A.
a <= R <= b.
Apply rule 1, we get a-a <= R - a <= b-a
0 <= R - a <= b - a.
R1 = rand(0, 1) * (b-a) // by apply rule 2.
R - a = rand(0,1) * (b-a) ==> R = a + rand(0,1) * (b-a)
==> 0 <= R1 - 1 <= 4
==> 0 <= (R1 - 1)/4 <= 1
==> 0 <= 6 * (R1 - 1)/4 <= 6
==> 1 <= 1 + 6 * (R1 - 1)/4 <= 7