如何仅用Random(0,1)实现Random(a,b)?
在算法导论一书中,有一个注释:
描述该过程的实现Random(a, b) 仅调用 Random(0,1)。作为 a 和 b 的函数,程序的预期运行时间是多少? Random(a,b) 结果的概率应该是纯均匀分布的,如 Random(0,1)
对于 Random 函数,结果是 a 和 b 之间的整数(含)。例如,Random(0,1) 生成 0 或 1; Random(a, b) 生成 a, a+1, a+2, ..., b
我的解决方案是这样的:
for i = 1 to b-a
r = a + Random(0,1)
return r
运行时间是 T=ba
这是正确的吗?我的解决方案的结果是均匀分布的吗?
谢谢
如果我的新解决方案是这样的怎么办:
r = a
for i = 1 to b - a //including b-a
r += Random(0,1)
return r
如果不正确,为什么 r += Random(0,1) 使 r 不均匀分布?
Possible Duplicate:
how to get uniformed random between a, b by a known uniformed random function RANDOM(0,1)
In the book of Introduction to algorithms, there is an excise:
Describe an implementation of the procedure Random(a, b) that only makes calls to Random(0,1). What is the expected running time of your procedure, as a function of a and b? The probability of the result of Random(a,b) should be pure uniformly distributed, as Random(0,1)
For the Random function, the results are integers between a and b, inclusively. For e.g., Random(0,1) generates either 0 or 1; Random(a, b) generates a, a+1, a+2, ..., b
My solution is like this:
for i = 1 to b-a
r = a + Random(0,1)
return r
the running time is T=b-a
Is this correct? Are the results of my solutions uniformly distributed?
Thanks
What if my new solution is like this:
r = a
for i = 1 to b - a //including b-a
r += Random(0,1)
return r
If it is not correct, why r += Random(0,1) makes r not uniformly distributed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
其他人已经解释了为什么您的解决方案不起作用。正确的解决方案如下:
1) 找到最小的数
p
,使得2^p > ba。
2) 执行以下算法:
3) 如果
r
大于ba
,则转至步骤 2。4) 您的结果是
r+a
那么让我们尝试随机(1,3)。
所以
ba
是 2。2^1 = 2
,因此p
必须为 2,以便2^p
大于 2。所以我们将循环两次。让我们尝试所有可能的输出:
所以 1/4 的时间,我们输出 1。我们输出 2 的时间的 1/4。我们输出 3 的时间的 1/4。我们必须重复的时间的 1/4第二次算法。看起来不错。
请注意,如果您必须经常这样做,则有两种优化方法很方便:
1)如果您经常使用相同的范围,请使用一个计算
p
一次的类,这样您就不必计算它每次。2) 许多 CPU 有快速的方法来执行高级语言中未公开的步骤 1。例如,x86 CPU 具有 BSR 指令。
Others have explained why your solution doesn't work. Here's the correct solution:
1) Find the smallest number,
p
, such that2^p > b-a
.2) Perform the following algorithm:
3) If
r
is greater thanb-a
, go to step 2.4) Your result is
r+a
So let's try Random(1,3).
So
b-a
is 2.2^1 = 2
, sop
will have to be 2 so that2^p
is greater than 2.So we'll loop two times. Let's try all possible outputs:
So 1/4 of the time, we output 1. 1/4 of the time we output 2. 1/4 of the time we output 3. And 1/4 of the time we have to repeat the algorithm a second time. Looks good.
Note that if you have to do this a lot, two optimizations are handy:
1) If you use the same range a lot, have a class that computes
p
once so you don't have to compute it each time.2) Many CPUs have fast ways to perform step 1 that aren't exposed in high-level languages. For example, x86 CPUs have the BSR instruction.
不,这是不正确的,该方法将集中在
(a+b)/2
周围。这是二项分布。您确定
Random(0,1)
生成整数吗?如果它产生 0 到 1 之间的浮点值,则更有意义。那么解决方案将是仿射变换,运行时间独立于a
和b
。我刚刚想到的一个想法,如果它与整数值有关:使用二分法。每一步都有一个
低-高
范围。如果Random(0,1)
返回 0,则下一个范围是low-(low+high)/2
,否则(low+high)/2-高。
细节和复杂性留给你,因为这是家庭作业。
这应该会创建(大约)均匀分布。
编辑:大约是那里的重要词。如果
b-a+1
是 2 的幂,则为统一,如果接近则相差不太远,但总体来说还不够好。啊,好吧,这是一个自发的想法,无法让他们一切顺利。No, it's not correct, that method will concentrate around
(a+b)/2
. It's a binomial distribution.Are you sure that
Random(0,1)
produces integers? it would make more sense if it produced floating point values between 0 and 1. Then the solution would be an affine transformation, running time independent ofa
andb
.An idea I just had, in case it's about integer values: use bisection. At each step, you have a range
low-high
. IfRandom(0,1)
returns 0, the next range islow-(low+high)/2
, else(low+high)/2-high
.Details and complexity left to you, since it's homework.
That should create (approximately) a uniform distribution.
Edit: approximately is the important word there. Uniform if
b-a+1
is a power of 2, not too far off if it's close, but not good enough generally. Ah, well it was a spontaneous idea, can't get them all right.不,您的解决方案不正确。这个总和将服从二项式分布。
但是,您可以生成 0、1 的纯随机序列并将其视为二进制数。
KennyTM:我的错。
No, your solution isn't correct. This sum'll have binomial distribution.
However, you can generate a pure random sequence of 0, 1 and treat it as a binary number.
KennyTM: my bad.
我阅读了其他答案。为了好玩,这里有另一种查找随机数的方法:
分配一个包含
ba
元素的数组。将所有值设置为
1
。迭代数组。对于每个非零元素,就像掷硬币一样。如果出现
0
,则将该元素设置为0
。每当完成一次迭代后,只剩下 1 个元素时,您就会得到随机数:
a+i
,其中i
是非零元素的索引(假设我们开始在0
上建立索引)。那么所有数字都有相同的可能性。 (您必须处理平局的情况,但我将其作为练习留给您。)这将有
O(infinity)
... :)但平均而言,一半的数字将被消除,因此它的平均案例运行时间为
log_2 (ba)
。I read the other answers. For fun, here is another way to find the random number:
Allocate an array with
b-a
elements.Set all the values to
1
.Iterate through the array. For each nonzero element, flip the coin, as it were. If it is came up
0
, set the element to0
.Whenever, after a complete iteration, you only have 1 element remaining, you have your random number:
a+i
wherei
is the index of the nonzero element (assuming we start indexing on0
). All numbers are then equally likely. (You would have to deal with the case where it's a tie, but I leave that as an exercise for you.)This would have
O(infinity)
... :)On average, though, half the numbers would be eliminated, so it would have an average case running time of
log_2 (b-a)
.首先,我假设您实际上是在累加结果,而不是在每个步骤中向 a 添加 0 或 1。
使用一些概率,您可以证明您的解决方案不是均匀分布的。结果值 r 为 (a+b)/2 的可能性最大。例如,如果 a 为 0,b 为 7,则获得值 4 的机会是(7 的组合 4)除以 2 的 7 次方。原因是,无论 7 个值中的哪 4 个,是 1,结果仍然是 4。
您估计的运行时间是正确的。
First of all I assume you are actually accumulating the result, not adding 0 or 1 to a on each step.
Using some probabilites you can prove that your solution is not uniformly distibuted. The chance that the resulting value r is (a+b)/2 is greatest. For instance if a is 0 and b is 7, the chance that you get a value 4 is (combination 4 of 7) divided by 2 raised to the power 7. The reason for that is that no matter which 4 out of the 7 values are 1 the result will still be 4.
The running time you estimate is correct.
您的解决方案的伪代码应如下所示:
至于均匀分布,假设该随机数生成器所基于的随机实现完全均匀,则获得 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%。
Your solution's pseudocode should look like:
As for uniform distribution, assuming that the random implementation this random number generator is based on is perfectly uniform the odds of getting 0 or 1 are 50%. Therefore getting the number you want is the result of that choice made over and over again.
So for a=1, b=5, there are 5 choices made.
The odds of getting 1 involves 5 decisions, all 0, the odds of that are 0.5^5 = 3.125%
The odds of getting 5 involves 5 decisions, all 1, the odds of that are 0.5^5 = 3.125%
As you can see from this, the distribution is not uniform -- the odds of any number should be 20%.
在您创建的算法中,它实际上并不是均匀分布的。
结果“r”将始终是“a”或“a+1”。它永远不会超出这个范围。
它应该看起来像这样:
通过在计算中包含“r”,您就包含了所有先前“for”循环运行的“随机性”。
In the algorithm you created, it is really not equally distributed.
The result "r" will always be either "a" or "a+1". It will never go beyond that.
It should look something like this:
By including "r" into your computation, you are including the "randomness" of all the previous "for" loop runs.