Math 模行为背后的数学

Math 模行为背后的数学,math,random,statistics,probability,modulo,Math,Random,Statistics,Probability,Modulo,序言 这个问题与PRNG和rand的行为无关。这是关于利用两个均匀分布的值对模的幂 导言 我知道,不应该使用模%将一个值从一个范围转换为另一个范围,例如,从rand函数获得一个介于0和5之间的值:将存在偏差。在这里和这个答案中都有解释 但是今天在调查了一些看起来错误的代码之后,我制作了一个工具来演示模的行为:发现这还不够清楚 一个骰子只有3位 我检查了范围为0到5的6个值。对这些值进行编码只需要3位 $ ./modulo-test 10000 6 3 interations = 10000, r

序言

这个问题与PRNG和rand的行为无关。这是关于利用两个均匀分布的值对模的幂

导言

我知道,不应该使用模%将一个值从一个范围转换为另一个范围,例如,从rand函数获得一个介于0和5之间的值:将存在偏差。在这里和这个答案中都有解释

但是今天在调查了一些看起来错误的代码之后,我制作了一个工具来演示模的行为:发现这还不够清楚

一个骰子只有3位

我检查了范围为0到5的6个值。对这些值进行编码只需要3位

$ ./modulo-test 10000 6 3
interations = 10000, range = 6, bits = 3 (0x00000007)
  [0..7] => [0..5]

theorical occurences    1666.67 probability 0.16666667

   [   0] occurences    2446    probability 0.24460000 ( +46.76%)
   [   1] occurences    2535    probability 0.25350000 ( +52.10%)
   [   2] occurences    1275    probability 0.12750000 ( -23.50%)
   [   3] occurences    1297    probability 0.12970000 ( -22.18%)
   [   4] occurences    1216    probability 0.12160000 ( -27.04%)
   [   5] occurences    1231    probability 0.12310000 ( -26.14%)

  minimum occurences    1216.00 probability 0.12160000 ( -27.04%)
  maximum occurences    2535.00 probability 0.25350000 ( +52.10%)
     mean occurences    1666.67 probability 0.16666667 (  +0.00%)
   stddev occurences     639.43 probability 0.06394256 (  38.37%)
使用3位输入,结果确实很糟糕,但表现与预期一样。见答案

增加输入位数

让我困惑的是,增加输入位数会使结果不同。 您不应该忘记增加迭代次数,例如样本数,否则结果可能是错误的,请参阅错误的统计数据

让我们尝试使用4位:

$ ./modulo-test 20000 6 4
interations = 20000, range = 6, bits = 4 (0x0000000f)
  [0..15] => [0..5]

theorical occurences    3333.33 probability 0.16666667

   [   0] occurences    3728    probability 0.18640000 ( +11.84%)
   [   1] occurences    3763    probability 0.18815000 ( +12.89%)
   [   2] occurences    3675    probability 0.18375000 ( +10.25%)
   [   3] occurences    3721    probability 0.18605000 ( +11.63%)
   [   4] occurences    2573    probability 0.12865000 ( -22.81%)
   [   5] occurences    2540    probability 0.12700000 ( -23.80%)

  minimum occurences    2540.00 probability 0.12700000 ( -23.80%)
  maximum occurences    3763.00 probability 0.18815000 ( +12.89%)
     mean occurences    3333.33 probability 0.16666667 (  +0.00%)
   stddev occurences     602.48 probability 0.03012376 (  18.07%)
让我们尝试使用5位:

$ ./modulo-test 40000 6 5
interations = 40000, range = 6, bits = 5 (0x0000001f)
  [0..31] => [0..5]

theorical occurences    6666.67 probability 0.16666667

   [   0] occurences    7462    probability 0.18655000 ( +11.93%)
   [   1] occurences    7444    probability 0.18610000 ( +11.66%)
   [   2] occurences    6318    probability 0.15795000 (  -5.23%)
   [   3] occurences    6265    probability 0.15662500 (  -6.03%)
   [   4] occurences    6334    probability 0.15835000 (  -4.99%)
   [   5] occurences    6177    probability 0.15442500 (  -7.34%)

  minimum occurences    6177.00 probability 0.15442500 (  -7.34%)
  maximum occurences    7462.00 probability 0.18655000 ( +11.93%)
     mean occurences    6666.67 probability 0.16666667 (  +0.00%)
   stddev occurences     611.58 probability 0.01528949 (   9.17%)
让我们尝试使用6位:

$ ./modulo-test 80000 6 6
interations = 80000, range = 6, bits = 6 (0x0000003f)
  [0..63] => [0..5]

theorical occurences   13333.33 probability 0.16666667

   [   0] occurences   13741    probability 0.17176250 (  +3.06%)
   [   1] occurences   13610    probability 0.17012500 (  +2.08%)
   [   2] occurences   13890    probability 0.17362500 (  +4.18%)
   [   3] occurences   13702    probability 0.17127500 (  +2.77%)
   [   4] occurences   12492    probability 0.15615000 (  -6.31%)
   [   5] occurences   12565    probability 0.15706250 (  -5.76%)

  minimum occurences   12492.00 probability 0.15615000 (  -6.31%)
  maximum occurences   13890.00 probability 0.17362500 (  +4.18%)
     mean occurences   13333.33 probability 0.16666667 (  +0.00%)
   stddev occurences     630.35 probability 0.00787938 (   4.73%)
问题:

请向我解释为什么在更改输入位并相应增加样本计数时结果会不同?这背后的数学推理是什么

错误的统计数字

在问题的前一个版本中,我展示了一个32位输入的测试,只有1000000次迭代,例如10^6个样本,我说我对得到正确的结果感到惊讶。 这是如此错误,我感到惭愧:必须有N倍多的样本才能有信心获得生成器的所有2^32值。这里10^6比2^32小。对能够用数学/统计语言解释这一点的人的奖励

以下是错误的结果:

$ ./modulo-test 1000000 6 32
interations = 1000000, range = 6, bits = 32 (0xffffffff)
  [0..4294967295] => [0..5]

theorical occurences  166666.67 probability 0.16666667

   [   0] occurences  166881    probability 0.16688100 (  +0.13%)
   [   1] occurences  166881    probability 0.16688100 (  +0.13%)
   [   2] occurences  166487    probability 0.16648700 (  -0.11%)
   [   3] occurences  166484    probability 0.16648400 (  -0.11%)
   [   4] occurences  166750    probability 0.16675000 (  +0.05%)
   [   5] occurences  166517    probability 0.16651700 (  -0.09%)

  minimum occurences  166484.00 probability 0.16648400 (  -0.11%)
  maximum occurences  166881.00 probability 0.16688100 (  +0.13%)
     mean occurences  166666.67 probability 0.16666667 (  +0.00%)
   stddev occurences     193.32 probability 0.00019332 (   0.12%)

我仍然需要反复阅读的优秀文章。

本质上,你在做:

(rand() & 7) % 6
假设rand均匀分布在[0;rand_MAX]上,rand_MAX+1是2的幂。很明显,rand&7可以评估为0,1,…,7,并且结果是等概率的

现在,让我们看看当取模6的结果时会发生什么

0和6映射到0; 1和7映射到1; 2张地图到2张地图; 3张地图到3张地图; 4张地图到4张地图; 5张地图到5张地图。 这就解释了为什么你得到的0和1是其他数字的两倍

第二种情况也是如此。然而,额外数字的值要小得多,这使得它们的贡献与噪声难以区分

总之,如果在[0;M-1]上有一个均匀分布的整数,并且取其模N,则结果将偏向于零,除非M可被N整除。

rand或某些其他PRNG在[0..rand\u MAX]区间内产生值。您希望使用余数运算符将这些映射到间隔[0..N-1]

0=r。
现在,如果q很小,那么q和q+1之间的相对差值很大,但是如果q很大,比如说-2^32/6,那么这个差值就不容易测量。

这一切都有意义吗?我是说,你难道不希望他们有所不同吗?2/8比4/4294967296大得多。不建议使用rand%N,因为一些旧的?rand的实现在低位的顺序结果中显示模式。即使rand在您的实现中确实是随机的,但这并不意味着每个人都可以安全地依赖它。@aschepler,我想他是在问,如果生成的随机数范围不能被您试图得到的范围整除,那么对较低结果的固有偏见。这本身并不受随机数生成器实现的随机性或缺乏随机数生成器实现的影响。只是偏差不太明显,因为40亿中只有4个额外值,而不是8中的2个。谢谢你的解释。我知道基本行为,不觉得有必要在问题中描述它。关于32位输入的例子,由于样本数减少,它是错误的。所以这基本上是我的错误。我改变了问题,修正了样本数量,问了一个不同但相关的问题。
(RAND_MAX+1) = q*N + r