是和否,这取决于您所说的“唯一方法”。是的,因为没有一种方法可以保证终止,所以最好的方法(对于和通用值)是一种以概率1终止的算法。随你便。NR
为什么总的来说不可能保证终止
假设您具有确定性的计算引擎(图灵机或使您的船漂浮的任何东西),加上一个生成元素集随机元素的。您的目标是生成元素集元素。引擎的输出仅取决于oracle返回的值序列;它是该潜在无限序列的函数。R[0..R−1]N[0,N−1]f(r0,r1,r2,…)
假设您的引擎最多调用次oracle 。可能有痕迹的oracle被调用少于次;如果是这样,则额外地调用oracle以使它始终被精确地调用次不会更改输出。因此,在不失一般性的前提下,我们假设oracle被精确地调用了次。然后,结果的概率是序列数,使得。由于oracle是一个统一的随机生成器,因此每个序列都是等概率的,并且具有的概率。因此,每个结果的概率形式为mmmmx(r0,…,rm−1)f(r0,…,rm−1)=x1/RmA/Rm其中是到之间的整数。A0Rm
如果划分一些,则可以生成一个均匀分布通过调用随机发生器元件倍(这是留给读者作为练习到读取器)。否则,这是不可能的:无法以概率获得结果。请注意,该条件等同于说的所有素数也是因数(这比您在问题中所写的要宽容;例如,您可以从4个随机元素中选择一个6面公平即使4不除以6)也会死亡。NRmmNm1/NNR
减少浪费
在您的策略中,当,您不必立即重新绘制。直观地讲,中还剩下一些熵,您可以将其保留在混合中。r≥kN[kN..R−1]
假设有一瞬间,您实际上将永远生成低于随机数,并通过绘制一次生成其中的。如果您对该分组生成的代数进行直接拒绝采样,则抽奖上的浪费为,即剩余的除以平局次数。可以少至。当和为互质时,可以通过选择足够大的任意减小废物。对于和一般值NuddRd−kNudRdmodNugcd(R,N)RNdRN,计算会更复杂,因为您需要分别考虑和,但是同样可以通过足够大的组来任意减小浪费。gcd(R,N)N/gcd(R,N)
实际上,即使随机数相对无效(例如在密码学中),除非简单地拒绝采样,否则除非很小,否则几乎不值得做任何事情。例如,在密码术中,通常是2的幂,而通常是数百或数千位,通常通过在所需范围内进行直接拒绝采样来进行均匀的随机数生成。NRN