可能重复:
how to get uniformed random between a, b by a known uniformed random function RANDOM(0,1)
在算法简介一书中,有一个消费税:
描述只调用Random(0,1)的过程Random(a,b)的实现。作为a和b的函数,您的程序的预期运行时间是多少?随机(a,b)结果的概率应该是纯粹均匀分布的,如随机(0,1)
对于Random函数,结果是a和b之间的整数,包含。例如,Random(0,1)生成0或1;随机(a,b)生成a,a + 1,a + 2,...,b
我的解决方案是这样的:
for i = 1 to b-a
r = a + Random(0,1)
return r
运行时间 T = b-a
这是对的吗?我的解决方案的结果是否均匀分布?
由于
如果我的新解决方案如下:
r = a
for i = 1 to b - a //including b-a
r += Random(0,1)
return r
如果不正确,为什么r + = Random(0,1)使r不均匀分布?
答案 0 :(得分:16)
其他人已经解释了为什么您的解决方案不起作用。这是正确的解决方案:
1)找到最小的数字p
,使2^p > b-a
。
2)执行以下算法:
r=0
for i = 1 to p
r = 2*r + Random(0,1)
3)如果r
大于b-a
,请转到第2步。
4)您的结果是r+a
所以让我们试试随机(1,3)
所以b-a
是2.
2^1 = 2
,因此p
必须为2,以便2^p
大于2。
所以我们会循环两次。让我们尝试所有可能的输出:
00 -> r=0, 0 is not > 2, so we output 0+1 or 1.
01 -> r=1, 1 is not > 2, so we output 1+1 or 2.
10 -> r=2, 2 is not > 2, so we output 2+1 or 3.
11 -> r=3, 3 is > 2, so we repeat.
所以1/4的时间,我们输出1. 1/4的时间我们输出2. 1/4的时间我们输出3.而1/4的时间我们必须重复算法一秒时间。看起来不错。
请注意,如果必须执行此操作,则可以使用两个优化:
1)如果您经常使用相同的范围,请使用一个计算p
一次的类,这样您就不必每次都计算它。
2)许多CPU都有快速的方法来执行未在高级语言中公开的步骤1。例如,x86 CPU具有BSR指令。
答案 1 :(得分:2)
不,这不正确,该方法将集中在(a+b)/2
。这是一个二项分布。
你确定Random(0,1)
产生整数吗?如果它产生的浮点值介于0和1之间会更有意义。那么解决方案就是仿射变换,运行时间与a
和b
无关。
我刚才有一个想法,如果它是关于整数值:使用二分法。在每一步中,您都有一个范围low-high
。如果Random(0,1)
返回0,则下一个范围为low-(low+high)/2
,否则为(low+high)/2-high
。
因为它是家庭作业所以留给你的细节和复杂性。
这应该创造(近似)均匀分布。
编辑: 大约是那里的重要词汇。如果b-a+1
是2的幂,那么是统一的,如果它接近则不太远,但通常不够好。啊,这是一个自发的想法,不能让他们没事。
答案 2 :(得分:1)
我读了其他答案。为了好玩,这是找到随机数的另一种方法:
使用b-a
元素分配数组。
将所有值设置为1
。
遍历数组。对于每个非零元素,按原样翻转硬币。如果出现0
,请将元素设置为0
。
每当完成一次迭代后,你只剩下1个元素,你就得到了随机数:a+i
其中i
是非零元素的索引(假设我们开始在{{1上建立索引) }})。那么所有数字都是同样可能的。 (你必须处理它是一个平局的情况,但我把它作为练习留给你。)
这会有0
... :)
但平均而言,一半的数字将被消除,因此它的平均案例运行时间为O(infinity)
。
答案 3 :(得分:0)
首先,我假设您实际上在累积结果,而不是在每一步上添加0或1。 使用一些概率可以证明您的解决方案不是均匀分布的。结果值r为(a + b)/ 2的可能性最大。例如,如果a为0且b为7,则获得值4的机会是(7的组合4)除以2提升到7的幂。原因是无论7个值中的哪4个值是1,结果仍然是4。
您估计的运行时间是正确的。
答案 4 :(得分:0)
在你创建的算法中,它实际上并不是平均分配的。
结果“r”将始终为“a”或“a + 1”。它永远不会超越它。
看起来应该是这样的:
r=0;
for i=0 to b-a
r = a + r + Random(0,1)
return r;
通过在计算中加入“r”,您可以包含所有先前“for”循环运行的“随机性”。
答案 5 :(得分:0)
不,您的解决方案不正确。这个总和将具有二项分布。
但是,您可以生成0,1的纯随机序列,并将其视为二进制数。
repeat
result = a
steps = ceiling(log(b - a))
for i = 0 to steps
result += (2 ^ i) * Random(0, 1)
until result <= b
KennyTM:我的不好。
答案 6 :(得分:-1)
您的解决方案的伪代码应如下所示:
r=a
for i = 0 to b-a
r+=Random(0,1)
return r
对于均匀分布,假设该随机数生成器基于的随机实现是完全一致的,获得0或1的几率是50%。因此,获得您想要的数字是一遍又一遍的选择的结果。
因此,对于a = 1,b = 5,有5个选择。
获得1的几率涉及5个决定,均为0,其可能性为0.5 ^ 5 = 3.125%
获得5的几率涉及5个决定,全部为1,可能性为0.5 ^ 5 = 3.125%
从中可以看出,分布不均匀 - 任何数字的几率应为20%。