改善"随机性"当扩展rand()的范围时

时间:2014-05-07 16:57:14

标签: c algorithm random statistics

我正在使用我在其他SO帖子(在下面的参考文献中列出)中找到的一对算法,并且我正在尝试找出如何改进分发。我通过将位数加倍来有效地扩展随机数的范围,并且希望确保分布尽可能均匀,同时消除(或至少减少)模偏差和其他伪像对混洗算法的影响这将使用我修改的随机数生成器的结果。

所以,据我所知,如果我使用常量种子初始化我的RNG(即:srand(1)),我将在{{1}中调用rand()来获得相同的确定性输出模式循环。现在,如果我通过for初始化我的种子,它将是一个不同的模式,但它仍然可能无法帮助我解决以下问题:我试图弄清楚我是否要实现以下算法:

  • 取两个随机数a,b
  • 计算a *(RAND_MAX + 1)+ b

我可以:

  1. 生成每个可能的坐标对(a,b),其中srand(time(NULL))a,b ∈ Z+ on [0, RAND_MAX]a是零到b之间的正整数。
  2. 最大化整个分布的均匀性(即:最佳平坦的直方图)。
  3. 虽然RAND_MAX的输出应该是均匀分布的,但我不知道它是否能保证给我N次,N + 1次调用的值来每次循环并给出在随机序列再次重复之前,每一对列在第(1)点。 我的新随机数生成器理论上可以在rand()上生成随机值,但我不知道是否存在"漏洞"也就是我的算法永远无法生成此范围内的值。

    我试图自己进一步研究这个问题,但是我无法找到有关C中随机序列产生[0, RAND_MAX ^ 2]多长时间的信息,直到它重复出现为止。由于缺少这些信息和其他信息,我无法弄清楚是否有可能生成每一对(a,b)。

    所以,使用rand(),是否有可能实现点(1),如果是这样,是否有任何关于如何优化其随机性的可靠建议"根据第(2)点?

    感谢您的时间和帮助。

    更新

    我后来重新讨论了这个问题并使用8位PRNG进行了模拟。虽然它确实可以生成所有可能的坐标对,但实际上分布非常有趣,并且绝对不均匀。最后,我阅读了几篇有关PRNG的文章/论文,并使用Mersenne Twiser算法生成所需的额外位(即MT19937-64)。

    参考


    1. 延长rand()最大范围,访问次数2014-05-07,<https://stackoverflow.com/questions/9775313/extend-rand-max-range>
    2. C 中的随机数组,访问日期2014-05-07,<https://stackoverflow.com/questions/6127503/shuffle-array-in-c>

1 个答案:

答案 0 :(得分:1)

假设

正如评论中所指出的,rand()的行为取决于实现。所以,让我们做一些简化的假设来解决问题:

  • rand()可以生成从0RAND_MAX的所有值。 Justfication :如果不能,那么生成所有可能的对( a b )就更难了。
  • rand()生成统计随机序列。 对齐:组合两个随机函数(或两次相同的函数)的结果仅与基本随机函数一样好。

当然,我们不应期望结果比构建块更好,因此rand()实现中的任何缺陷都将反映在由它组成的任何函数中。

分发中的漏洞

种子rand()生成给定种子的确定性序列,因为种子确定了PRNG的初始状态。序列的最大周期为2 N 其中 N 是状态中的位数。请注意,该状态实际上可能比RAND_MAX具有更多位,我们将假设RAND_MAX =(2 N - 1) 。因为它是序列,所以生成两个连续的“随机” N 位值a和b意味着 a b 。因此,方法 a *(RAND_MAX + 1)+ b 会有一些漏洞。

a b 的一点解释:PRNGs通过维持 N 位的内部状态来工作。它唯一地使用该状态来确定其下一个状态,因此一旦相同的状态再次出现,序列就开始重复。序列开始重复之前经历的状态数称为句点。因此,从技术上讲,我们可以 a = b ,但这意味着一段时间为1,那就是very bad PRNG。有关详细信息,已在软件工程网站上发布了helpful answer on PRNG periods

无洞算法

允许连续“随机”调用相等的一种方法是生成2 N 位数,但只考虑一定数量的位有效,即丢弃一些。现在,我们可以 a = b ,但非常的概率略小于另一个随机数 c 。请注意,这与Java's random number generator的工作方式类似。它以48位播种,但输出一个32位的随机数,丢弃16位(假设种子中的位数=状态中的位数#。)

但是,由于您需要大于RAND_MAX的值,您可以使用上述方法,然后连接这些位,直到您获得足够的位以达到所需的最大值(尽管再次,分布是不太统一)。