C 生成具有几何分布的数字的最快方法

C 生成具有几何分布的数字的最快方法,c,random,binary,bit-manipulation,C,Random,Binary,Bit Manipulation,我想产生一个伪随机数,它的分布与硬币正面在第一个反面之前的抛硬币数相同 0: p = 0.5 1: p = 0.25 2: p = 0.125 ... 我如何才能有效地生成这样的分发?我一直在想办法做到这一点,而不为每次翻转产生随机位。我目前的理论是在均匀分布的随机数中计算前导0位的数量,但我一直无法找到一个好的参考或证明这是正确的 这是正常的脱融合衰减分布 您面临的问题不是如何确定这是正确的分布,而是如何生成具有此特性的随机生成器。通常,您以另一个随机数生成器为基础,并尝试应用一个函数,从已

我想产生一个伪随机数,它的分布与硬币正面在第一个反面之前的抛硬币数相同

0: p = 0.5
1: p = 0.25
2: p = 0.125
...

我如何才能有效地生成这样的分发?我一直在想办法做到这一点,而不为每次翻转产生随机位。我目前的理论是在均匀分布的随机数中计算前导0位的数量,但我一直无法找到一个好的参考或证明这是正确的

这是正常的脱融合衰减分布

您面临的问题不是如何确定这是正确的分布,而是如何生成具有此特性的随机生成器。通常,您以另一个随机数生成器为基础,并尝试应用一个函数,从已知属性的生成器中可以得到以新方式分布的数字

对于您的方法,我多次使用标准随机生成器[0..1]之间的平面数生成器作为源,如果我对其应用函数,让我们猜测一下logx函数,您将得到一个近似图,如下所示:

|->    x
|->      x
|->         x
|->              x
|->                         x
|->                                                            x
+====================================================================
而且它似乎与所需的点的累积近似匹配确实,这是正确的方法


这个函数的积分给出了X的概率,你是否考虑了特定的编程语言、硬件或操作系统?LZCNT可能会起作用,但它显然会在整数的宽度处达到顶点,而实际的翻转次数分布直到第一个尾部都不会达到顶点。64这个差别很小,但它是有区别的。那么它必须是多么接近?@ PATEO.C,和结果>32以后,永远都不需要,这就是为什么整数宽度不会是问题。@哈罗德OLOG log n,所以对于所有实际目的来说,32位是足够的。如果你愿意进入C++,有或者如果你需要真正的NUBBY。这是一个很好的答案,但是我很抱歉没有说得更清楚,我只对整数感兴趣,也就是说,投币次数不能是小数。我能把输出四舍五入吗?
|->                                                            X
|->                         X
|->              x
|->         X     
|->      X                   
|->    X                                                        
+====================================================================
       0
|          |
|    X     |
|          |
|  X       |
|X         |
+=============
 0         1
double y = -A * log(unit_random());
#include <math.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>

#include "gr.h"

double
geometric_random(void)
{
        double n = random();

        return -log(fabs(n) / INT_MAX);
} /* geometric_random */
$ make
$ gr -n 10000000 | mc -n 100 -b 20 >mc.out
                   n: 10000000
               sum_x: 10007209.0488715283572674
              sum_x2: 20023758.8835431151092052
               avg_x: 1.0007209048871528
              sdev_x: 1.0004667205707121
               min_x: 0.0000002696179218
               max_x: 17.2248827198513297
             below_A:      0
[0.0000000000000000, 0.2000000000000000]1811635
[0.2000000000000000, 0.4000000000000000]1484598: 0.8194796413184775
[0.4000000000000000, 0.6000000000000001]1213219: 0.8172037144061894
[0.6000000000000001, 0.8000000000000000]994937: 0.8200802987754066
[0.8000000000000000, 1.0000000000000000]813669: 0.8178095698521615
[1.0000000000000000, 1.2000000000000000]666035: 0.8185576690275775
[1.2000000000000000, 1.3999999999999999]545997: 0.8197722341918968
[1.3999999999999999, 1.5999999999999999]447841: 0.8202261184585263
[1.5999999999999999, 1.7999999999999998]365854: 0.8169283294740768
[1.7999999999999998, 1.9999999999999998]300525: 0.8214342333280489
[1.9999999999999998, 2.1999999999999997]246141: 0.8190366857998502
[2.1999999999999997, 2.3999999999999999]201303: 0.8178361183224250
[2.3999999999999999, 2.6000000000000001]164134: 0.8153579430013462
[2.6000000000000001, 2.8000000000000003]134768: 0.8210852108642938
[2.8000000000000003, 3.0000000000000004]110564: 0.8204024694289446
[3.0000000000000004, 3.2000000000000006] 90139: 0.8152653666654607
[3.2000000000000006, 3.4000000000000008] 74252: 0.8237499861325287
[3.4000000000000008, 3.6000000000000010] 60746: 0.8181059096051285
[3.6000000000000010, 3.8000000000000012] 49701: 0.8181773285483818
[3.8000000000000012, 4.0000000000000009] 40559: 0.8160600390334198
[4.0000000000000009, 4.2000000000000011] 33344: 0.8221109987918834
[4.2000000000000011, 4.4000000000000012] 27077: 0.8120501439539347
[4.4000000000000012, 4.6000000000000014] 22338: 0.8249806108505373
[4.6000000000000014, 4.8000000000000016] 18370: 0.8223654758707136
[4.8000000000000016, 5.0000000000000018] 15016: 0.8174197060424605
...