【问题标题】:Fast C random boolean generator快速 C 随机布尔生成器
【发布时间】:2018-05-09 14:03:56
【问题描述】:

我有兴趣在 C 中生成快速随机布尔值(或等效的 Bernoulli(0.5) 随机变量)。当然,如果有一个具有良好统计行为的快速随机生成器,那么问题“对随机 Bernoulli(0.5) 进行采样” " 很容易解决:在 (0,1) 中均匀采样x,如果x<0.5,则返回1,否则返回0

假设速度是最重要的,现在我有两个问题/考虑:

  1. 许多随机双精度数生成器首先在一定范围内统一生成整数m[0,M],然后简单地返回除法m/M。只检查m < M/2是否会更快(这里M/2是固定的,所以我们节省了一个部门)

    1. 有更快的方法吗?最后,我们在这里要求的统计属性要少得多:我们可能仍然对很长一段时间感兴趣,但是,例如,我们不关心分布的均匀性(只要大约 50% 的值在范围的前半部分)。

【问题讨论】:

  • 你的问题是如何写或者在哪里可以找到这样的东西?
  • 对于随机布尔值,clock()&1 就足够了。
  • (1) 您可以只进行概要分析和比较。 (2) 假设一个完美的输入 RNG,你可以从每个随机整数中提取 32 个(或任何你的单词大小)随机布尔值。
  • 只需使用您平台上可用的 random 函数(randrandomarc4random 等)并保留返回值的一位.
  • 生成一个无符号的 64 位整数并将这些位用作布尔值。这就像在 1 次中生成 64 个布尔值。

标签: c performance random boolean


【解决方案1】:

我对生成快速随机布尔值很感兴趣

使用LCG 可能很快,但由于 OP 只需要 bool 结果,请考虑从合理的生成器中一次仅提取 1 位,并将其余部分保存以备后用。 @Akshay L Aradhya

基于@R..@R.. 代码的示例。

extern uint32_t lcg64_temper(uint64_t *seed); // see R.. code

static uint64_t gseed; //  Initialize this in some fashion.
static unsigned gcount = 0;

bool rand_bool(void) {
  static uint32_t rbits;
  if (gcount == 0) {
    gcount = 32;  // I'd consider using 31 here, just to cope with some LCG weaknesses.
    rbits = lcg64_temper(&gseed);  
  }
  gcount--;
  bool b = rbits & 1;
  rbits >>= 1;
  return b;
}

【讨论】:

  • 我想知道在常见用例中这是否会比我的解决方案更快?
  • @Bathsheba 许多未知数,尤其是宽整数乘法的成本。成本越高,提取 1 位并保存其余位就越有利可图。 fuzzy 部分是 low a quality random number 生成器如何满足 OP 对随机性与速度的需求?
  • 都一样。
【解决方案2】:

提取随机数的最后一位可能会造成严重破坏,因为线性同余生成器可以在奇数和偶数之间交替1。像clock() & 1 这样的方案也会有可怕的相关性。


考虑基于 Donald Kunth 的快速而肮脏的生成器的解决方案:对于uint32_t I,序列

I = 1664525 * I + 1013904223;

2 * I < I 是产生布尔图形的条件。在这里,我依赖于 I 的环绕行为,这种行为应该会发生一半,并且避免了潜在的昂贵除法。

测试I <= 0x7FFFFFFF 不那么花哨,可能还更快,但中点的硬编码并不完全令人满意。


1 我在这里介绍的生成器可以。

【讨论】:

    猜你喜欢
    • 2016-02-21
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 2012-03-13
    • 2013-10-12
    • 2017-09-05
    • 2015-12-29
    相关资源
    最近更新 更多