1

语境

基于人口的增量学习 (PBIL) 算法的一部分是计算许多有偏的随机位。每个位的偏差由 0.0-1.0 范围内的相应双精度数确定。

对于每个位,将 0.0-1.0 范围内的无偏随机双精度与偏差进行比较。如果生成的随机双精度值小于偏差,则该位设置为 0,否则为 1。

在生成有偏差的位序列后,这些位将转换为各种范围内的双精度数。

问题

我想直接在一个范围内生成一个有偏差的双精度。那是没有操纵双重表示中的每一位。然后每个双精度数将有一个变量来确定偏差(不是每个位一个)。如前所述,每个双精度数也具有确定随机双精度数的下限和上限的最小和最大常数。

以下示例生成可接受的分布。但是,如果没有潜在的无休止的 while 循环来解决问题,那就太好了。

public double getBiasedRandom(double bias, double min, double max) {
    double rndBiased;
    double variance = (max-min)*0.3;

    do {
         rndBiased = bias + (random.nextGaussian() * variance);
    } while(rndBiased < min && rndBiased <= max);

    return rndBiased;
}

解决方案不必返回相同的分布,但范围内的所有值都必须是任何偏差的可能结果。此外,更接近偏差的值应该比更远的值更有可能。我不知道多少。理想情况下,它将由可以通过实验设置的变量确定。在上面的例子中,这个变量是常数 0.3。

我试图研究不同的分布,但我的数学技能不足。还要记住,性能是至关重要的,一个近似但有效的解决方案可能是有利的。出于同样的原因,依赖于加权表的解决方案可能不值得。

编辑:添加了一个受 Cristiano Zambon 回答启发的潜在解决方案。

4

1 回答 1

1

如果我理解得很好,你只需要一个函数,它返回一个随机编号的“居中”偏差,并且总是在 {min;max} 范围内......

关于什么:

public double getBiasedRandom(double bias, double min, double max) {
    double bias_depth_perc = 0.1;
    double bias_depth_abs = (max - min)*bias_depth_perc;
    double min_bias = bias - bias_depth;
    double max_bias = bias + bias_depth;
    Random tRandom = new Random();

    if (max_bias > max) max_bias = max;
    if (min_bias < min) min_bias = min;

    double variance = (max_bias - min_bias)/2;


    double rndBiased = bias + tRandom .nextGaussian() * aVariance;

    if (rndBiased > max)
       rndBiased = max - (rndBiased - max);

    if (rndBiased < min)
       rndBiased = min + (min - rndBiased);

    return rndBiased;
}

实际上,您只需使用以偏差为中心的高斯分布即可获得有偏差的随机数,其方差可以设置为范围的百分比(在示例中设置为双偏差深度 perc = 0.1 行的 10%)。

编辑:当偏差接近边界并且你得到很多超出限制的随机数时改变了行为。现在它只是简单地复制边界内的随机生成数,其距离等于与限制本身的距离。这实际上以简单的不对称分布结束。

第二个解决方案:这有点棘手。这里的想法是始终生成一个对称的随机数,然后将生成的数字映射到正确的范围内。例如:如果您有:

  • 最小值 = 0
  • 最大值 = 1
  • 偏差 = 0.1

您首先生成一个以 0.5 为中心的随机数,并带有您选择的方差:

  • rnd = 0.5 tRandom.nextGaussian() * 方差;

然后,如果 rnd > 0.5,则将其映射到范围 {bias; 偏差 + max_bias} 具有简单的比例缩放。如果 rnd < 0.5,则将其映射到范围 {min_bias; 偏见}。

这是代码:

public double getBiasedRandom(double bias, double min, double max) {
    double centered_depth_perc = 0.3;
    double centered_depth_abs = (max - min)*centered_depth_perc;
    double center = 0.5;

    Random tRandom = new Random();  
    double rndCentered = center  + tRandom .nextGaussian() * centered_depth_abs; // generate centered random number. 

    if (rndCentered >= center)
        rndBiased = (rndCentered - center) * (max - bias) + bias;
    else
        rndBiased = bias - (center - rndCentered) * (bias - min);

    // the following two tests will be as more important as centered_depth_perc 
    // get bigger. 
    if (rndBiased > max) 
       rndBiased = max;

    if (rndBiased < min)
       rndBiased = min;

    return rndBiased;
}

希望它可以帮助。

于 2013-08-01T09:55:17.957 回答