使用tr1 <random> </random>创建非均匀整数分布

时间:2011-03-14 09:05:04

标签: c++ random distribution

现在我使用以下代码创建一个带有范围的整数的均匀分布。 (我拿出了播种代码)

int random(int min, int max)
{
    static std::mt19937 gen;
    std::uniform_int<int> dist(min, max);
    return dist(gen);

}

我试图修改它以给出一个有利于最小值的分布的分布,并且几乎从不产生接近最大值。我可以看到所有预先制作的发行版,但它们都不是整数。而且我无法根据任何文档判断哪一个符合我的需求。我最接近的是维基百科上显示的卡方分布,其中k = 2

但我无法弄清楚,基于documentation如何使用整数,更不用说设置k值。

如何设置我的函数以使用适当的非均匀整数分布?


仍在努力选择正确的发行版:以下是std::poisson_distribution<int> dist((max - min) * .1);从0到20的结果:   

还没有完全存在,因为0应该比1更频繁,但它应该有助于下一个人,将会发布更多结果。


我的最终解决方案成为了一系列方法:

int randomDist(int min, int max)
{
    static std::mt19937 gen;
    std::chi_squared_distribution<double> dist(2);

    int x;
    do
    {
    x = (int)(max*dist(gen)/10) + min;
    }
    while (x > max);
    return x;
}

给出结果:

2 个答案:

答案 0 :(得分:9)

还有其他整数分布,它们名称中没有int。他们的班级定义确实有typedef IntType result_type

您描述的行为是:

  • binomial_distribution (t, p)

    这会生成0≤ x t 范围内的数字,因此您需要将范围转换为min。平均值位于 t·p ,因此请在0附近选择 p

    std::binomial_distribution<int> dist(max - min, .1);
    return dist(gen) + min;

  • poisson_distribution (λ)

    这产生数字0≤x<0。 ∞,但是大数字的可能性逐渐降低。您可以审查max以上的任何内容,将其限制在某个范围内。参数λ是平均值。选择它以匹配前面的示例:

    std::poisson_distribution<int> dist((max - min) * .1);
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

  • geometric_distribution (p)

    还产生数字0≤x<0。 ∞,但0是最可能的结果,并且每个后续数字都不太可能。再次选择参数以匹配前一个示例的平均值:

    std::geometric_distribution<int> dist(1 / ((max - min) * .1 + 1));
    int x;
    do
        x = dist(gen) + min;
    while (x > max);
    return x;

您还可以使用任何连续分布生成double,然后将其四舍五入为int

答案 1 :(得分:6)

除了在 @aaz 的答案中说的分布之外,请记住,您还可以使用{{3}将均匀分布转换为您可能想到的任何概率分布函数。 (但实际上只对某些“漂亮”函数可行)或inverse transform sampling(在任何情况下都可以应用,但计算成本很高)。

在我看来,符合您需求的分布将是(负面的)rejection sampling

Exponential distribution

幸运的是,它是您可以应用逆变换采样的分布之一,这意味着,从均匀[0,1]分布中获取样本,您可以通过应用公式得到指数分布:

x = - ln(1-p)/lambda
带有p

是来自均匀分布的随机值,lambda是指数分布的参数;有关详细信息,请参阅exponential distribution

获得x(这将是double)之后,只需将其投放到int(或使用以下函数对其进行舍入:

int round(double val)
{
    // warning: can give counterintuitive results with negative numbers
    return int(val+0.5);
}

)获得你的结果。


<强> 修改

顺便说一下,我没有注意到即使是指数分布已经包含在<random>here)中......好吧,甚至更好,你不需要编写代码,但是一点点的理论永远不会浪费:)

相关问题