Javaで最大、最小、平均(平均)で乱数を生成する
質問
次のプロパティで乱数を生成する必要があります。
分は200でなければなりません
Maxは20000でなければなりません
平均(平均)は500です。
オプション:75パーセンタイルは5000です
間違いなくそれは均一な分布でも、ガウスでもありません。左の歪みを与える必要があります。
他のヒント
言う X
ターゲット変数は、実行して範囲を正規化できます Y=(X-200)/(20000-200)
. 。だから今あなたはいくつか欲しいです Y
値を取得するランダム変数 [0,1]
平均で (500-200)/(20000-200)=1/66
.
あなたには多くの選択肢があり、最も自然なものは私には思えます ベータ分布, Y ~ Beta(a,b)
と a/(a+b) = 1/66
- 追加の自由度があり、最後の四分位の要件に合わせて選択できます。
その後、xをasに返すだけです Y*(20000-200)+200
ベータランダム変数を生成するには、使用できます Apache Commons または参照してください ここ.
これはあなたが探している答えではないかもしれませんが、3つの均一な分布を持つ特定のケース:
(左側の数字を無視しますが、スケーリングすることです!)
public int generate() {
if(random(0, 65) == 0) {
// 50-100 percentile
if(random(1, 13) > 3) {
// 50-75 percentile
return random(500, 5000);
} else {
// 75-100 percentile
return random(5000, 20000);
}
} else {
// 0-50 percentile
return random(200, 500);
}
}
数字を手に入れた方法
まず、曲線下の面積は200〜500〜500-20000の間で等しくなります。これは、高さの関係があることを意味します 300 * leftHeight == 19500 * rightHeight
作り leftHeight == 65 * rightHeight
これにより、1/66の右を選択するチャンスがあり、65/66のチャンスが左に選ばれます。
次に、比率が 500-5000 chance == 5000-20000 chance * 10 / 3
. 。繰り返しますが、これは、50〜75パーセンタイルに参加する10/13のチャンスがあり、3/13が75-100になるチャンスがあることを意味します。
@stasへの称賛 - 私は彼の「包括的ランダム」機能を使用しています。
そして、はい、この方法は個別の数字で動作し、私の計算が継続的であったため、私の数字が間違っていることに気付きます。誰かが私の国境のケースを修正できればいいでしょう。
0; 1]で動作する関数fを使用できます。
Integral(f(x)dx) on [0;1] = 500
f(0) = 200
f(0.75) = 5000
f(1) = 20000
フォームの関数を推測します
f(x) = a*exp(x) + b*x + c
解決策かもしれませんが、関連システムを解決するだけです。
それから、あなたはします f(uniform_random(0,1))
そして、あなたはそこにいます!
パート分布 (また ベータパート分布)は、最小および最大および推定モードを取得するように設計されています。これは、三角形の分布の「スムーズな」バージョンであり、その分布から乱数を生成することは、次のように実装できます。
startpt + (endpt - startpt) *
BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt),
1.0 + (endpt - midpt) * shape / (endpt - startpt))
どこ-
startpt
最小です、midpt
モードです(必ずしも平均または平均ではありません)、endpt
最大です、shape
数は0以上ですが、通常は4です。BetaDist(X, Y)
パラメーターを使用してベータ分布から乱数を返しますX
とY
.
既知の平均が与えられた(mean
), midpt
以下で計算できます。
3 * mean / 2 - (startpt + endpt) / 4