【问题标题】:creating a non-uniform, integer distribution using tr1 <random>使用 tr1 <random> 创建非均匀整数分布
【发布时间】:2011-07-14 20:55:25
【问题描述】:

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

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&lt;int&gt; 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;
}

给出结果:

【问题讨论】:

  • 在泊松分布中,如果您选择小于 1 的参数(当前为 (20−0)*.1 = 2),0 将比 1 更频繁。您还可以通过具有任何参数的几何分布来获得它。您应该选择的模型取决于您要建模的内容:几何模型是事件发生之前的时间(例如,进球所需的射门次数),泊松模型是时间间隔内事件发生的次数(例如,次数比赛中的进球数)。
  • 好吧,我将它用于实时遗传算法。当需要培育一种新生物时,我不会有不同的世代,而是根据适应度对它们进行排序,然后根据这条曲线选择父母。
  • @Zak – 如果您使用几何分布进行选择,那么您可以将每个父母的选择描述为#1 vs (#2 的获胜者 vs (#3 的获胜者 vs ... )),其中 #i 以概率 p 战胜任何 #j,i
  • @Zak:在我看来,您的图表仍然是负指数分布;我会直接使用它。
  • @Matteo & @Zak – 是的,chi_square_distribution(2) 是一个与exponential_distribution(.5) 相同的特殊情况。此外,max*exponential_distribution(.5)/10exponential_distrubtion(max*.5/10) 相同,floor(exponential_distribution(max*.5/10))geometric_distribution(1-exp(-max*.5/10)) 相同。

标签: c++ random distribution


【解决方案1】:

除了 @aaz 的出色答案中所说的分布之外,请记住,您还可以使用 inverse transform sampling 将均匀分布转换为您可能想到的任何概率分布函数(然而,这实际上只适用于一些“不错”的功能)或rejection sampling(可以在任何情况下应用,但计算成本可能很高)。

在我看来,适合您需求的发行版将是(否定的)exponential distribution

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

x = - ln(1-p)/lambda

其中p是均匀分布的随机值,lambda是指数分布的参数;请参阅here 了解更多信息。

一旦你得到x(这将是一个double),只需将其转换为int(或使用类似以下的函数将其四舍五入:

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

) 来获得你的结果。


编辑

顺便说一句,我没有注意到&lt;random&gt;link)中甚至已经包含了指数分布...好吧,更好的是,您不需要编写代码,但是一点一点理论永远不会浪费:)

【讨论】:

    【解决方案2】:

    那里还有其他整数分布,只是它们的名称中没有int。他们的类定义中有typedef IntType result_type

    如您所描述的行为是:

    • binomial_distribution(t, p)

      这会生成 0 ≤ xt 范围内的数字,因此您需要将范围转换为 min。均值在t·p,所以选择一个接近0的p

      std::binomial_distribution&lt;int&gt; dist(max - min, .1);
      return dist(gen) + min;

    • poisson_distribution(λ)

      这会生成 0 ≤ x max 以上的任何内容以将其限制在一个范围内。参数 λ 是平均值。选择它来匹配前面的例子:

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

    • geometric_distribution(p)

      也生成数字 0 ≤ x

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

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

    【讨论】:

      猜你喜欢
      • 2018-02-06
      • 2011-04-04
      • 1970-01-01
      • 2013-07-22
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 2017-07-16
      • 2021-02-10
      相关资源
      最近更新 更多