2011-03-14 22 views
8

我用下面的代码来创建整数与一范围内均匀分布。 (我拿出播种代码)眼下创建非均匀,整分配使用TR1 <random>

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

} 

我想修改它给予有利于twords最小值分布,几乎从不接近最大值。我可以看到所有预先制作的发行版,但没有一个是整数。而且我也无法根据任何文档分辨哪一个符合我的需求。我来最接近的是卡方分布如图所示在维基百科上,其中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; 
} 

给出的结果是:

+0

在泊松分布中,如果选择小于1的参数(当前(20-0)*。1 = 2),则0会比1更频繁。您还可以通过任何参数进行几何分布。您应该选择哪一个取决于您正在建模的内容:几何模型直到事件发生的时间(例如,评分目标所需的投篮次数),泊松模型在一段时间内(例如,数字游戏中的目标)。 – aaz 2011-03-14 12:33:51

+1

那么我用它来实时遗传算法。与其有独特的一代,当我们开始培育一种新的有机体时,我通过健身来挑选它们,并根据这条曲线选择父母。 – Zak 2011-03-14 21:54:22

+0

@Zak - 如果选择使用几何分布,则可以将每个父母的选择描述为#1 vs(#2 vs(获胜者#3 vs ...))的比赛),其中#i获胜对任何#j,我 aaz 2011-03-14 22:41:04

回答

9

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

其表现为你描述的是:

  • binomial_distribution(t, p)

    此范围内生成数字0≤X,所以你需要通过翻译的范围min。均值是在吨·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;

您也可以使用任何连续分布来生成一个double然后四舍五入它到int

6

除了分布在说@aaz“伟大的回答,请记住,你也可以改变你的均匀分布,以你可能想到的任何概率分布函数,使用inverse transform sampling(即但是实际上是可行的只有对于一些“好”功能)或rejection sampling(可以在任何情况下应用,但是可能在计算上是昂贵的)。

在我看来,这将满足您的需求分布将是(负)exponential distribution

Exponential distribution

幸运的是,这是你可以申请反变换抽样分布之一,这意味着,从均匀具有样品[0,1]的分布,可以通过应用下面的公式得到一个指数分布:

x = - ln(1-p)/lambda 

p是随机VAL ue从均匀分布和lambda是指数分布的参数;有关更多信息,请参阅here

一旦你x(这将是一个double),只是它(与函数或圆形像:

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

)转换为int获得你的结果。


编辑

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