生成排序的随机数而不涉及取幂?

时间:2013-11-09 11:13:37

标签: algorithm statistics distribution probability uniform

我正在寻找一个数学方程式或算法,它可以在[0,1]范围内按升序生成均匀的随机数,而无需除法运算符的帮助。我热衷于跳过除法操作,因为我在硬件中实现它。谢谢。

2 个答案:

答案 0 :(得分:2)

以升序(或降序)顺序生成数字意味着按顺序生成它们但具有正确的分布。反过来,这意味着我们需要知道一组大小N的最小值的分布,然后在每个阶段我们需要使用条件来根据我们已经看到的内容确定下一个值。从数学角度来看,这些都是直截了当的,除了避免分裂的问题。

您可以使用算法min = 1 - U**(1/N)从单个均匀(0,1)随机数U生成N个均匀(0,1)的最小值,其中**表示取幂。换句话说,均匀的N th 根的补集与[0,1]范围内的N个均匀的最小值具有相同的分布,然后可以缩放到任何其他区间长度你喜欢。

条件方面基本上说已经生成的k值会占用原始区间的某些部分,而我们现在想要的是N-k值的最小值,缩放到剩余范围。

组合这两个部分产生以下逻辑。生成最小的N个制服,按剩余的间隔长度(第一次为1)对其进行缩放,并将该结果作为我们生成的最后一个值。然后生成最小的N-1制服,按剩余的间隔长度进行缩放,并将其添加到最后一个,以便为您提供下一个值。泡沫,冲洗,重复,直到你完成所有这些。假设您在此之前读入或指定了N,则以下Ruby实现会给出分布正确的结果:

last_u = 0.0
N.downto(1) do |i|
  p last_u += (1.0 - last_u) * (1.0 - (rand ** (1.0/i)))
end

但我们有使用除法的那个讨厌的 th root。但是,如果我们提前知道N,我们可以预先计算从1到N的整数的倒数,并将它们表格化。

last_u = 0.0
N.downto(1) do |i|
  p last_u += (1.0 - last_u) * (1.0 - (rand ** inverse[i]))
end

我不知道如何在不使用取幂的情况下顺序获得正确的分布行为。如果这是一个显示阻止,你将不得不放弃过程的顺序性或均匀性要求。

答案 1 :(得分:2)

您可以尝试所谓的“分层抽样”,这意味着您将范围划分为区间,然后从区间随机抽样。由此产生的样品比从整个间隔产生的样品更均匀(更少结块)。由于这个原因,分层抽样减少了蒙特卡罗估计的方差(我不认为这对你很重要,但这就是为什么这个方法被发明,作为方差方法的减少)。

按顺序生成数字是一个有趣的问题,但我的猜测是,要在整个时间间隔内获得均匀分布,您将不得不应用一些需要更多计算的公式。如果你想最大限度地减少计算时间,我怀疑你做得比生成样本然后对它进行排序要好。