上下文
基于人口的增量学习(PBIL)算法的一部分是计算许多偏置随机比特。每个位的偏置由0.0-1.0范围内的相应双精度确定。
对于每个位,将0.0-1.0范围内的无偏差随机双精度与偏差进行比较。如果生成的随机双精度小于偏差,则将该位设置为0,否则为1。
在生成比特偏置序列后,比特将转换为各种范围内的双精度数。
问题
我想直接在一个范围内生成一个有偏差的双。这是在没有操纵双重表示中的每个位的情况下。然后,每个双精度数将具有确定偏差的单个变量(每个位不是一个)。如前所述,每个double也有一个最小和最大常数,它决定了随机双数的下限和上限。
以下示例生成可接受的分布。然而,如果没有潜在的无限循环,解决问题会很好。
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的回答中添加了一个潜在的解决方案。
答案 0 :(得分: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;
}
实际上,您只需使用以偏差为中心的高斯分布得到偏差随机数,其方差可以设置为范围的百分比(在示例中设置为10%,行double bias_depth_perc = 0.1)。
编辑:当偏差接近边界时改变了行为,并且您获得了超出限制的大量随机数。现在它只是将边界内随机生成的数字复制到距离限制本身的距离。这实际上以简单的不对称分布结束。
第二个解决方案: 这有点棘手。这里的想法是始终生成对称的随机数,然后将生成的数字映射到正确的范围。例如:如果你有:
首先生成一个以0.5为中心的随机数,并选择方差:
然后,如果rnd是&gt; 0.5,你将它映射到范围{bias;偏差+ max_bias}与简单的尺度moltiplication。 如果rnd是&lt; 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;
}
希望它可以提供帮助。