生成小于4位的随机数,但其具有1,2或3位的概率相等

时间:2016-05-06 13:13:03

标签: c++ random distribution

我目前正在使用1 + (int)(rand() * 999.0 / RAND_MAX)生成1到999之间的随机数,但两位数和一位数的数字并不像三位数那样频繁出现。

我该如何解决这个问题?

请注意,虽然原始代码的范围为0到999(含),但我实际上需要1到999的范围。

3 个答案:

答案 0 :(得分:29)

您观察到一位数字不会像两位数和三位数一样频繁出现并不奇怪。

只有9个一位数字(不包括零),但有90个两位数字,900个三位数字。因此,统一的随机数生成器将在该频率中绘制数字。

要生成[1,999]范围内的随机数,使其具有1,2和3位数的概率相等,请使用您喜欢的生成器生成随机数p,例如,范围[0,1](参见C ++中的新随机库函数),并使用std::pow(1000, p);对其进行转换。

您应该注意,生成的分布不会是分段均匀:也就是说绘制具有一定数字位数的数字的概率与绘制概率不同具有该位数的任何其他数字。但它确实具有连续且可微分的累积密度函数,这在数学上很重要。

(对于数学倾向,我应用的转换是OP需要的分布的分位数函数。)

答案 1 :(得分:20)

你也可以使用更快一点的if语句:

    int m=rand();
    if(m%3+1==3)
        z=(int)rand()%900+100;
    else if(m%3+1==2)
        z=(int)rand()%90+10;
    else if(m%3+1==1)
        z=(int)rand()%10;

100,000,000次重复的clock()差异是:

t_pow: 23912
t_if: 6640

使用时钟滴答测试代码以进行性能分配 - IFPOW

if和pow变体之间的分布差异:Plot in wolframalpha.com

答案 2 :(得分:2)

您可以在一个使用2个random的语句中执行此操作。将第一个乘以10 **秒。第二个是1,2或3.这里是一个Excel公式:

=Int(Rand()*10^(int(Rand()*3)+1))