確率で分布する値を見つけるには1/x
:
の積分1/x
はln x
であり、@ dbauppが指摘したように、それは際限なく成長します。実際、ln x
xが0に近づくときの限界は無限大(負)であり、正の無限大に成長するときの限界は無限大(正)です。
したがって、関数の範囲をある間隔に制限する必要があります。[min, max)
ここで、min > 0
および両方は有限です。
の逆関数q = ln x
は、でx = e^q
あるため、分位関数はですe^[(ln max - ln min)q + ln(min)]
。ここで、qは区間に含まれます。[0,1)
少し代数の後、それは(max/min)^q * min
=になります(max^q)(min^(1-q))
(どちらの形式が数値的に安定しているかはわかりません)
したがって、nextDoubleから取得するように、0から1の範囲の均一に分散された値をこの関数にプラグインするとpdf = 1/x
、指定された最小値から最大値の範囲の値が得られます。
public static double reciprocalQuantile(double q, double min, double max) {
return Math.pow(max, q)*Math.pow(min, 1-q);
}
だからあなたは言うことができます:
Random rand = new Random();
double value = reciprocalQuantile(rand.nextDouble(), 0.0001, 10000);
私は思う:-)私の数学をチェックしてください。
もう1つのポイント:もちろん、minをDouble.MIN_VALUEに、maxをDouble.MAX_VALUEに設定することもできますが、浮動小数点表現については、それが問題になるかどうかを知るのに十分な知識がありません。そのようになるには、数がどれだけ小さい/大きい必要があるか。また、あまり役に立たないかもしれません。少しのテストで、非常に小さな値と非常に大きな値が多数示されました。これは、上部と下部の積分が無限大に近づくため、驚くことではありません。したがって、きれいなヒストグラムを作成するために中程度の範囲で十分な値を取得するには、多くの値が必要になります。