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

Zak*_*Zak 8 c++ random distribution

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

但我无法弄清楚,基于文档如何使用整数,更不用说设置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;
}
Run Code Online (Sandbox Code Playgroud)

给出结果:

aaz*_*aaz 9

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

行为与你描述的一样是:

  • binomial_distribution(t, p)

    此范围为0≤生成数字X牛逼,所以你需要通过翻译的范围min.平均值是t·p,所以选择p接近0.

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

  • poisson_distribution(?)

    这会产生数字0≤x<∞,但是大数字的可能性逐渐降低.你可以审查上面的任何内容,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是最可能的结果,并且每个后续数字都比前一个更不可能.再次选择参数以匹配前一个示例的平均值:

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

您还可以使用任何连续分布生成a double然后将其舍入到a int.


Mat*_*lia 6

除了在@aaz的伟大答案中所说的分布之外,请记住,您还可以使用逆变换采样将您的均匀分布转换为您可能想到的任何概率分布函数(但实际上只对某些" 不好" "函数"或拒绝抽样(可以在任何情况下应用,但计算上可能很昂贵).

在我看来,符合您需求的分布将是(负)指数分布:

指数分布

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

x = - ln(1-p)/lambda
Run Code Online (Sandbox Code Playgroud)

with p是来自均匀分布的随机值,lambda是指数分布的参数; 请看这里了解更多信息.

一旦你得到x(将是一个double),只需将它投射到int(或用以下函数围绕它:

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

)获得你的结果.


编辑

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