【问题标题】:Objective-C: Modulo biasObjective-C:模偏差
【发布时间】:2009-03-15 22:51:21
【问题描述】:

使用:

value = arc4random() % x

如何避免或消除模偏差?

至少根据 Wikipedia 的说法,在编写概率游戏时,模偏差是一个问题。

【问题讨论】:

  • 考虑将 Zoidberg 的答案重新标记为正确答案,因为根据 arc4random() 的作者,这是规范的正确答案。

标签: objective-c random


【解决方案1】:

使用arc4random_uniform(x)。这是为你做的。

根据手册页:

arc4random_uniform() 将返回小于upper_bound 的均匀分布随机数。推荐 arc4random_uniform() 而非 arc4random() % upper_bound 之类的结构,因为当上限不是 2 的幂时,它可以避免“模偏差”。

【讨论】:

    【解决方案2】:

    arc4random 返回一个 32 位无符号整数(0 到 232-1)。

    对于足够小的 x,可能不会有明显的模偏差。但是,如果您想真正确定,请执行以下操作:

    y = 2p 其中 2p-1p

    val = arc4random() % y;
    while(val >= x)
        val = arc4random() % y;
    

    【讨论】:

    • 如果我记得,Python 的随机数生成器中有类似的东西。
    • 我碰巧遇到了同样的任务,C 实现可以在 OpenBSD arc4random_uniform() src/sys/dev/rnd.c 找到
    【解决方案3】:
    u_int32_t maxValue = ~((u_int32_t) 0);      // equal to 0xffff...
    maxValue -= maxValue % x;                   // make maxValue a multiple of x
    while((value = arc4random()) >= maxValue) { // loop until we get 0 ≤ value < maxValue
    }
    value %= x;
    

    尽管除非您使用任何低于一百万(或更多)的 x,否则我不会担心

    【讨论】:

      【解决方案4】:

      如果arc4random mod x 的最大值大于x,则忽略大于最大值arc4random-max mod x 的任何值,而是再次调用arc4random

      【讨论】:

        【解决方案5】:
        u_int32_t maxValue = ~((u_int32_t) 0);      // equal to 0xffff...
        maxValue -= maxValue % x;                   // make maxValue a multiple of x
        while((value = arc4random()) >= maxValue) { // loop until we get 0 ≤ value < maxValue
        }
        value %= x;
        

        对 cobbal 的回答有些迂腐的反对。它“有效”,即它消除了模偏差,但它拒绝了比必要更多的值。最极端的情况是 x = 2^31。 arc4random() 的所有值都应在此处接受,但编写的代码将拒绝其中的一半。

        相反,将 1 添加到 maxValue 的初始化(将其置于 2^32,因此您必须使用 64 位 int),然后就对了。您还可以避免使用 64 位 int。预先测试是否 2^32 % x == 0,如果是,则所有 arc4random() 值都可接受,您可以跳过循环,否则您可以通过在初始化时减去 2^32 % x 来保持 maxValue 为 32 位。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-09-21
          • 2013-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-16
          • 2022-09-29
          相关资源
          最近更新 更多