产生这种随机分布的更有效方法?

ala*_*ere 3 c++ random math

是否有更高效,可能更数学和更少算法的方法来实现类似的随机数分布?

unsigned int weighted_random_UINT()
{
    float r2 = 1;
    while(rand() % 4 != 0) // 3/4 chance
    {
        r2 *= fmod(
            ((float)rand()/RAND_MAX)+1, // random float between 1 and 2
            (float)UINT_MAX
        );
    }
    return (unsigned int)r2 - 1;
}
Run Code Online (Sandbox Code Playgroud)

下面是一个不太安全但更容易阅读的版本.

r2 *= ((float)rand()/RAND_MAX)+1;
Run Code Online (Sandbox Code Playgroud)


分布可视化: 分布可视化
问题中更平滑的解决方案(第一个图表)与最佳答案中的更快解决方案(第二个图表)之间的比较: 比较http://with-logic.co.uk/a/graph.png

nul*_*nge 5

我认为你不必遍历它,但一旦足够,就像这样:

unsigned int weighted_random_UINT()
{
    float r2 = ((float)rand()/RAND_MAX)+1; // random float between 1 and 2
    unsigned int k = 0;
    while(rand() % 4 != 0) // 3/4 chance
    {k = k < UINT_MAX ? k + 1: UINT_MAX;}
    return (unsigned int)fpow(r2,(float)k) - 1;
}
Run Code Online (Sandbox Code Playgroud)

第一部分是几何分布,最后一部分是均匀分布.你想要的(1+U(0,1))^G(3/4).

应该可以找到一些更快的方法来找到G(3/4).

编辑: 我在维基百科上找到了它:http: //en.wikipedia.org/wiki/Geometric_distribution#Related_distributions

G(p)=floor(ln(U)/ln(1-p))
Run Code Online (Sandbox Code Playgroud)

因此你想:

U^floor(ln(U)/ln(1-3/4))
Run Code Online (Sandbox Code Playgroud)

这应该只是两次调用rand.