[英]java schedule a callable at pseudo 'fixed' rate (bell curve distribution for example)
[英]Bell curve with left or right bias
在 Java 中,我想生成一个从 1 到 100 的随机数,该随机数可以基于刻度的任一端,同时仍然有可能来自另一端的数字仍然被“滚动”。
澄清一下,在正常情况下,在1 - 100 的卷数上,平均值为 50 ,但在某些情况下,我希望平均值下降到 25%。 但是仍然有机会产生 100%。
我看过 Random.nextGaussian,它确实改变了钟形曲线,但对于低端值,这消除了高端可能性。
我应该使用什么公式或公式组合?
计算出所需的确切分发形式。
计算该分布的分位数函数。
使用适当的生成器在[0,1)中绘制一个统一的随机数。
那就是分位数功能的输入。
结果编号将根据需要分配。
想出了一些简单的方法来至少接近这样的结果。 我有点没能掌握这一切背后的数学原理,所以我主要是通过反复试验得出这个结论,当我得到一些看起来足够好的东西时,我就结束了。
找到了两种方法:
基本上创建三角分布,然后用简单的指数调整它的值。 它创建了一个类似于钟形曲线的形状,但它在峰值处有一个尖锐的尖峰,而不是一个沉闷的尖峰。 通过改变指数,接近峰值的曲线可以是凹的也可以是凸的。
/** * @param min lower bound * @param max upper bound * @param avg mode <min, max> * @param exp convex (0, 0.5> or concave <0.5, 1> or linear (0.5) */ public static double triangleExponential(double min, double max, double avg, double exp) { if (min >= max || avg < min || avg > max) { throw new IllegalArgumentException(); } double pivot = MathUtils.range(avg, min, max, 0, 1); double x = generator.nextUniform(0, 1); double nx; if (x < pivot) { nx = MathUtils.range(x, 0, pivot, 0, 1); nx = Math.pow(nx, exp); nx = MathUtils.range(nx, 0, 1, 0, pivot); } else { nx = MathUtils.range(x, pivot, 1, 0, 1); nx = 1 - Math.pow(nx, exp); nx = MathUtils.range(nx, 0, 1, pivot, 1); } return MathUtils.range(nx, 0, 1, min, max); }
第二种方法只是采用高斯分布并根据需要挤压/拉伸它。
/** * @param min lower bound * @param max upper bound * @param avg mode <min, max> * @param exp 'peak sharpness' (0, 2> */ public static double squishedGaussian(double min, double max, double avg, double exp) { if (min >= max || avg < min || avg > max) { throw new IllegalArgumentException(); } double pivot = MathUtils.range(avg, min, max, 0, 1); double uniform = generator.nextUniform(0, 1); double x = generateGaussian(); if (uniform < pivot) { x = Math.pow(x, exp); x = MathUtils.range(x, 0, 1, 0, pivot); } else { x = 1 - (Math.pow(x, exp)); x = MathUtils.range(x, 0, 1, pivot, 1); } return MathUtils.range(x, 0, 1, min, max); } static double generateGaussian() { double gaussianMax = 5; //Its more like 5.4 double rand; do { rand = Math.abs(generator.nextGaussian(0, 1)); } while (rand > gaussianMax); return 1 - MathUtils.range(rand, 0, gaussianMax, 0, 1); }
MathUtils.range
只是一个重新映射 function 的值范围
public static double range(double OldValue, double OldMin, double OldMax, double NewMin, double NewMax) {
return (((OldValue - OldMin) * (NewMax - NewMin)) / (OldMax - OldMin)) + NewMin;
}
generator
是来自org.apache.commons.math3.random
的RandomDataGenerator
class
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.