Objective-C的:模偏置

问题描述 投票:13回答:6

使用:

value = arc4random() % x

如何避免或消除模偏见?

至少根据维基百科,编程游戏的机会,当模偏差是一个问题。

objective-c random
6个回答
14
投票

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

有可能将是足够小x没有noticable模偏置。但是,如果你想成为真正的肯定,这样做:

Y = 2P其中2P-1 <X≤2P

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

49
投票

使用arc4random_uniform(x)。这会为你。

根据手册页:

arc4random_uniform()将返回比upper_bound少了均匀分布的随机数。 arc4random_uniform()建议过像,因为它避免“模数偏压”的时候,上限不是二的幂arc4random() % upper_bound结构。


4
投票
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下一个百万(或更多),我不会担心


2
投票

如果arc4random MOD x的最大值比x时,忽略超过最大arc4random-max mod x更大的任何值,调用arc4random再次来代替。


1
投票
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%×== 0,如果是的话所有arc4random()的值是可接受的,并且可以跳过循环,否则可以通过在初始化减去2 ^ 32%×32位保持包括maxValue。


-2
投票

使用下面的方法。它避免了“模数偏见”和它`快于iPhone。节省你的CPU周期。

如果你想4-7:

(random() / (float)RAND_MAX )*3+4

或者如果你想0-8

(random() / (float)RAND_MAX )+8
© www.soinside.com 2019 - 2024. All rights reserved.