【问题标题】:How to implement Random(a,b) with only Random(0,1)? [duplicate]如何仅使用 Random(0,1) 实现 Random(a,b)? [复制]
【发布时间】:2012-01-31 08:16:20
【问题描述】:

可能重复:
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 的函数,您的程序的预期运行时间是多少? 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=b-a

这是正确的吗?我的解决方案的结果是否均匀分布?

谢谢

如果我的新解决方案是这样的:

r = a
for i = 1 to b - a //including b-a
    r += Random(0,1)
return r

如果不正确,为什么 r += Random(0,1) 使得 r 不均匀分布?

【问题讨论】:

  • 您的解决方案不是均匀分布的。例如,最低值a 只能通过 random(0)+random(0)+random(0)+...之和来“计算”。但是“中间”值的概率是更高,因为它可以计算为 0+0+0+1+1、0+0+1+0+1、1+1+0+0+0,以此类推。把它想象成扔两个骰子。得到2(1+1)或12(6+6)的概率低于得到7(1+6,2+5,3+4,4+3,5+2,6+1)的概率(卡坦英尺的定居者。;))。
  • 您的第二行每次都会重置r。您应该将其初始化为a,然后在循环中根据自身进行更新。

标签: algorithm random probability


【解决方案1】:

其他人已经解释了为什么您的解决方案不起作用。这是正确的解决方案:

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

让我们试试 Random(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 指令。

【讨论】:

  • 所以这里的想法是找到表示最高数字所需的最大位数,然后为每个位掷硬币。
  • 是的。然后如果超出范围,请重复该过程。
  • 我自己也遇到了类似的问题,但是以二分搜索的形式。谢谢,很高兴看到没问题。虽然希望有一种聪明的方法将问题从 2 的幂减少到任意数字(以及更好的 O-big)。
【解决方案2】:

不,这是不正确的,该方法将集中在(a+b)/2 周围。这是一个二项分布。

你确定Random(0,1) 产生整数吗?如果它产生介于 0 和 1 之间的浮点值会更有意义。那么解决方案将是仿射变换,运行时间独立于 ab

我刚刚想到的一个想法,如果它是关于整数值的:使用二分法。在每一步,您都有一个范围low-high。如果 Random(0,1) 返回 0,则下一个范围是 low-(low+high)/2,否则为 (low+high)/2-high。 细节和复杂性留给你,因为这是家庭作业。

这应该创建(大约)均匀分布。

编辑: 大约是那里的重要词。如果b-a+1 是 2 的幂,则一致,如果它接近,则不会太远,但通常不够好。啊,好吧,这是一个自发的想法,不能把它们弄好。

【讨论】:

  • 这是书中的一段话:我们假设我们有一个随机数生成器 RANDOM。对 RANDOM(a, b) 的调用会返回一个介于 a 和 b 之间的整数,包括两个整数,每个这样的整数都具有相同的可能性。例如,RANDOM(0, 1) 以 1/2 的概率生成 0,以 1/2 的概率生成 1
  • 啊哈。对,否则就太容易了。我看到作业标签时忘记了第一行:)
  • @DanielFischer 这只会产生近似均匀的分布。考虑 (1,3)。
  • 是的,仅适用于 2 的幂。但对于自发的想法来说并不太糟糕。
【解决方案3】:

不,您的解决方案不正确。这个总和会有二项分布。

但是,你可以生成一个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:我的错。

【讨论】:

  • 2 ^ (i * Random(0, 1))?你的意思是(2 ^ i) * Random(0, 1)
【解决方案4】:

我阅读了其他答案。为了好玩,这里是另一种找到随机数的方法:

分配具有b-a 元素的数组。 将所有值设置为1。 遍历数组。对于每个非零元素,抛硬币,就像它一样。如果出现0,则将元素设置为0

只要在一个完整的迭代之后,你只剩下 1 个元素,你就有你的随机数:a+i 其中i 是非零元素的索引(假设我们开始索引0)。那么所有的数字都是同样可能的。 (你必须处理平局的情况,但我把它留给你作为练习。)

这将有O(infinity) ... :) 不过,平均而言,将消除一半的数字,因此它的平均案例运行时间为log_2 (b-a)

【讨论】:

  • 你实际上可以合理地完成这项工作,如果你做得对,它是 O(n log n)(其中 n=b-a)。基本上,如果 Random(0,1) 为 1,您希望增加每个数组元素,如果其值小于截止值,则考虑运行中的每个元素。每次通过后增加截止值,如果没有有效值,则减少截止值。当一个条目有效时,您就完成了。
【解决方案5】:

首先,我假设您实际上是在累积结果,而不是在每个步骤中将 0 或 1 添加到 a 中。 使用一些概率,您可以证明您的解决方案不是均匀分布的。结果值 r 为 (a+b)/2 的机会最大。例如,如果 a 为 0 且 b 为 7,则您获得值 4 的机会是(7 的组合 4)除以 2 的 7 次方。原因是无论 7 个值中的哪 4 个是 1 结果仍然是 4。

您估计的运行时间是正确的。

【讨论】:

    【解决方案6】:

    您的解决方案的伪代码应如下所示:

    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%。

    【讨论】:

      【解决方案7】:

      在您创建的算法中,它确实分布不均。

      结果“r”总是“a”或“a+1”。它永远不会超出此范围。

      它应该看起来像这样:

      r=0;
      for i=0 to b-a
         r = a + r + Random(0,1)
      
      return r;
      

      通过在计算中包含“r”,您将包含所有先前“for”循环运行的“随机性”。

      【讨论】:

      • 但是返回的数字不会超过 b 吗?
      • 好吧,等等。我假设Random(0,1) 只返回 0 或 1
      猜你喜欢
      • 1970-01-01
      • 2013-07-06
      • 2015-03-26
      • 2018-10-18
      • 1970-01-01
      • 2015-11-02
      • 2017-07-16
      • 1970-01-01
      • 2017-10-28
      相关资源
      最近更新 更多