是否有更高效,可能更具数学性和更少算法的方法来实现类似的随机数分布?
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;
}
下面是一个不太安全但更容易阅读的内幕版本。
r2 *= ((float)rand()/RAND_MAX)+1;
<小时/> 分布可视化:
答案 0 :(得分: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;
}
第一部分是几何分布,最后一部分是均匀分布。
你想要(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))
因此你想:
U^floor(ln(U)/ln(1-3/4))
这应该只是两次调用rand。